00001 import os
00002 import sys
00003 import math
00004 import struct
00005 import Image
00006
00007 import pyauto
00008 import cterm
00009 from cterm.cterm_const import *
00010
00011 import clnch_skin
00012 import clnch_misc
00013 import clnch_native
00014 import clnch_colortable
00015
00016
00017
00018
00019
00020 class Widget:
00021
00022 def __init__( self, window, x, y, width, height ):
00023 self.window = window
00024 self.x = x
00025 self.y = y
00026 self.width = width
00027 self.height = height
00028 self.enable_cursor = False
00029 self.enable_ime = False
00030
00031 def setPosSize( self, x, y, width, height ):
00032 self.x = x
00033 self.y = y
00034 self.width = width
00035 self.height = height
00036
00037 def enableCursor( self, enable ):
00038 if not self.enable_cursor and enable:
00039 self.window.enableIme( self.enable_ime )
00040 self.enable_cursor = enable
00041
00042 def enableIme( self, enable ):
00043 self.window.enableIme( self.enable_cursor )
00044 self.enable_ime = enable
00045
00046
00047
00048
00049
00050
00051 class ButtonWidget(Widget):
00052
00053 def __init__( self, window, x, y, width, height, message, handler=None ):
00054
00055 Widget.__init__( self, window, x, y, width, height )
00056
00057 self.message = message
00058 self.handler = handler
00059
00060 self.paint()
00061
00062 def onKeyDown( self, vk, mod ):
00063
00064
00065
00066 if vk==VK_SPACE:
00067 self.onPush()
00068
00069 elif vk==VK_RETURN:
00070 self.onPush()
00071
00072 self.paint()
00073
00074 def onPush(self):
00075 if self.handler:
00076 self.handler()
00077
00078 def paint(self):
00079
00080 if self.enable_cursor:
00081 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00082 self.window.setCursorPos( -1, -1 )
00083 else:
00084 attr = cterm.Attribute( fg=clnch_colortable.fg )
00085
00086 self.window.putString( self.x, self.y, self.width, 1, attr, self.message )
00087
00088
00089
00090
00091
00092
00093 class CheckBoxWidget(Widget):
00094
00095 def __init__( self, window, x, y, width, height, message, check ):
00096
00097 Widget.__init__( self, window, x, y, width, height )
00098
00099 def createImage(path):
00100 pil_img = Image.open(path)
00101 pil_img = pil_img.convert( "RGBA" )
00102 return cterm.Image.fromString( pil_img.size, pil_img.tostring() )
00103 self.img0 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/check0.png' ))
00104 self.img1 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/check1.png' ))
00105
00106 self.plane_size = self.window.getCharSize()
00107 self.plane_size = ( self.plane_size[0]*2-1, self.plane_size[1]-1 )
00108
00109 self.plane = cterm.Plane( self.window, (0,0), self.plane_size, 0 )
00110 self.plane.setImage(self.img0)
00111
00112 self.message = message
00113 self.check = check
00114
00115 self.paint()
00116
00117 def onKeyDown( self, vk, mod ):
00118
00119
00120
00121 if vk==VK_SPACE:
00122 self.check = not self.check
00123 self.paint()
00124
00125 def paint(self):
00126
00127 pos1 = self.window.charToClient( self.x, self.y )
00128 pos2 = self.window.charToClient( self.x+2, self.y+1 )
00129
00130 self.plane.setPos( ( (pos1[0]+pos2[0]-self.plane_size[0])/2, (pos1[1]+pos2[1]-self.plane_size[1])/2 ) )
00131
00132 if self.check:
00133 self.plane.setImage(self.img1)
00134 else:
00135 self.plane.setImage(self.img0)
00136
00137 if self.enable_cursor:
00138 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00139 self.window.setCursorPos( -1, -1 )
00140 else:
00141 attr = cterm.Attribute( fg=clnch_colortable.fg )
00142
00143 self.window.putString( self.x+3, self.y, self.width-3, 1, attr, self.message )
00144
00145 def getValue(self):
00146 return self.check
00147
00148
00149
00150
00151
00152
00153
00154 class ChoiceWidget(Widget):
00155
00156 def __init__( self, window, x, y, width, height, message, item_list, initial_select ):
00157
00158 Widget.__init__( self, window, x, y, width, height )
00159
00160 self.message = message
00161 self.item_list = item_list
00162 self.select = initial_select
00163
00164 self.paint()
00165
00166 def onKeyDown( self, vk, mod ):
00167
00168
00169
00170 if vk==VK_LEFT:
00171 self.select -= 1
00172 if self.select<0 : self.select=0
00173 elif vk==VK_RIGHT:
00174 self.select += 1
00175 if self.select>len(self.item_list)-1 : self.select=len(self.item_list)-1
00176 self.paint()
00177
00178 def paint(self):
00179
00180 x = self.x
00181
00182 message_width = self.window.getStringWidth(self.message)
00183 self.window.putString( x, self.y, message_width, 1, cterm.Attribute( fg=clnch_colortable.fg ), self.message )
00184 x += message_width + 2
00185
00186 for i in xrange(len(self.item_list)):
00187
00188 item = self.item_list[i]
00189
00190 if self.select==i :
00191 if self.enable_cursor :
00192 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00193 self.window.setCursorPos( -1, -1 )
00194 else:
00195 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.choice_bg )
00196 else:
00197 attr = cterm.Attribute( fg=clnch_colortable.fg )
00198
00199 item_width = self.window.getStringWidth(item)
00200 self.window.putString( x, self.y, item_width, 1, attr, item )
00201 x += item_width + 2
00202
00203 def getValue(self):
00204 return self.select
00205
00206
00207
00208
00209
00210
00211 class ColorWidget(Widget):
00212
00213 color_table = ( (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0), (0,0,0) )
00214
00215 def __init__( self, window, x, y, width, height, message, color ):
00216
00217 Widget.__init__( self, window, x, y, width, height )
00218
00219 self.frame_plane_size = self.window.getCharSize()
00220 self.frame_plane_size = ( self.frame_plane_size[0]*4-1, self.frame_plane_size[1]-1 )
00221 self.frame_plane = cterm.Plane( self.window, (0,0), self.frame_plane_size, 1 )
00222 self.color_plane_size = ( self.frame_plane_size[0]-2, self.frame_plane_size[1]-2 )
00223 self.color_plane = cterm.Plane( self.window, (0,0), self.color_plane_size, 0 )
00224
00225 self.message = message
00226 self.color = color
00227
00228 self.paint()
00229
00230 def onKeyDown( self, vk, mod ):
00231
00232
00233
00234 if vk==VK_SPACE or vk==VK_RETURN:
00235 result, color, ColorWidget.color_table = clnch_native.chooseColor( self.window.getHWND(), self.color, ColorWidget.color_table )
00236 if result:
00237 self.color = color
00238 self.paint()
00239
00240 def paint(self):
00241
00242 pos1 = self.window.charToClient( self.x+0, self.y )
00243 pos2 = self.window.charToClient( self.x+4, self.y+1 )
00244
00245 self.frame_plane.setPos( ( (pos1[0]+pos2[0]-self.color_plane_size[0])/2, (pos1[1]+pos2[1]-self.color_plane_size[1])/2 ) )
00246 self.frame_plane.setImage( cterm.Image.fromString( (1,1), struct.pack( "BBBB", clnch_colortable.bg[0]^0xff, clnch_colortable.bg[1]^0xff, clnch_colortable.bg[2]^0xff, 0xff ) ) )
00247
00248 self.color_plane.setPos( ( (pos1[0]+pos2[0]-self.color_plane_size[0])/2+1, (pos1[1]+pos2[1]-self.color_plane_size[1])/2+1 ) )
00249 self.color_plane.setImage( cterm.Image.fromString( (1,1), struct.pack( "BBBB", self.color[0], self.color[1], self.color[2], 0xff ) ) )
00250
00251 if self.enable_cursor:
00252 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00253 self.window.setCursorPos( -1, -1 )
00254 else:
00255 attr = cterm.Attribute( fg=clnch_colortable.fg )
00256
00257 self.window.putString( self.x+5, self.y, self.width-3, 1, attr, self.message )
00258
00259 def getValue(self):
00260 return self.color
00261
00262
00263
00264
00265
00266
00267 class HotKeyWidget(Widget):
00268
00269 def __init__( self, window, x, y, width, height, vk, mod ):
00270
00271 Widget.__init__( self, window, x, y, width, height )
00272
00273 self.vk = vk
00274 self.mod = mod
00275
00276 self.paint()
00277
00278 def onKeyDown( self, vk, mod ):
00279
00280
00281
00282 if vk==VK_LCONTROL or vk==VK_RCONTROL or vk==VK_CONTROL:
00283 mod &= ~MODKEY_CTRL
00284 elif vk==VK_LMENU or vk==VK_RMENU or vk==VK_MENU:
00285 mod &= ~MODKEY_ALT
00286 elif vk==VK_LSHIFT or vk==VK_RSHIFT or vk==VK_SHIFT:
00287 mod &= ~MODKEY_SHIFT
00288 elif vk==VK_LWIN or vk==VK_RWIN:
00289 mod &= ~MODKEY_WIN
00290
00291 self.vk = vk
00292 self.mod = mod
00293
00294 self.paint()
00295
00296 def paint(self):
00297
00298 if self.enable_cursor:
00299 attr = cterm.Attribute( fg=clnch_colortable.fg, bg=clnch_colortable.select_bg )
00300 self.window.setCursorPos( -1, -1 )
00301 else:
00302 attr = cterm.Attribute( fg=clnch_colortable.fg )
00303
00304 _vk_name_table = {
00305
00306 VK_A : "A",
00307 VK_B : "B",
00308 VK_C : "C",
00309 VK_D : "D",
00310 VK_E : "E",
00311 VK_F : "F",
00312 VK_G : "G",
00313 VK_H : "H",
00314 VK_I : "I",
00315 VK_J : "J",
00316 VK_K : "K",
00317 VK_L : "L",
00318 VK_M : "M",
00319 VK_N : "N",
00320 VK_O : "O",
00321 VK_P : "P",
00322 VK_Q : "Q",
00323 VK_R : "R",
00324 VK_S : "S",
00325 VK_T : "T",
00326 VK_U : "U",
00327 VK_V : "V",
00328 VK_W : "W",
00329 VK_X : "X",
00330 VK_Y : "Y",
00331 VK_Z : "Z",
00332
00333 VK_0 : "0",
00334 VK_1 : "1",
00335 VK_2 : "2",
00336 VK_3 : "3",
00337 VK_4 : "4",
00338 VK_5 : "5",
00339 VK_6 : "6",
00340 VK_7 : "7",
00341 VK_8 : "8",
00342 VK_9 : "9",
00343
00344 VK_OEM_MINUS : "Minus",
00345 VK_OEM_PLUS : "Plus",
00346 VK_OEM_COMMA : "Comma",
00347 VK_OEM_PERIOD : "Period",
00348
00349 VK_NUMLOCK : "NumLock",
00350 VK_DIVIDE : "Divide",
00351 VK_MULTIPLY : "Multiply",
00352 VK_SUBTRACT : "Subtract",
00353 VK_ADD : "Add",
00354 VK_DECIMAL : "Decimal",
00355
00356 VK_NUMPAD0 : "Num0",
00357 VK_NUMPAD1 : "Num1",
00358 VK_NUMPAD2 : "Num2",
00359 VK_NUMPAD3 : "Num3",
00360 VK_NUMPAD4 : "Num4",
00361 VK_NUMPAD5 : "Num5",
00362 VK_NUMPAD6 : "Num6",
00363 VK_NUMPAD7 : "Num7",
00364 VK_NUMPAD8 : "Num8",
00365 VK_NUMPAD9 : "Num9",
00366
00367 VK_F1 : "F1",
00368 VK_F2 : "F2",
00369 VK_F3 : "F3",
00370 VK_F4 : "F4",
00371 VK_F5 : "F5",
00372 VK_F6 : "F6",
00373 VK_F7 : "F7",
00374 VK_F8 : "F8",
00375 VK_F9 : "F9",
00376 VK_F10 : "F10",
00377 VK_F11 : "F11",
00378 VK_F12 : "F12",
00379
00380 VK_LEFT : "Left",
00381 VK_RIGHT : "Right",
00382 VK_UP : "Up",
00383 VK_DOWN : "Down",
00384 VK_SPACE : "Space",
00385 VK_TAB : "Tab",
00386 VK_BACK : "Back",
00387 VK_RETURN : "Return",
00388 VK_ESCAPE : "Escape",
00389 VK_CAPITAL : "CapsLock",
00390 VK_APPS : "Apps",
00391
00392 VK_INSERT : "Insert",
00393 VK_DELETE : "Delete",
00394 VK_HOME : "Home",
00395 VK_END : "End",
00396 VK_NEXT : "PageDown",
00397 VK_PRIOR : "PageUp",
00398
00399 VK_MENU : "Alt",
00400 VK_LMENU : "LAlt",
00401 VK_RMENU : "RAlt",
00402 VK_CONTROL : "Ctrl",
00403 VK_LCONTROL : "LCtrl",
00404 VK_RCONTROL : "RCtrl",
00405 VK_SHIFT : "Shift",
00406 VK_LSHIFT : "LShift",
00407 VK_RSHIFT : "RShift",
00408 VK_LWIN : "LWin",
00409 VK_RWIN : "RWin",
00410
00411 VK_SNAPSHOT : "PrintScreen",
00412 VK_SCROLL : "ScrollLock",
00413 VK_PAUSE : "Pause",
00414 }
00415
00416 str_mod = ""
00417 if self.mod & MODKEY_ALT:
00418 str_mod += "A-"
00419 if self.mod & MODKEY_CTRL:
00420 str_mod += "C-"
00421 if self.mod & MODKEY_SHIFT:
00422 str_mod += "S-"
00423 if self.mod & MODKEY_WIN:
00424 str_mod += "W-"
00425
00426 try:
00427 str_vk = _vk_name_table[self.vk]
00428 except KeyError:
00429 str_vk = "(%d)" % self.vk
00430
00431 s = str_mod + str_vk
00432
00433 s = clnch_misc.adjustStringWidth( self.window, s, self.width, clnch_misc.ALIGN_CENTER )
00434
00435 self.window.putString( self.x, self.y, self.width, 1, attr, s )
00436
00437 def getValue(self):
00438 return [ self.vk, self.mod ]
00439
00440
00441
00442
00443
00444 class action_Insert:
00445 def __init__( self, pos, text ):
00446 self.pos = pos
00447 self.text = text
00448
00449 class action_Delete:
00450 def __init__( self, pos, text ):
00451 self.pos = pos
00452 self.text = text
00453
00454 class action_Back:
00455 def __init__( self, pos, text ):
00456 self.pos = pos
00457 self.text = text
00458
00459 class EditWidget(Widget):
00460
00461 class UpdateInfo:
00462 def __init__( self, text, selection ):
00463 self.text = text
00464 self.selection = selection
00465
00466 def __init__( self, window, x, y, width, height, text, selection=None, margin1=1, margin2=12, auto_complete=False, no_bg=False, autofix_list=None, update_handler=None, candidate_handler=None, word_break_handler=None ):
00467
00468 Widget.__init__( self, window, x, y, width, height )
00469
00470 self.enableIme(True)
00471
00472 self.text = text
00473 if selection==None : selection=[ len(text), len(text) ]
00474 self.selection = selection
00475 if margin1 > self.width/2 : margin1 = self.width/2
00476 if margin2 > self.width/2 : margin2 = self.width/2
00477 self.margin1 = margin1
00478 self.margin2 = margin2
00479 self.auto_complete = auto_complete
00480 self.scroll_pos = -self.margin1
00481 self.autofix_list = autofix_list
00482 self.update_handler = update_handler
00483 self.candidate_handler = candidate_handler
00484 if word_break_handler:
00485 sekf.word_break_handler = word_break_handler
00486 else:
00487 self.word_break_handler = clnch_misc.wordbreak_Filename
00488
00489 self.undo_list = []
00490 self.redo_list = []
00491 self.last_action = None
00492
00493 if not no_bg:
00494 pos1 = self.window.charToClient(x,y)
00495 pos2 = self.window.charToClient(x+width,y+1)
00496 self.skin_edit = clnch_skin.SkinPlane( self.window, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_active.png' ) )
00497 self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
00498 else:
00499 self.skin_edit = None
00500
00501 if candidate_handler:
00502 self.list_window = CandidateWindow( x, y, 10, 1, 80, 16, window, selchange_handler=self.onListSelChange )
00503 self.list_window_pos = 0
00504 else:
00505 self.list_window = None
00506
00507 self.makeVisible( self.selection[1] )
00508
00509 self.paint()
00510
00511 def destroy(self):
00512 if self.skin_edit:
00513 self.skin_edit.destroy()
00514 if self.list_window:
00515 self.list_window.destroy()
00516
00517 def setPosSize( self, x, y, width, height ):
00518 Widget.setPosSize( self, x, y, width, height )
00519 if self.skin_edit:
00520 pos1 = self.window.charToClient(x,y)
00521 pos2 = self.window.charToClient(x+width,y+1)
00522 self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
00523
00524 def setAutoComplete( self, auto_complete ):
00525 self.auto_complete = auto_complete
00526
00527 def getAutoComplete(self):
00528 return self.auto_complete
00529
00530 def appendUndo( self, action ):
00531 if self.last_action != None :
00532 self.undo_list.append(self.last_action)
00533 self.redo_list = []
00534 self.last_action = action
00535
00536 def undo(self):
00537
00538 self.appendUndo(None)
00539
00540 if len(self.undo_list)==0 : return
00541
00542 action = self.undo_list[-1]
00543
00544 if isinstance( action, action_Insert ):
00545
00546 update_info = EditWidget.UpdateInfo(
00547 self.text[ : action.pos ] + self.text[ action.pos + len(action.text) : ],
00548 [ action.pos, action.pos ]
00549 )
00550
00551 elif isinstance( action, action_Delete ) or isinstance( action, action_Back ):
00552
00553 update_info = EditWidget.UpdateInfo(
00554 self.text[ : action.pos ] + action.text + self.text[ action.pos : ],
00555 [ action.pos+len(action.text), action.pos+len(action.text) ]
00556 )
00557
00558 else:
00559 assert(0)
00560
00561 self.closeList()
00562
00563 if self.update_handler:
00564 if self.update_handler(update_info)==False:
00565 return
00566
00567 self.undo_list = self.undo_list[:-1]
00568 self.redo_list.append(action)
00569
00570 self.text = update_info.text
00571 self.selection = update_info.selection
00572 self.makeVisible( self.selection[1] )
00573 self.paint()
00574
00575 def redo(self):
00576
00577 if len(self.redo_list)==0 : return
00578
00579 action = self.redo_list[-1]
00580
00581 if isinstance( action, action_Insert ):
00582
00583 update_info = EditWidget.UpdateInfo(
00584 self.text[ : action.pos ] + action.text + self.text[ action.pos : ],
00585 [ action.pos + len(action.text), action.pos + len(action.text) ]
00586 )
00587
00588 elif isinstance( action, action_Delete ) or isinstance( action, action_Back ):
00589
00590 update_info = EditWidget.UpdateInfo(
00591 self.text[ : action.pos ] + self.text[ action.pos + len(action.text) : ],
00592 [ action.pos, action.pos ]
00593 )
00594
00595 else:
00596 assert(0)
00597
00598 self.closeList()
00599
00600 if self.update_handler:
00601 if self.update_handler(update_info)==False:
00602 return
00603
00604 self.undo_list.append(action)
00605 self.redo_list = self.redo_list[:-1]
00606
00607 self.text = update_info.text
00608 self.selection = update_info.selection
00609 self.makeVisible( self.selection[1] )
00610 self.paint()
00611
00612 def onKeyDown( self, vk, mod ):
00613
00614
00615
00616 if mod==MODKEY_SHIFT:
00617
00618 if vk==VK_SPACE:
00619 if self.candidate_handler:
00620 self.window.removeKeyMessage()
00621 if self.list_window.numItems()==0:
00622 self.insertText(u"")
00623 return True
00624 return self.list_window.onKeyDown( vk, mod )
00625
00626 elif vk==VK_LEFT:
00627 self.appendUndo(None)
00628 self.selection[1] = max( self.selection[1]-1, 0 )
00629 elif vk==VK_RIGHT:
00630 self.appendUndo(None)
00631 self.selection[1] = min( self.selection[1]+1, len(self.text) )
00632 elif vk==VK_HOME:
00633 self.appendUndo(None)
00634 self.selection[1] = 0
00635 elif vk==VK_END:
00636 self.appendUndo(None)
00637 self.selection[1] = len(self.text)
00638 self.makeVisible( self.selection[1] )
00639 self.paint()
00640
00641 elif mod==MODKEY_CTRL:
00642
00643 if vk==VK_LEFT:
00644 self.appendUndo(None)
00645 new_caret_pos = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00646 self.selection = [ new_caret_pos, new_caret_pos ]
00647 self.makeVisible( self.selection[1] )
00648 self.paint()
00649
00650 elif vk==VK_RIGHT:
00651 self.appendUndo(None)
00652 new_caret_pos = self.word_break_handler( self.text, self.selection[1]+1, +1 )
00653 self.selection = [ new_caret_pos, new_caret_pos ]
00654 self.makeVisible( self.selection[1] )
00655 self.paint()
00656
00657 elif vk==VK_BACK:
00658 if self.selection[0]==self.selection[1] and self.selection[0]>0:
00659 selection_left = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00660 selection_right = self.selection[1]
00661 update_info = EditWidget.UpdateInfo(
00662 self.text[ : selection_left ] + self.text[ selection_right : ],
00663 [ selection_left, selection_left ]
00664 )
00665 else:
00666 selection_left = min( self.selection[0], self.selection[1] )
00667 selection_right = max( self.selection[0], self.selection[1] )
00668 update_info = EditWidget.UpdateInfo(
00669 self.text[ : selection_left ] + self.text[ selection_right : ],
00670 [ selection_left, selection_left ]
00671 )
00672
00673 if self.candidate_handler:
00674 self.popupList( update_info, False )
00675
00676 if self.update_handler:
00677 if self.update_handler(update_info)==False:
00678 return
00679
00680 self.appendUndo( action_Delete( update_info.selection[0], self.text[ selection_left : selection_right ] ) )
00681 self.appendUndo(None)
00682
00683 self.text = update_info.text
00684 self.selection = update_info.selection
00685 self.makeVisible( self.selection[1] )
00686 self.paint()
00687
00688 elif vk==VK_A:
00689 self.appendUndo(None)
00690 self.selection = [ 0, len(self.text) ]
00691 self.makeVisible( self.selection[1] )
00692 self.paint()
00693
00694 elif vk==VK_X:
00695 self.appendUndo(None)
00696 if self.selection[0]==self.selection[1] : return
00697
00698 selection_left = min( self.selection[0], self.selection[1] )
00699 selection_right = max( self.selection[0], self.selection[1] )
00700
00701 update_info = EditWidget.UpdateInfo(
00702 self.text[ : selection_left ] + self.text[ selection_right : ],
00703 [ selection_left, selection_left ]
00704 )
00705
00706 self.closeList()
00707
00708 if self.update_handler:
00709 if self.update_handler(update_info)==False:
00710 return
00711
00712 self.appendUndo( action_Delete( selection_left, self.text[ selection_left : selection_right ] ) )
00713 self.appendUndo(None)
00714
00715 clnch_misc.setClipboardText( self.text[ selection_left : selection_right ] )
00716
00717 self.text = update_info.text
00718 self.selection = update_info.selection
00719 self.makeVisible( self.selection[1] )
00720 self.paint()
00721
00722 elif vk==VK_C:
00723 self.appendUndo(None)
00724 if self.selection[0]==self.selection[1] : return
00725
00726 selection_left = min( self.selection[0], self.selection[1] )
00727 selection_right = max( self.selection[0], self.selection[1] )
00728
00729 update_info = EditWidget.UpdateInfo(
00730 self.text,
00731 [ self.selection[1], self.selection[1] ]
00732 )
00733
00734 self.closeList()
00735
00736 if self.update_handler:
00737 if self.update_handler(update_info)==False:
00738 return
00739
00740 clnch_misc.setClipboardText( self.text[ selection_left : selection_right ] )
00741
00742 self.text = update_info.text
00743 self.selection = update_info.selection
00744 self.makeVisible( self.selection[1] )
00745 self.paint()
00746
00747 elif vk==VK_V:
00748 self.appendUndo(None)
00749 selection_left = min( self.selection[0], self.selection[1] )
00750 selection_right = max( self.selection[0], self.selection[1] )
00751
00752 clipboard_text = clnch_misc.getClipboardText()
00753
00754 update_info = EditWidget.UpdateInfo(
00755 self.text[ : selection_left ] + clipboard_text + self.text[ selection_right : ],
00756 [ selection_left+len(clipboard_text), selection_left+len(clipboard_text) ]
00757 )
00758
00759 self.closeList()
00760
00761 if self.update_handler:
00762 if self.update_handler(update_info)==False:
00763 return
00764
00765 self.appendUndo( action_Insert( selection_left, clipboard_text ) )
00766 self.appendUndo(None)
00767
00768 self.text = update_info.text
00769 self.selection = update_info.selection
00770 self.makeVisible( self.selection[1] )
00771 self.paint()
00772
00773 elif vk==VK_Z:
00774 self.appendUndo(None)
00775 self.undo()
00776
00777 elif vk==VK_Y:
00778 self.redo()
00779
00780 elif mod==MODKEY_SHIFT|MODKEY_CTRL:
00781
00782 if vk==VK_LEFT:
00783 self.appendUndo(None)
00784 self.selection[1] = self.word_break_handler( self.text, self.selection[1]-1, -1 )
00785 self.makeVisible( self.selection[1] )
00786 self.paint()
00787
00788 elif vk==VK_RIGHT:
00789 self.appendUndo(None)
00790 self.selection[1] = self.word_break_handler( self.text, self.selection[1]+1, +1 )
00791 self.makeVisible( self.selection[1] )
00792 self.paint()
00793
00794 elif mod==0:
00795
00796 if vk in (VK_SPACE,VK_UP,VK_DOWN,VK_PRIOR,VK_NEXT):
00797 if self.candidate_handler:
00798 self.window.removeKeyMessage()
00799 if self.list_window.numItems()==0:
00800 self.insertText(u"")
00801 return True
00802 return self.list_window.onKeyDown( vk, mod )
00803
00804 elif vk==VK_TAB:
00805 if self.candidate_handler:
00806 if self.list_window.numItems()!=0:
00807 self.window.removeKeyMessage()
00808 common_prefix = self.list_window.commonPrefix()
00809 selection_left = min( self.selection[0], self.selection[1] )
00810 self.insertText(self.text[ selection_left : self.list_window_pos + len(common_prefix) ] )
00811 return True
00812
00813 elif vk==VK_ESCAPE:
00814 if self.candidate_handler:
00815 if self.list_window.numItems()>0:
00816 self.closeList()
00817 return True
00818
00819 elif self.selection[0]==self.selection[1]:
00820 if vk==VK_LEFT:
00821 self.appendUndo(None)
00822 new_caret_pos = max( self.selection[1]-1, 0 )
00823 self.selection = [ new_caret_pos, new_caret_pos ]
00824 elif vk==VK_RIGHT:
00825 self.appendUndo(None)
00826 new_caret_pos = min( self.selection[1]+1, len(self.text) )
00827 self.selection = [ new_caret_pos, new_caret_pos ]
00828 elif vk==VK_HOME:
00829 self.appendUndo(None)
00830 self.selection = [ 0, 0 ]
00831 elif vk==VK_END:
00832 self.appendUndo(None)
00833 self.selection = [ len(self.text), len(self.text) ]
00834 elif vk==VK_DELETE:
00835 update_info = EditWidget.UpdateInfo(
00836 self.text[ : self.selection[0] ] + self.text[ self.selection[1]+1 : ],
00837 [ self.selection[0], self.selection[0] ]
00838 )
00839
00840 self.closeList()
00841
00842 if self.update_handler:
00843 if self.update_handler(update_info)==False:
00844 return
00845
00846 if isinstance( self.last_action, action_Delete ):
00847 self.last_action.text += self.text[ self.selection[0] : self.selection[0]+1 ]
00848 else:
00849 self.appendUndo( action_Delete( self.selection[0], self.text[ self.selection[0] : self.selection[0]+1 ] ) )
00850
00851 self.text = update_info.text
00852 self.selection = update_info.selection
00853 elif vk==VK_BACK:
00854 remove_left = max( self.selection[1]-1, 0 )
00855 update_info = EditWidget.UpdateInfo(
00856 self.text[ : remove_left ] + self.text[ self.selection[1] : ],
00857 [ remove_left, remove_left ]
00858 )
00859
00860 self.closeList()
00861
00862 if self.update_handler:
00863 if self.update_handler(update_info)==False:
00864 return
00865
00866 if isinstance( self.last_action, action_Back ):
00867 self.last_action.text = self.text[ remove_left : self.selection[1] ] + self.last_action.text
00868 self.last_action.pos -= 1
00869 else:
00870 self.appendUndo( action_Back( remove_left, self.text[ remove_left : self.selection[1] ] ) )
00871
00872 self.text = update_info.text
00873 self.selection = update_info.selection
00874 self.makeVisible( self.selection[1] )
00875 self.paint()
00876 else:
00877 if vk==VK_LEFT:
00878 self.appendUndo(None)
00879 new_caret_pos = min( self.selection[0], self.selection[1] )
00880 self.selection = [ new_caret_pos, new_caret_pos ]
00881 elif vk==VK_RIGHT:
00882 self.appendUndo(None)
00883 new_caret_pos = max( self.selection[0], self.selection[1] )
00884 self.selection = [ new_caret_pos, new_caret_pos ]
00885 elif vk==VK_HOME:
00886 self.appendUndo(None)
00887 self.selection = [ 0, 0 ]
00888 elif vk==VK_END:
00889 self.appendUndo(None)
00890 self.selection = [ len(self.text), len(self.text) ]
00891 elif vk==VK_DELETE or vk==VK_BACK:
00892 selection_left = min( self.selection[0], self.selection[1] )
00893 selection_right = max( self.selection[0], self.selection[1] )
00894 update_info = EditWidget.UpdateInfo(
00895 self.text[ : selection_left ] + self.text[ selection_right : ],
00896 [ selection_left, selection_left ]
00897 )
00898
00899 self.closeList()
00900
00901 if self.update_handler:
00902 if self.update_handler(update_info)==False:
00903 return
00904 self.appendUndo( action_Delete( selection_left, self.text[ selection_left : selection_right ] ) )
00905 self.appendUndo(None)
00906 self.text = update_info.text
00907 self.selection = update_info.selection
00908 self.makeVisible( self.selection[1] )
00909 self.paint()
00910
00911 def onChar( self, ch, mod ):
00912
00913
00914
00915 if self.autofix_list:
00916 for autofix_string in self.autofix_list:
00917 if unichr(ch) in autofix_string:
00918
00919 selection_left = min( self.selection[0], self.selection[1] )
00920 selection_right = max( self.selection[0], self.selection[1] )
00921
00922 min_pos = -1
00923 for autofix_char in autofix_string:
00924 pos = self.text.find( autofix_char, selection_left, selection_right )
00925 if pos>=0:
00926 if min_pos<0 or pos<min_pos : min_pos=pos
00927
00928 if min_pos>=0:
00929 self.selection = [ min_pos, selection_right ]
00930 else:
00931 self.selection = [ selection_right, selection_right ]
00932
00933 if ch<=0xff and ( ch<0x20 or ch==0x7f ):
00934 return
00935 else:
00936 self.insertText( unichr(ch) )
00937
00938 def onWindowMove( self ):
00939 self.closeList()
00940
00941 def popupList( self, update_info=None, complete=True ):
00942
00943 if self.candidate_handler:
00944
00945 if update_info==None:
00946 update_info = EditWidget.UpdateInfo(
00947 self.text,
00948 self.selection
00949 )
00950
00951 selection_right = max( update_info.selection[0], update_info.selection[1] )
00952
00953 candidate_list, base_len = self.candidate_handler(update_info)
00954
00955
00956 if complete:
00957 try:
00958 select = candidate_list.index(update_info.text[base_len:selection_right])
00959 except:
00960 select = 0
00961 else:
00962 select = -1
00963
00964 x, y1 = self.window.charToScreen( self.x+self.window.getStringWidth(update_info.text[:base_len])-self.scroll_pos, self.y )
00965 x, y2 = self.window.charToScreen( self.x+self.window.getStringWidth(update_info.text[:base_len])-self.scroll_pos, self.y+1 )
00966 self.list_window_pos = base_len
00967 self.list_window.setItems( x, y1, y2, candidate_list, select )
00968
00969 if complete and len(candidate_list)>0:
00970
00971 left = update_info.text[:base_len]
00972 mid = candidate_list[select]
00973 right = update_info.text[selection_right:]
00974
00975 update_info.text = left + mid + right
00976 update_info.selection = [ update_info.selection[0], len(left)+len(mid) ]
00977
00978 def closeList(self):
00979 if self.candidate_handler:
00980 x, y = self.window.charToScreen( 0, 0 )
00981 self.list_window_pos = 0
00982 self.list_window.setItems( x, y, y, [], 0 )
00983
00984 def onListSelChange( self, select, text ):
00985
00986 selection_left = min( self.selection[0], self.selection[1] )
00987 selection_right = max( self.selection[0], self.selection[1] )
00988
00989 left = self.text[:self.list_window_pos]
00990 mid = text
00991 right = self.text[selection_right:]
00992
00993 update_info = EditWidget.UpdateInfo(
00994 left + mid + right,
00995 [ selection_left, len(left)+len(mid) ]
00996 )
00997
00998 if self.update_handler:
00999 if self.update_handler(update_info)==False:
01000 return
01001
01002 self.text = update_info.text
01003 self.selection = update_info.selection
01004 self.makeVisible( self.selection[1] )
01005 self.paint()
01006
01007 def insertText( self, text ):
01008 selection_left = min( self.selection[0], self.selection[1] )
01009 selection_right = max( self.selection[0], self.selection[1] )
01010
01011 new_caret_pos = selection_left + len(text)
01012 update_info = EditWidget.UpdateInfo(
01013 self.text[ : selection_left ] + text + self.text[ selection_right : ],
01014 [ new_caret_pos, new_caret_pos ]
01015 )
01016
01017 if self.candidate_handler:
01018 self.popupList( update_info, self.auto_complete )
01019
01020 if self.update_handler:
01021 if self.update_handler(update_info)==False:
01022 return
01023
01024 inserted_text = text + update_info.text[ update_info.selection[0] : update_info.selection[1] ]
01025
01026 if selection_left==selection_right:
01027 if isinstance( self.last_action, action_Insert ):
01028 self.last_action.text += inserted_text
01029 else:
01030 self.appendUndo( action_Insert( selection_left, inserted_text ) )
01031 else:
01032 self.appendUndo( action_Delete( selection_left, self.text[selection_left:selection_right] ) )
01033 self.appendUndo( action_Insert( selection_left, inserted_text ) )
01034
01035 self.text = update_info.text
01036 self.selection = update_info.selection
01037 self.makeVisible( self.selection[1] )
01038 self.paint()
01039
01040 def selectAll(self):
01041 self.selection = [ 0, len(self.text) ]
01042 self.paint()
01043
01044 def clear(self):
01045
01046 update_info = EditWidget.UpdateInfo(
01047 u"",
01048 [ 0, 0 ]
01049 )
01050
01051 if self.update_handler:
01052 if self.update_handler(update_info)==False:
01053 return
01054
01055 self.text = update_info.text
01056 self.selection = update_info.selection
01057 self.makeVisible( self.selection[1] )
01058 self.paint()
01059
01060 def makeVisible( self, pos ):
01061
01062 def countStringWidthRight( text, pos, width ):
01063 while True:
01064 if pos<0 or pos>len(text)-1 :
01065 width -= 1
01066 else:
01067 width -= self.window.getStringWidth(text[pos])
01068 if width < 0 : break
01069 pos += 1
01070 return pos
01071
01072 def countStringWidthLeft( text, pos, width ):
01073 while True:
01074 pos -= 1
01075 if pos<0 or pos>len(text)-1 :
01076 width -= 1
01077 else:
01078 width -= self.window.getStringWidth(text[pos])
01079 if width < 0 : break
01080 return pos + 1
01081
01082 if pos < countStringWidthRight( self.text, self.scroll_pos+1, self.margin1-1 ) :
01083 self.scroll_pos = max( countStringWidthLeft( self.text, pos, self.margin2 ), -self.margin1 )
01084 elif pos > countStringWidthRight( self.text, self.scroll_pos, self.width-self.margin1 ) :
01085 pos1 = countStringWidthLeft( self.text, pos, self.width-self.margin2 )
01086 pos2 = countStringWidthLeft( self.text, len(self.text), self.width-self.margin1 )
01087 self.scroll_pos = min( pos1, pos2 )
01088
01089 def paint(self):
01090
01091 selection_left = min( self.selection[0], self.selection[1] )
01092 selection_right = max( self.selection[0], self.selection[1] )
01093
01094 x = self.x
01095 width = self.width
01096
01097 attribute_edit = cterm.Attribute( fg=clnch_colortable.edit_fg )
01098 attribute_edit_selected = cterm.Attribute( fg=clnch_colortable.edit_select_fg, bg=clnch_colortable.edit_select_bg )
01099
01100 self.window.putString( x, self.y, width, 1, attribute_edit, u" " * width )
01101
01102 if self.scroll_pos < selection_left:
01103
01104 if self.scroll_pos<0:
01105 left_string = self.text[ 0 : selection_left ]
01106 x += 1
01107 width -= 1
01108 else:
01109 left_string = self.text[ self.scroll_pos : selection_left ]
01110
01111 self.window.putString( x, self.y, width, 1, attribute_edit, left_string )
01112 left_string_width = self.window.getStringWidth(left_string)
01113 x += left_string_width
01114 width -= left_string_width
01115
01116 if selection_left < selection_right:
01117
01118 if self.scroll_pos<selection_left:
01119 mid_string = self.text[ selection_left : selection_right ]
01120 else:
01121 mid_string = self.text[ self.scroll_pos : selection_right ]
01122
01123 if self.enable_cursor:
01124 attr = attribute_edit_selected
01125 else:
01126 attr = attribute_edit
01127
01128 self.window.putString( x, self.y, width, 1, attr, mid_string )
01129 mid_string_width = self.window.getStringWidth(mid_string)
01130 x += mid_string_width
01131 width -= mid_string_width
01132
01133 if selection_right < self.scroll_pos + self.width:
01134
01135 right_string = self.text[ selection_right : ]
01136
01137 self.window.putString( x, self.y, width, 1, attribute_edit, right_string )
01138 right_string_width = self.window.getStringWidth(right_string)
01139 x += right_string_width
01140 width -= right_string_width
01141
01142 if self.enable_cursor:
01143 if self.scroll_pos<0:
01144 left_string = self.text[ 0 : self.selection[1] ]
01145 offset = 1
01146 else:
01147 left_string = self.text[ self.scroll_pos : self.selection[1] ]
01148 offset = 0
01149 self.window.setCursorPos( self.x + offset + self.window.getStringWidth(left_string), self.y )
01150
01151 def getText(self):
01152 return self.text
01153
01154 def setText(self,text):
01155 self.text = text
01156
01157 def getSelection(self):
01158 return self.selection
01159
01160 def setSelection(self,selection):
01161 self.selection = selection
01162
01163 class CandidateWindow( cterm.Window ):
01164
01165 def __init__( self, x, y, min_width, min_height, max_width, max_height, parent_window, keydown_hook=None, selchange_handler=None ):
01166
01167 cterm.Window.__init__(
01168 self,
01169 x=x,
01170 y=y,
01171 width=5,
01172 height=5,
01173 origin= ORIGIN_X_LEFT | ORIGIN_Y_TOP,
01174 parent_window=parent_window,
01175 bg_color = clnch_colortable.candlist_bg,
01176 show = False,
01177 resizable = False,
01178 title_bar = False,
01179 minimizebox = False,
01180 maximizebox = False,
01181 activate_handler = self.onActivate,
01182 keydown_handler = self.onKeyDown,
01183 char_handler = self.onChar,
01184 )
01185
01186 self.parent_window = parent_window
01187
01188 self.min_width = min_width
01189 self.min_height = min_height
01190 self.max_width = max_width
01191 self.max_height = max_height
01192
01193 self.keydown_hook = keydown_hook
01194 self.selchange_handler = selchange_handler
01195
01196 self.setItems( x, y, y, [], 0 )
01197
01198 def setItems( self, x, y1, y2, items, select=0 ):
01199
01200 max_item_width = 0
01201 for item in items:
01202 if isinstance(item,list) or isinstance(item,tuple):
01203 item = item[0]
01204 item_width = self.getStringWidth(item)
01205 if item_width>max_item_width:
01206 max_item_width=item_width
01207
01208 window_width = max_item_width
01209 window_height = len(items)
01210
01211 window_width = max(window_width,self.min_width)
01212 window_height = max(window_height,self.min_height)
01213
01214 window_width = min(window_width,self.max_width)
01215 window_height = min(window_height,self.max_height)
01216
01217
01218 y = y2
01219 monitor_info_list = pyauto.Window.getMonitorInfo()
01220 for monitor_info in monitor_info_list:
01221 if monitor_info[0][0] <= x < monitor_info[0][2] and monitor_info[0][1] <= y1 < monitor_info[0][3]:
01222 window_rect = self.getWindowRect()
01223 char_w, char_h = self.getCharSize()
01224 if y2 + (window_rect[3]-window_rect[1]) + (self.max_height-self.height())*char_h >= monitor_info[1][3]:
01225 y = y1 - ((window_rect[3]-window_rect[1]) + (window_height-self.height())*char_h)
01226 break
01227
01228 if not len(items):
01229 self.show( False, False )
01230
01231 self.setPosSize(
01232 x=x,
01233 y=y,
01234 width=window_width,
01235 height=window_height,
01236 origin= ORIGIN_X_LEFT | ORIGIN_Y_TOP
01237 )
01238
01239 if len(items):
01240 self.show( True, False )
01241
01242 self.items = items
01243 self.scroll_info = clnch_misc.ScrollInfo()
01244 self.select = select
01245 self.scroll_info.makeVisible( self.select, self.height() )
01246
01247
01248
01249
01250
01251 self.paint()
01252
01253 def onActivate( self, active ):
01254 if active:
01255 self.parent_window.activate()
01256
01257 def onKeyDown( self, vk, mod ):
01258
01259 if self.keydown_hook:
01260 if self.keydown_hook( vk, mod ):
01261 return True
01262
01263 if mod==MODKEY_SHIFT:
01264 if vk==VK_SPACE:
01265 if not len(self.items) : return True
01266 self.select -= 1
01267 if self.select<0 : self.select=len(self.items)-1
01268 self.scroll_info.makeVisible( self.select, self.height() )
01269
01270 if self.selchange_handler:
01271 self.selchange_handler( self.select, self.items[self.select] )
01272
01273 self.paint()
01274 return True
01275
01276 elif mod==0:
01277 if vk==VK_SPACE:
01278 if not len(self.items) : return True
01279 self.select += 1
01280 if self.select>len(self.items)-1 : self.select=0
01281 self.scroll_info.makeVisible( self.select, self.height() )
01282
01283 if self.selchange_handler:
01284 self.selchange_handler( self.select, self.items[self.select] )
01285
01286 self.paint()
01287 return True
01288
01289 elif vk==VK_UP:
01290 if not len(self.items) : return True
01291 if self.select>=0:
01292 self.select -= 1
01293 if self.select<0 : self.select=0
01294 else:
01295 self.select=len(self.items)-1
01296 self.scroll_info.makeVisible( self.select, self.height() )
01297
01298 if self.selchange_handler:
01299 self.selchange_handler( self.select, self.items[self.select] )
01300
01301 self.paint()
01302 return True
01303
01304 elif vk==VK_DOWN:
01305 if not len(self.items) : return True
01306 self.select += 1
01307 if self.select>len(self.items)-1 : self.select=len(self.items)-1
01308 self.scroll_info.makeVisible( self.select, self.height() )
01309
01310 if self.selchange_handler:
01311 self.selchange_handler( self.select, self.items[self.select] )
01312
01313 self.paint()
01314 return True
01315
01316 elif vk==VK_PRIOR:
01317 if not len(self.items) : return True
01318
01319 if self.select>=0:
01320 if self.select>self.scroll_info.pos :
01321 self.select = self.scroll_info.pos
01322 else:
01323 self.select -= self.height()
01324 if self.select<0 : self.select=0
01325 else:
01326 self.select=len(self.items)-1
01327
01328 self.scroll_info.makeVisible( self.select, self.height() )
01329
01330 if self.selchange_handler:
01331 self.selchange_handler( self.select, self.items[self.select] )
01332
01333 self.paint()
01334 return True
01335
01336 elif vk==VK_NEXT:
01337 if not len(self.items) : return True
01338 if self.select<self.scroll_info.pos+self.height()-1:
01339 self.select = self.scroll_info.pos+self.height()-1
01340 else:
01341 self.select += self.height()
01342 if self.select>len(self.items)-1 : self.select=len(self.items)-1
01343 self.scroll_info.makeVisible( self.select, self.height() )
01344
01345 if self.selchange_handler:
01346 self.selchange_handler( self.select, self.items[self.select] )
01347
01348 self.paint()
01349 return True
01350
01351 def onChar( self, ch, mod ):
01352 pass
01353
01354 def paint(self):
01355
01356 x=0
01357 y=0
01358 width=self.width()
01359 height=self.height()
01360
01361 attribute_normal = cterm.Attribute( fg=clnch_colortable.fg )
01362 attribute_candidate = cterm.Attribute( fg=clnch_colortable.candlist_fg, bg=clnch_colortable.candlist_bg )
01363 attribute_candidate_selected = cterm.Attribute( fg=clnch_colortable.candlist_select_fg, bg=clnch_colortable.candlist_select_bg )
01364
01365 for i in xrange(height):
01366 index = self.scroll_info.pos+i
01367 if index < len(self.items):
01368
01369 item = self.items[index]
01370 if isinstance(item,list) or isinstance(item,tuple):
01371 item = item[0]
01372
01373 if self.select==index:
01374 attr=attribute_candidate_selected
01375 else:
01376 attr=attribute_candidate
01377 self.putString( x, y+i, width, 1, attr, u" " * width )
01378 self.putString( x, y+i, width, 1, attr, item )
01379 else:
01380 self.putString( x, y+i, width, 1, attribute_normal, u" " * width )
01381
01382 def getSelection(self):
01383 return self.select
01384
01385 def numItems(self):
01386 return len(self.items)
01387
01388 def commonPrefix(self):
01389 if len(self.items)==0 : return u""
01390 common_prefix = self.items[0].lower()
01391 for item in self.items:
01392 name = item.lower()
01393 while 1:
01394 if name.startswith(common_prefix): break
01395 common_prefix = common_prefix[:-1]
01396 if not common_prefix : return u""
01397 return common_prefix
01398
01399
01400
01401
01402
01403 class TimeWidget(Widget):
01404
01405 FOCUS_YEAR = 0
01406 FOCUS_MONTH = 1
01407 FOCUS_DAY = 2
01408 FOCUS_HOUR = 3
01409 FOCUS_MINUTE = 4
01410 FOCUS_SECOND = 5
01411
01412 def __init__( self, window, x, y, timestamp ):
01413
01414 Widget.__init__( self, window, x, y, 22, 1 )
01415
01416 pos1 = self.window.charToClient(x,y)
01417 pos2 = self.window.charToClient(x+22,y+1)
01418 self.skin_edit = clnch_skin.SkinPlane( self.window, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_active.png' ) )
01419 self.skin_edit.adjust( (pos1[0],pos1[1],pos2[0]-pos1[0],pos2[1]-pos1[1]) )
01420
01421 self.year_edit = EditWidget( window, x+1, y, 4, 1, "%04d"%timestamp[0], None, 0, 1, update_handler=self.onYearUpdate )
01422 self.month_edit = EditWidget( window, x+6, y, 2, 1, "%02d"%timestamp[1], None, 0, 1, update_handler=self.onMonthUpdate )
01423 self.day_edit = EditWidget( window, x+9, y, 2, 1, "%02d"%timestamp[2], None, 0, 1, update_handler=self.onDayUpdate )
01424 self.hour_edit = EditWidget( window, x+13, y, 2, 1, "%02d"%timestamp[3], None, 0, 1, update_handler=self.onHourUpdate )
01425 self.minute_edit = EditWidget( window, x+16, y, 2, 1, "%02d"%timestamp[4], None, 0, 1, update_handler=self.onMinuteUpdate )
01426 self.second_edit = EditWidget( window, x+19, y, 2, 1, "%02d"%timestamp[5], None, 0, 1, update_handler=self.onSecondUpdate )
01427
01428 self.year_edit.enableIme(False)
01429 self.month_edit.enableIme(False)
01430 self.day_edit.enableIme(False)
01431 self.hour_edit.enableIme(False)
01432 self.minute_edit.enableIme(False)
01433 self.second_edit.enableIme(False)
01434
01435 self.year_edit.selectAll()
01436 self.month_edit.selectAll()
01437 self.day_edit.selectAll()
01438 self.hour_edit.selectAll()
01439 self.minute_edit.selectAll()
01440 self.second_edit.selectAll()
01441
01442 self.focus = TimeWidget.FOCUS_YEAR
01443
01444 self.paint()
01445
01446 def onYearUpdate( self, info ):
01447 if len(info.text.strip())==0 :
01448 i=0
01449 else:
01450 i = int(info.text)
01451 if i>9999 : return False
01452 info.text = u"%04d"%i
01453 info.selection = [4,4]
01454 return True
01455
01456 def onMonthUpdate( self, info ):
01457 if len(info.text.strip())==0 :
01458 i=0
01459 else:
01460 i = int(info.text)
01461 if i>12 : return False
01462 info.text = u"%02d"%i
01463 info.selection = [2,2]
01464 return True
01465
01466 def onDayUpdate( self, info ):
01467 if len(info.text.strip())==0 :
01468 i=0
01469 else:
01470 i = int(info.text)
01471 if i>31 : return False
01472 info.text = u"%02d"%i
01473 info.selection = [2,2]
01474 return True
01475
01476 def onHourUpdate( self, info ):
01477 if len(info.text.strip())==0 :
01478 i=0
01479 else:
01480 i = int(info.text)
01481 if i>23 : return False
01482 info.text = u"%02d"%i
01483 info.selection = [2,2]
01484 return True
01485
01486 def onMinuteUpdate( self, info ):
01487 if len(info.text.strip())==0 :
01488 i=0
01489 else:
01490 i = int(info.text)
01491 if i>59 : return False
01492 info.text = u"%02d"%i
01493 info.selection = [2,2]
01494 return True
01495
01496 def onSecondUpdate( self, info ):
01497 if len(info.text.strip())==0 :
01498 i=0
01499 else:
01500 i = int(info.text)
01501 if i>59 : return False
01502 info.text = u"%02d"%i
01503 info.selection = [2,2]
01504 return True
01505
01506 def onKeyDown( self, vk, mod ):
01507
01508
01509
01510 if vk==VK_LEFT:
01511 if self.focus==TimeWidget.FOCUS_MONTH:
01512 self.focus=TimeWidget.FOCUS_YEAR
01513 self.year_edit.selectAll()
01514 elif self.focus==TimeWidget.FOCUS_DAY:
01515 self.focus=TimeWidget.FOCUS_MONTH
01516 self.month_edit.selectAll()
01517 elif self.focus==TimeWidget.FOCUS_HOUR:
01518 self.focus=TimeWidget.FOCUS_DAY
01519 self.hour_edit.selectAll()
01520 elif self.focus==TimeWidget.FOCUS_MINUTE:
01521 self.focus=TimeWidget.FOCUS_HOUR
01522 self.minute_edit.selectAll()
01523 elif self.focus==TimeWidget.FOCUS_SECOND:
01524 self.focus=TimeWidget.FOCUS_MINUTE
01525 self.second_edit.selectAll()
01526 self.paint()
01527
01528 elif vk==VK_RIGHT:
01529 if self.focus==TimeWidget.FOCUS_YEAR:
01530 self.focus=TimeWidget.FOCUS_MONTH
01531 self.month_edit.selectAll()
01532 elif self.focus==TimeWidget.FOCUS_MONTH:
01533 self.focus=TimeWidget.FOCUS_DAY
01534 self.day_edit.selectAll()
01535 elif self.focus==TimeWidget.FOCUS_DAY:
01536 self.focus=TimeWidget.FOCUS_HOUR
01537 self.hour_edit.selectAll()
01538 elif self.focus==TimeWidget.FOCUS_HOUR:
01539 self.focus=TimeWidget.FOCUS_MINUTE
01540 self.minute_edit.selectAll()
01541 elif self.focus==TimeWidget.FOCUS_MINUTE:
01542 self.focus=TimeWidget.FOCUS_SECOND
01543 self.second_edit.selectAll()
01544 self.paint()
01545
01546 else:
01547 if self.focus==TimeWidget.FOCUS_YEAR:
01548 self.year_edit.onKeyDown( vk, mod )
01549 elif self.focus==TimeWidget.FOCUS_MONTH:
01550 self.month_edit.onKeyDown( vk, mod )
01551 elif self.focus==TimeWidget.FOCUS_DAY:
01552 self.day_edit.onKeyDown( vk, mod )
01553 elif self.focus==TimeWidget.FOCUS_HOUR:
01554 self.hour_edit.onKeyDown( vk, mod )
01555 elif self.focus==TimeWidget.FOCUS_MINUTE:
01556 self.minute_edit.onKeyDown( vk, mod )
01557 elif self.focus==TimeWidget.FOCUS_SECOND:
01558 self.second_edit.onKeyDown( vk, mod )
01559
01560 def onChar( self, ch, mod ):
01561
01562
01563
01564 if u"0123456789\b".find(unichr(ch)) >= 0:
01565
01566 if self.focus==TimeWidget.FOCUS_YEAR:
01567 self.year_edit.onChar( ch, mod )
01568 elif self.focus==TimeWidget.FOCUS_MONTH:
01569 self.month_edit.onChar( ch, mod )
01570 elif self.focus==TimeWidget.FOCUS_DAY:
01571 self.day_edit.onChar( ch, mod )
01572 elif self.focus==TimeWidget.FOCUS_HOUR:
01573 self.hour_edit.onChar( ch, mod )
01574 elif self.focus==TimeWidget.FOCUS_MINUTE:
01575 self.minute_edit.onChar( ch, mod )
01576 elif self.focus==TimeWidget.FOCUS_SECOND:
01577 self.second_edit.onChar( ch, mod )
01578
01579 def paint(self):
01580
01581 attribute_edit = cterm.Attribute( fg=clnch_colortable.edit_fg )
01582
01583 self.window.putString( self.x, self.y, self.width, 1, attribute_edit, u" / / : : " )
01584
01585 self.year_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_YEAR )
01586 self.year_edit.paint()
01587
01588 self.month_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_MONTH )
01589 self.month_edit.paint()
01590
01591 self.day_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_DAY )
01592 self.day_edit.paint()
01593
01594 self.hour_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_HOUR )
01595 self.hour_edit.paint()
01596
01597 self.minute_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_MINUTE )
01598 self.minute_edit.paint()
01599
01600 self.second_edit.enableCursor( self.enable_cursor and self.focus==TimeWidget.FOCUS_SECOND )
01601 self.second_edit.paint()
01602
01603 def getValue(self):
01604 return (
01605 int(self.year_edit.getText()),
01606 int(self.month_edit.getText()),
01607 int(self.day_edit.getText()),
01608 int(self.hour_edit.getText()),
01609 int(self.minute_edit.getText()),
01610 int(self.second_edit.getText())
01611 )
01612
01613
01614
01615
01616
01617
01618 class ProgressBarWidget(Widget):
01619
01620 busy_anim_speed = 0.4
01621
01622 def __init__( self, window, x, y, width, height ):
01623
01624 Widget.__init__( self, window, x, y, width, height )
01625
01626 def createImage(path):
01627 pil_img = Image.open(path)
01628 pil_img = pil_img.convert( "RGBA" )
01629 return cterm.Image.fromString( pil_img.size, pil_img.tostring(), (0,0,0) )
01630 img0 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/progress0.png' ))
01631 img1 = createImage(os.path.join( os.path.split(sys.argv[0])[0], 'skin/progress1.png' ))
01632
01633 self.frame_plane = cterm.Plane( self.window, (0,0), (0,0), 1 )
01634 self.frame_plane.setImage(img0)
01635 self.bar_plane = cterm.Plane( self.window, (0,0), (0,0), 0 )
01636 self.bar_plane.setImage(img1)
01637
01638 self.busy_mode = False
01639 self.busy_anim_phase = 0
01640 self.busy_anim_theta = 0
01641 self.busy_anim_chase = 0
01642 self.value = [ 0, 0 ]
01643
01644 self.paint()
01645
01646 def destroy(self):
01647 self.window.killTimer(self._onTimer)
01648 self.frame_plane.destroy()
01649 self.bar_plane.destroy()
01650
01651 def show(self,visible):
01652 self.frame_plane.show(visible)
01653 self.bar_plane.show(visible)
01654
01655 def paint(self):
01656
01657 pos1 = self.window.charToClient( self.x, self.y )
01658 pos2 = self.window.charToClient( self.x+self.width, self.y+self.height )
01659 margin_y = 2
01660
01661 self.frame_plane.setPos( ( pos1[0], pos1[1]+margin_y ) )
01662 self.frame_plane.setSize( ( pos2[0]-pos1[0], pos2[1]-pos1[1]-margin_y ) )
01663
01664 self.bar_plane.setPos( ( pos1[0] + int((pos2[0]-pos1[0])*self.value[0]), pos1[1]+margin_y ) )
01665 self.bar_plane.setSize( ( int((pos2[0]-pos1[0])*(self.value[1]-self.value[0])), pos2[1]-pos1[1]-margin_y ) )
01666
01667 attr = cterm.Attribute( fg=clnch_colortable.edit_fg )
01668 self.window.putString( self.x, self.y, self.width, 1, attr, u" " * self.width )
01669
01670 def setValue( self, value ):
01671 if value!=None:
01672 value = max( value, 0.0 )
01673 value = min( value, 1.0 )
01674
01675 if self.value[1] != value:
01676 self.value[0] = 0.0
01677 self.value[1] = value
01678 self.paint()
01679 else:
01680 if not self.busy_mode:
01681 self.busy_mode = True
01682 self.busy_anim_phase = 0
01683 self.busy_anim_theta = 0
01684 self.busy_anim_chase = 0
01685 self.window.setTimer( self._onTimer, 50 )
01686
01687 def getValue(self):
01688 return self.value[1]
01689
01690 def _onTimer(self):
01691
01692 if self.busy_anim_phase==0:
01693 self.busy_anim_theta += ProgressBarWidget.busy_anim_speed
01694 if self.busy_anim_theta > math.pi*0.5:
01695 self.busy_anim_phase = 1
01696
01697 elif self.busy_anim_phase==1:
01698 self.busy_anim_theta += ProgressBarWidget.busy_anim_speed
01699 self.busy_anim_chase += ProgressBarWidget.busy_anim_speed
01700 if self.busy_anim_theta > math.pi:
01701 self.busy_anim_theta = math.pi
01702 self.busy_anim_phase = 2
01703
01704 elif self.busy_anim_phase==2:
01705 self.busy_anim_chase += ProgressBarWidget.busy_anim_speed
01706 if self.busy_anim_chase > math.pi:
01707 self.busy_anim_chase = math.pi
01708 self.busy_anim_phase = 3
01709
01710 elif self.busy_anim_phase==3:
01711 self.busy_anim_theta -= ProgressBarWidget.busy_anim_speed
01712 if self.busy_anim_theta < math.pi*0.5:
01713 self.busy_anim_phase = 4
01714
01715 elif self.busy_anim_phase==4:
01716 self.busy_anim_theta -= ProgressBarWidget.busy_anim_speed
01717 self.busy_anim_chase -= ProgressBarWidget.busy_anim_speed
01718 if self.busy_anim_theta < 0:
01719 self.busy_anim_theta = 0
01720 self.busy_anim_phase = 5
01721
01722 elif self.busy_anim_phase==5:
01723 self.busy_anim_chase -= ProgressBarWidget.busy_anim_speed
01724 if self.busy_anim_chase < 0:
01725 self.busy_anim_chase = 0
01726 self.busy_anim_phase = 0
01727
01728 value1 = math.cos(self.busy_anim_theta) * 0.5 + 0.5
01729 value2 = math.cos(self.busy_anim_chase) * 0.5 + 0.5
01730
01731 self.value = [ min(value1,value2), max(value1,value2) ]
01732
01733 self.paint()