CraftLaunch APIリファレンス

clnch_mainwindow.py

00001 import os
00002 import sys
00003 import re
00004 import time
00005 import datetime
00006 import profile
00007 import fnmatch
00008 import threading
00009 import zipfile
00010 import ConfigParser
00011 import filecmp
00012 import traceback
00013 
00014 import pyauto
00015 import cterm
00016 from cterm.cterm_const import *
00017 
00018 import clnch_statusbar
00019 import clnch_msgbox
00020 import clnch_listwindow
00021 import clnch_consolewindow
00022 import clnch_musicplayer
00023 import clnch_configmenu
00024 import clnch_commandline
00025 import clnch_widget
00026 import clnch_skin
00027 import clnch_misc
00028 import clnch_ini
00029 import clnch_native
00030 import clnch_threadutil
00031 import clnch_subprocess
00032 import clnch_resource
00033 import clnch_colortable
00034 from clnch_resource import *
00035 
00036 KeyEvent = clnch_misc.KeyEvent
00037 ChrEvent = clnch_misc.ChrEvent
00038 KeyMapCondition = clnch_misc.KeyMapCondition
00039 
00040 os.stat_float_times(False)
00041 
00042 #--------------------------------------------------------------------
00043 
00044 PAINT_STATUS_BAR         = 1<<14
00045 PAINT_ALL                = PAINT_STATUS_BAR
00046 
00047 class MainWindow( cterm.Window ):
00048 
00049     def __init__( self, config_filename, debug=False, profile=False ):
00050     
00051         self.initialized = False
00052 
00053         self.config_filename = config_filename
00054 
00055         self.debug = debug
00056         self.profile = profile
00057 
00058         self.loadState()
00059 
00060         clnch_colortable.loadSetting()
00061 
00062         self.skin_enabled = False
00063 
00064         cterm.Window.__init__(
00065             self,
00066             x=0,
00067             y=0,
00068             width=clnch_ini.getint( "GEOMETRY", "min_width", 18 ),
00069             height=1,
00070             font_name = clnch_ini.get( "FONT", "name", "" ),
00071             font_size = clnch_ini.getint( "FONT", "size", 12 ),
00072             bg_color = clnch_colortable.bg,
00073             border_size = 3,
00074             resizable = False,
00075             title_bar = False,
00076             title = clnch_resource.clnch_appname,
00077             show = False,
00078             cursor = True,
00079             icon=False,
00080             activate_handler = self._onActivate,
00081             close_handler = self._onClose,
00082             endsession_handler = self._onEndSession,
00083             move_handler = self._onMove,
00084             size_handler = self._onSize,
00085             keydown_handler = self._onKeyDown,
00086             char_handler = self._onChar,
00087             lbuttondown_handler = self._onLeftButtonDown,
00088             rbuttondown_handler = self._onRightButtonDown,
00089             )
00090             
00091         self.resetPos()
00092             
00093         self.updateTopMost()
00094         
00095         self.show(True)
00096 
00097         self.setCursorPos( -1, -1 )
00098 
00099         self.updateHotKey()
00100         
00101         self.status_bar = clnch_statusbar.StatusBar()
00102         self.simple_status_bar_layer = clnch_statusbar.SimpleStatusBarLayer()
00103         self.simple_status_bar_resistered = False
00104         self.custom_status_bar_map = {}
00105         self.status_bar_paint_hook = None
00106         self.commandline_edit = None
00107 
00108         self.cmd_keymap = clnch_misc.KeyMap()
00109         self.cmd_keymap2 = clnch_misc.KeyMap()
00110         self.compare_list = []
00111         self.sorter_list = []
00112         self.association_list = []
00113         self.editor = u"notepad.exe"
00114         self.clock_format = u"%m/%d(%a) %H:%M"
00115         self.commandline_list = []
00116         self.commandline_history = []
00117         self.commandLineHistoryLoad()
00118         
00119         self.launcher = clnch_commandline.commandline_Launcher(self)
00120 
00121         self.keydown_hook = None
00122         self.char_hook = None
00123         self.enter_hook = None
00124         self.mouse_event_mask = False
00125         
00126         self.quit_requested = False
00127         
00128         self.mouse_click_info = None
00129 
00130         self.musicplayer = None
00131 
00132         self.task_queue = clnch_threadutil.JobQueue()
00133         self.synccall = clnch_threadutil.SyncCall()
00134 
00135         self.child_window_lock = threading.RLock()
00136 
00137         self.setTimer( self.onTimer, 10 )
00138 
00139         clnch_misc.registerNetConnectionHandler( self._onCheckNetConnection )
00140 
00141         try:
00142             self.skinInit()
00143         except:
00144             traceback.print_exc()
00145 
00146         self.console_window = clnch_consolewindow.ConsoleWindow( self, debug=debug )
00147         self.console_window.registerStdio()
00148 
00149         self.updateInactiveBehavior()
00150 
00151         self.initialized = True
00152 
00153         self.paint()
00154 
00155     def destroy(self):
00156         self.console_window.unregisterStdio()
00157         self.console_window.destroy()
00158         cterm.Window.destroy(self)
00159 
00160     def onTimer(self):
00161         clnch_threadutil.JobQueue.checkAll()
00162         self.synccall.check()
00163 
00164     def subThreadCall( self, func, arg, cancel_func=None, cancel_func_arg=(), raise_error=False, print_traceback=False ):
00165 
00166         class SubThread( threading.Thread ):
00167 
00168             def __init__( self, main_window ):
00169                 threading.Thread.__init__(self)
00170                 self.main_window = main_window
00171                 self.result = None
00172                 self.error = None
00173 
00174             def run(self):
00175                 try:
00176                     self.result = func(*arg)
00177                 except Exception, e:
00178                     if print_traceback:
00179                         traceback.print_exc()
00180                     self.error = e
00181 
00182         def onKeyDown( vk, mod ):
00183             if vk==VK_ESCAPE:
00184                 if cancel_func:
00185                     cancel_func(*cancel_func_arg)
00186             return True
00187 
00188         def onChar( ch, mod ):
00189             return True
00190 
00191         keydown_hook_old = self.keydown_hook
00192         char_hook_old = self.char_hook
00193         mouse_event_mask_old = self.mouse_event_mask
00194 
00195         sub_thread = SubThread(self)
00196         sub_thread.start()
00197 
00198         self.keydown_hook = onKeyDown
00199         self.char_hook = onChar
00200         self.mouse_event_mask = True
00201 
00202         self.removeKeyMessage()
00203         self.messageLoop( sub_thread.isAlive )
00204 
00205         sub_thread.join()
00206         result = sub_thread.result
00207         error = sub_thread.error
00208         del sub_thread
00209 
00210         self.keydown_hook = keydown_hook_old
00211         self.char_hook = char_hook_old
00212         self.mouse_event_mask = mouse_event_mask_old
00213 
00214         if error:
00215             if raise_error:
00216                 raise error
00217             else:
00218                 print error
00219         
00220         return result
00221 
00222     def subProcessCall( self, cmd, cwd=None, env=None, enable_cancel=False ):
00223 
00224         p = clnch_subprocess.SubProcess(cmd,cwd,env)
00225         
00226         if enable_cancel:
00227             cancel_handler = p.cancel
00228         else:
00229             cancel_handler = None
00230 
00231         return self.subThreadCall( p, (), cancel_handler )
00232 
00233     def taskEnqueue( self, job_item, comment=u"" ):
00234         if comment and self.task_queue.numItems()>0:
00235             self.setStatusMessage( u"タスクを予約しました : %s" % comment, 3000 )
00236         self.task_queue.enqueue(job_item)
00237 
00238     def commandLine( self, title, text=u"", selection=None, auto_complete=False, autofix_list=None, update_handler=None, candidate_handler=None, status_handler=None, keydown_handler=None, char_handler=None, enter_handler=None, escape_handler=None ):
00239 
00240         if title:
00241             title = u" " + title + u" "
00242         title_width = self.getStringWidth(title)
00243         status_string = [ u"" ]
00244         result = [ None ]
00245 
00246         class CommandLine:
00247 
00248             def __init__( commandline_self ):
00249                 pass
00250                 
00251             def _onKeyDown( commandline_self, vk, mod ):
00252             
00253                 if keydown_handler:
00254                     if keydown_handler( commandline_self, vk, mod ):
00255                         return True
00256             
00257                 if self.commandline_edit.onKeyDown( vk, mod ):
00258                     return True
00259 
00260                 if vk==VK_RETURN:
00261                     result[0] = self.commandline_edit.getText()
00262                     if enter_handler:
00263                         commandline_self.closeList()
00264                         if enter_handler( commandline_self, result[0], mod ):
00265                             return True
00266                     commandline_self.quit()
00267 
00268                 elif vk==VK_ESCAPE:
00269                     if self.commandline_edit.getText():
00270                         self.commandline_edit.clear()
00271                     else:
00272                         if escape_handler:
00273                             if escape_handler(commandline_self):
00274                                 return True
00275                         commandline_self.quit()
00276 
00277                 return True
00278 
00279             def _onChar( commandline_self, ch, mod ):
00280 
00281                 if char_handler:
00282                     if char_handler( commandline_self, ch, mod ):
00283                         return True
00284             
00285                 self.commandline_edit.onChar( ch, mod )
00286 
00287                 return True
00288 
00289             def _onUpdate( commandline_self, update_info ):
00290                 if update_handler:
00291                     if not update_handler(update_info):
00292                         return False
00293                 if status_handler:
00294                     status_string[0] = status_handler(update_info)
00295                     self.paint(PAINT_STATUS_BAR)
00296                 commandline_self.updateWindowWidth(update_info.text)
00297 
00298             def _onPaint( commandline_self, x, y, width, height ):
00299             
00300                 if status_string[0]:
00301                     status_string_for_paint = u"  " + status_string[0] + u" "
00302                 else:
00303                     status_string_for_paint = u""
00304                 status_width = self.getStringWidth(status_string_for_paint)
00305                 edit_width = width-title_width-status_width
00306 
00307                 attr = cterm.Attribute( fg=clnch_colortable.bar_fg )
00308                 
00309                 if self.active:
00310                     self.putString( x, y, title_width, height, attr, title )
00311                     self.putString( x+width-status_width, y, status_width, height, attr, status_string_for_paint )
00312                 else:
00313                     self.putString( x, y, title_width, height, attr, u" "*title_width )
00314                     self.putString( x+width-status_width, y, status_width, height, attr, u" "*status_width )
00315 
00316                 if self.skin_enabled:
00317 
00318                     client_rect = self.getClientRect()
00319                     offset_x, offset_y = self.charToClient( 0, 0 )
00320                     char_w, char_h = self.getCharSize()
00321                     up_shift = 1
00322 
00323                     self.skin_edit_active.adjust(   ( title_width*char_w+offset_x, offset_y-up_shift, edit_width*char_w, char_h+up_shift ) )
00324                     self.skin_edit_inactive.adjust( ( title_width*char_w+offset_x, offset_y-up_shift, edit_width*char_w, char_h+up_shift ) )
00325 
00326                 self.commandline_edit.setPosSize( x+title_width, y, edit_width, height )
00327 
00328                 self.commandline_edit.enableCursor( self.active )
00329                 if not self.active:
00330                     self.setCursorPos( -1, -1 )
00331                 
00332                 self.commandline_edit.paint()
00333 
00334             def paint(commandline_self):
00335                 self.paint()
00336 
00337             def getText(commandline_self):
00338                 return self.commandline_edit.getText()
00339             
00340             def setText( commandline_self, text ):
00341                 self.commandline_edit.setText(text)
00342 
00343             def getSelection(commandline_self):
00344                 return self.commandline_edit.getSelection()
00345 
00346             def setSelection(commandline_self,selection):
00347                 self.commandline_edit.setSelection(selection)
00348 
00349             def selectAll(commandline_self):
00350                 self.commandline_edit.selectAll()
00351 
00352             def closeList(commandline_self):
00353                 self.commandline_edit.closeList()
00354 
00355             def updateWindowWidth( commandline_self, text ):
00356                 text_width = self.getStringWidth(text)
00357                 delta = text_width - self.commandline_edit.width + 2
00358                 if delta==0 : return
00359                 new_width = self.width() + delta
00360                 new_width = max( new_width, clnch_ini.getint( "GEOMETRY", "min_width", 18 ) )
00361                 new_width = min( new_width, clnch_ini.getint( "GEOMETRY", "max_width", 80 ) )
00362                 window_rect = self.getWindowRect()
00363                 self.setPosSize( window_rect[0], window_rect[1], new_width, self.height(), 0 )                    
00364 
00365             def appendHistory(commandline_self,newentry):
00366                 newentry_lower = newentry.lower()
00367                 for i in xrange(len(self.commandline_history)):
00368                     if self.commandline_history[i].lower()==newentry_lower:
00369                         del self.commandline_history[i]
00370                         break
00371                 self.commandline_history.insert( 0, newentry )
00372 
00373                 if len(self.commandline_history)>1000:
00374                     self.commandline_history = self.commandline_history[:1000]
00375 
00376             def quit(commandline_self):
00377                 commandline_self.updateWindowWidth(u"")
00378                 self.quit()
00379 
00380         commandline_edit_old = self.commandline_edit
00381         keydown_hook_old = self.keydown_hook
00382         char_hook_old = self.char_hook
00383         mouse_event_mask_old = self.mouse_event_mask
00384         status_bar_paint_hook_old = self.status_bar_paint_hook
00385 
00386         commandline = CommandLine()
00387         
00388         self.commandline_edit = clnch_widget.EditWidget( self, title_width, self.height()-1, self.width()-title_width, 1, text, selection, auto_complete=auto_complete, no_bg=True, autofix_list=autofix_list, update_handler=commandline._onUpdate, candidate_handler=candidate_handler )
00389         self.keydown_hook = commandline._onKeyDown
00390         self.char_hook = commandline._onChar
00391         self.mouse_event_mask = True
00392         self.status_bar_paint_hook = commandline._onPaint
00393 
00394         if status_handler:
00395             status_string[0] = status_handler(clnch_widget.EditWidget.UpdateInfo(text,selection))
00396 
00397         if self.skin_enabled:
00398             self.skin_edit_active.show(self.active)
00399             self.skin_edit_inactive.show(not self.active)
00400 
00401         self.paint(PAINT_STATUS_BAR)
00402 
00403         self.removeKeyMessage()
00404         def checkContinue():
00405             return self.active or len(self.commandline_edit.getText())>0
00406         self.messageLoop( checkContinue )
00407 
00408         self.commandline_edit.destroy()
00409 
00410         self.enableIme(False)
00411 
00412         self.commandline_edit = commandline_edit_old
00413         self.keydown_hook = keydown_hook_old
00414         self.char_hook = char_hook_old
00415         self.mouse_event_mask = mouse_event_mask_old
00416         self.status_bar_paint_hook = status_bar_paint_hook_old
00417         
00418         if self.skin_enabled:
00419             self.skin_edit_active.show(False)
00420             self.skin_edit_inactive.show(False)
00421 
00422         self.setCursorPos( -1, -1 )
00423         self.skinUpdate()
00424 
00425         self.paint(PAINT_STATUS_BAR)
00426 
00427         return result[0]
00428 
00429     def commandLineHistoryLoad(self):
00430         for i in xrange(1000):
00431             try:
00432                 self.commandline_history.append( unicode( clnch_ini.get( "COMMANDLINE", "history_%d"%(i,) ), "utf8" ) )
00433             except:
00434                 break
00435 
00436     def commandLineHistorySave(self):
00437         i=0
00438         while i<len(self.commandline_history):
00439             clnch_ini.set( "COMMANDLINE", "history_%d"%(i,), self.commandline_history[i].encode("utf8") )
00440             i+=1
00441         while True:
00442             if not clnch_ini.remove_option( "COMMANDLINE", "history_%d"%(i,) ) : break
00443             i+=1
00444 
00445     def _onActivate( self, active ):
00446         
00447         self.active = active
00448         
00449         if self.skin_enabled and self.commandline_edit:
00450             self.skin_edit_active.show(self.active)
00451             self.skin_edit_inactive.show(not self.active)
00452 
00453         self.paint()
00454 
00455     def _onClose( self ):
00456         self.quit()
00457 
00458     def _onEndSession( self ):
00459         self.saveState()
00460         clnch_ini.write()    
00461 
00462     def _onMove( self, x, y ):
00463 
00464         if not self.initialized : return
00465 
00466         if self.commandline_edit:
00467             self.commandline_edit.onWindowMove()
00468 
00469     def _onSize( self, width, height ):
00470         self.skinUpdate()
00471         self.paint()
00472 
00473     def _onKeyDown( self, vk, mod ):
00474 
00475         #print "_onKeyDown", vk, mod
00476 
00477         if self.keydown_hook:
00478             if self.keydown_hook( vk, mod ):
00479                 return True
00480 
00481         return True
00482 
00483     def _onChar( self, ch, mod ):
00484 
00485         #print "_onChar", ch, mod
00486 
00487         if self.char_hook:
00488             if self.char_hook( ch, mod ):
00489                 return
00490 
00491     def _onLeftButtonDown( self, x, y, mod ):
00492 
00493         #print "_onLeftButtonDown", x, y, mod
00494 
00495         #if self.mouse_event_mask : return
00496         
00497         self.drag(x,y);
00498         
00499     def _onRightButtonDown( self, x, y, mod ):
00500         
00501         #print "_onRightButtonDown", x, y, mod
00502 
00503         #if self.mouse_event_mask : return
00504         
00505         pass
00506 
00507     def _onCheckNetConnection( self, remote_resource_name ):
00508         
00509         def addConnection( hwnd, remote_resource_name ):
00510             try:
00511                 clnch_native.addConnection( hwnd, remote_resource_name )
00512             except Exception, e:
00513                 print u"ERROR : 接続失敗 : %s" % remote_resource_name
00514                 print e, "\n"
00515     
00516         self.synccall( addConnection, (self.getHWND(), remote_resource_name) )
00517             
00518     def ratioToScreen( self, ratio ):
00519         rect = self.getWindowRect()
00520         return ( int(rect[0] * (1-ratio[0]) + rect[2] * ratio[0]), int(rect[1] * (1-ratio[1]) + rect[3] * ratio[1]) )
00521 
00522     def centerOfWindowInPixel(self):
00523         rect = self.getWindowRect()
00524         return ( (rect[0]+rect[2])/2, (rect[1]+rect[3])/2 )
00525 
00526     def statusBar(self):
00527         return self.status_bar
00528 
00529     def registerStatusBar( self, func, priority=-1, interval=None ):
00530 
00531         if self.custom_status_bar_map.has_key( func ):
00532             return
00533         
00534         class CustomStatusBarLayer(clnch_statusbar.StatusBarLayer):
00535 
00536             def __init__( layer_self ):
00537                 clnch_statusbar.StatusBarLayer.__init__( layer_self, priority )
00538                 if interval:
00539                     self.setTimer( layer_self.onTimer, interval )
00540             
00541             def destroy( layer_self ):
00542                 if interval:
00543                     self.killTimer( layer_self.onTimer )
00544                 
00545             def paint( layer_self, window, x, y, width, height ):
00546                 s = u" %s" % ( func(width) )
00547                 s = clnch_misc.adjustStringWidth( window, s, width-1 )
00548                 attr = cterm.Attribute( fg=clnch_colortable.bar_fg )
00549                 window.putString( x, y, width, height, attr, s )
00550         
00551             def onTimer( layer_self ):
00552                 if self.commandline_edit==None and self.status_bar.isActiveLayer(layer_self):
00553                     self.paint( PAINT_STATUS_BAR )
00554         
00555         custom_status_bar_layer = CustomStatusBarLayer()
00556         self.status_bar.registerLayer(custom_status_bar_layer)
00557         self.custom_status_bar_map[func] = custom_status_bar_layer
00558     
00559     def unregisterStatusBar( self, func ):
00560 
00561         if not self.custom_status_bar_map.has_key( func ):
00562             return
00563 
00564         custom_status_bar_layer = self.custom_status_bar_map[func]
00565         self.status_bar.unregisterLayer(custom_status_bar_layer)
00566         custom_status_bar_layer.destroy()
00567         del self.custom_status_bar_map[func]
00568             
00569     def _onStatusMessageTimedout(self):
00570         self.clearStatusMessage()
00571 
00572     def setStatusMessage( self, message, timeout=None, error=False ):
00573 
00574         self.simple_status_bar_layer.setMessage(message,error)
00575 
00576         if not self.simple_status_bar_resistered:
00577             self.status_bar.registerLayer(self.simple_status_bar_layer)
00578             self.simple_status_bar_resistered = True
00579 
00580         if timeout!=None:
00581             self.killTimer( self._onStatusMessageTimedout )
00582             self.setTimer( self._onStatusMessageTimedout, timeout )
00583 
00584         self.paint( PAINT_STATUS_BAR )
00585 
00586     def clearStatusMessage( self ):
00587         self.simple_status_bar_layer.setMessage(u"")
00588         self.status_bar.unregisterLayer(self.simple_status_bar_layer)
00589         self.simple_status_bar_resistered = False
00590         self.paint( PAINT_STATUS_BAR )
00591         self.killTimer(self._onStatusMessageTimedout)
00592 
00593     def cursorFromHistory( self, file_list, history ):
00594         history_item = history.find( file_list.getLocation() )
00595         if history_item==None : return 0
00596         cursor = file_list.indexOf( history_item[1] )
00597         if cursor<0 : return 0
00598         return cursor
00599 
00600     #--------------------------------------------------------------------------
00601 
00602     def skinInit(self):
00603         self.skin_statusbar = clnch_skin.SkinPlane( self, os.path.join( os.path.split(sys.argv[0])[0], 'skin/statusbar.png' ), 1.5 )
00604         self.skin_edit_active = clnch_skin.SkinPlane( self, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_active.png' ), 1 )
00605         self.skin_edit_inactive = clnch_skin.SkinPlane( self, os.path.join( os.path.split(sys.argv[0])[0], 'skin/edit_inactive.png' ), 1 )
00606         self.skin_edit_active.show(False)
00607         self.skin_edit_inactive.show(False)
00608 
00609         self.skin_enabled = True
00610 
00611         self.skinUpdate()
00612 
00613     def skinUpdate(self):
00614 
00615         if not self.skin_enabled : return
00616 
00617         client_rect = self.getClientRect()
00618         offset_x, offset_y = self.charToClient( 0, 0 )
00619         char_w, char_h = self.getCharSize()
00620 
00621         self.skin_statusbar.adjust( ( 0, 0, client_rect[2], client_rect[3] ) )
00622 
00623     #--------------------------------------------------------------------------
00624 
00625     def updateColor(self):
00626         self.setBGColor( clnch_colortable.bg )
00627         self.paint()
00628 
00629     #--------------------------------------------------------------------------
00630 
00631     def updateFont(self):
00632         self.setFont( clnch_ini.get( "FONT", "name", "" ), clnch_ini.getint( "FONT", "size", 12 ) )
00633         window_rect = self.getWindowRect()
00634         self.setPosSize( window_rect[0], window_rect[1], self.width(), self.height(), 0 )
00635         
00636         self.console_window.updateFont()
00637 
00638     #--------------------------------------------------------------------------
00639 
00640     def _onTimerTopmost(self):
00641         wnd = pyauto.Window.fromHWND( self.getHWND() )
00642         wnd = wnd.getPrevious()
00643         while wnd:
00644             if( wnd.isVisible() 
00645             and not wnd.getClassName().startswith(u"#")
00646             and not wnd.getClassName() in ( u"ClnchWindowClass", u"SysShadow" )
00647             and not wnd.getProcessName().lower().endswith(".scr") ):
00648                 #print "_onTimerTopmost", wnd.getClassName(), wnd.getText(), wnd.getProcessName()
00649                 self.topmost(True)
00650                 break
00651             wnd = wnd.getPrevious()
00652         
00653     def updateTopMost(self):
00654         
00655         topmost = clnch_ini.getint( "GEOMETRY", "topmost", 0 )
00656         self.topmost(topmost!=0)
00657         
00658         if topmost==2:
00659             self.setTimer( self._onTimerTopmost, 10 )
00660         else:
00661             self.killTimer( self._onTimerTopmost )
00662 
00663     #--------------------------------------------------------------------------
00664 
00665     def resetPos(self):
00666 
00667         rect = self.getWindowRect()
00668 
00669         monitor = clnch_ini.getint( "GEOMETRY", "monitor", 0 )
00670         x = clnch_ini.getint( "GEOMETRY", "x", 0 )
00671         y = clnch_ini.getint( "GEOMETRY", "y", 0 )
00672         
00673         monitor_info_list = pyauto.Window.getMonitorInfo()
00674         if not monitor<len(monitor_info_list):
00675             monitor = 0
00676             x = 0
00677             y = 0
00678         
00679         monitor_info = monitor_info_list[monitor]
00680         if x>=0:
00681             x = monitor_info[0][0] + x
00682         else:
00683             x = monitor_info[0][2] + x - (rect[2]-rect[0]) + 1
00684 
00685         if y>=0:
00686             y = monitor_info[0][1] + y
00687         else:
00688             y = monitor_info[0][3] + y - (rect[3]-rect[1]) + 1
00689 
00690         self.setPosSize( x, y, self.width(), self.height(), 0 )                    
00691 
00692     #--------------------------------------------------------------------------
00693 
00694     def _statusbar_Clock( self, width ):
00695         now = datetime.datetime.now()
00696         return now.strftime(self.clock_format)
00697 
00698     def updateInactiveBehavior(self):
00699 
00700         inactive_behavior = clnch_ini.get( "MISC", "inactive_behavior", "washy" )
00701         
00702         if inactive_behavior=="clock":
00703             self.registerStatusBar( self._statusbar_Clock, priority=-1, interval=1000 )
00704         else:    
00705             self.unregisterStatusBar( self._statusbar_Clock )
00706 
00707     #--------------------------------------------------------------------------
00708 
00709     def paint( self, option=PAINT_ALL ):
00710     
00711         if not self.initialized : return
00712 
00713         if option & PAINT_STATUS_BAR:
00714             if self.status_bar_paint_hook:
00715                 self.status_bar_paint_hook( 0, self.height()-1, self.width(), 1 )
00716             else:
00717                 self.status_bar.paint( self, 0, self.height()-1, self.width(), 1 )
00718 
00719     #--------------------------------------------------------------------------
00720 
00721     def configure(self):
00722 
00723         default_keymap = clnch_ini.get( "MISC", "default_keymap", "106" )
00724 
00725         self.cmd_keymap = clnch_misc.KeyMap()
00726         self.cmd_keymap2 = clnch_misc.KeyMap()
00727         self.cmd_keymap2[ KeyEvent( VK_SPACE, MODKEY_ALT ) ] = self.command_AutoCompleteToggle
00728         self.cmd_keymap[ KeyEvent( VK_OEM_PERIOD, MODKEY_CTRL ) ] = self.command_MusicList
00729         self.cmd_keymap[ KeyEvent( VK_OEM_PERIOD, MODKEY_CTRL|MODKEY_SHIFT ) ] = self.command_MusicStop
00730         if default_keymap=="101":
00731             self.cmd_keymap[ KeyEvent( VK_OEM_2, MODKEY_CTRL ) ] = self.command_ContextMenu
00732         elif default_keymap=="106":
00733             self.cmd_keymap[ KeyEvent( VK_OEM_102, MODKEY_CTRL ) ] = self.command_ContextMenu
00734 
00735         self.association_list = [
00736             ( u"*.mp3 *.wma *.wav", self.command_MusicPlay ), 
00737         ]
00738 
00739         self.commandline_list = [
00740             self.launcher,
00741             clnch_commandline.commandline_ExecuteURL(self),
00742             clnch_commandline.commandline_ExecuteFile(self),
00743             clnch_commandline.commandline_Calculator(self),
00744         ]
00745         
00746         self.launcher.command_list = [
00747             ( u"Edit",      self.command_Edit ),
00748             ( u"History",   self.command_History ),
00749             ( u"Config",    self.command_ConfigMenu ),
00750             ( u"Reload",    self.command_Reload ),
00751             ( u"About",     self.command_About ),
00752             ( u"Quit",      self.command_Quit ),
00753         ]
00754 
00755         try:
00756             fd = file( self.config_filename, 'r' )
00757             fileimage = fd.read()
00758             user_namespace = {}
00759             code = compile( fileimage, self.config_filename, 'exec' )
00760             exec code in user_namespace, user_namespace
00761             user_namespace["configure"](self)
00762         except:
00763             print u'ERROR : error occured while reading config file.'
00764             traceback.print_exc()
00765 
00766 
00767     def loadState(self):
00768         
00769         if clnch_ini.get( "MISC", "directory_separator", "backslash" )=="slash":
00770             clnch_misc.use_slash = True
00771         else:
00772             clnch_misc.use_slash = False
00773 
00774     def saveState(self):
00775 
00776         print u"Save State"
00777         try:
00778             clnch_ini.set( "GEOMETRY", "width", str(self.width()) )
00779             clnch_ini.set( "GEOMETRY", "height", str(self.height()) )
00780 
00781             self.commandLineHistorySave()
00782             
00783             self.console_window.saveState()
00784 
00785             if self.musicplayer:
00786                 self.musicplayer.save( "MUSIC" )
00787                 clnch_ini.set( "MUSIC", "restore", str(1) )
00788             else:
00789                 clnch_ini.set( "MUSIC", "restore", str(0) )
00790 
00791         except Exception, e:
00792             print u"Failed"
00793             print "  %s" % unicode(str(e),'mbcs')
00794         else:
00795             print u'Done.'
00796 
00797     #--------------------------------------------------------------------------
00798 
00799     def start(self):
00800         
00801         print clnch_resource.startupString()
00802 
00803         # 音楽プレイヤの復元
00804         if clnch_ini.getint( "MUSIC", "restore", 0 ):
00805             if self.musicplayer==None:
00806                 self.musicplayer = clnch_musicplayer.MusicPlayer(self)
00807             self.musicplayer.load( "MUSIC" )    
00808         
00809         self.console_window.setAutoShow(True)    
00810 
00811     def stop(self):
00812         self.console_window.setAutoShow(False)    
00813 
00814     #--------------------------------------------------------------------------
00815 
00816     def _inactiveMessageLoop(self):
00817 
00818         inactive_behavior = clnch_ini.get( "MISC", "inactive_behavior", "washy" )
00819 
00820         if inactive_behavior in ("washy","hide"):
00821 
00822             def _onPaint( x, y, width, height ):
00823                 attr = cterm.Attribute( fg=clnch_colortable.bar_fg )
00824                 self.putString( x, y, width, height, attr, u" "*width )
00825 
00826             status_bar_paint_hook_old = self.status_bar_paint_hook
00827 
00828             self.status_bar_paint_hook = _onPaint
00829 
00830             if self.skin_enabled:
00831                 self.skin_edit_active.show(False)
00832                 self.skin_edit_inactive.show(True)
00833 
00834             self.paint(PAINT_STATUS_BAR)
00835         
00836         if inactive_behavior=="hide":
00837             self.show(False)
00838 
00839         self.removeKeyMessage()
00840         def checkContinue():
00841             return not self.active
00842         self.messageLoop( checkContinue )
00843 
00844         if inactive_behavior in ("washy","hide"):
00845             self.status_bar_paint_hook = status_bar_paint_hook_old
00846     
00847             if self.skin_enabled:
00848                 self.skin_edit_active.show(False)
00849                 self.skin_edit_inactive.show(False)
00850 
00851             self.paint(PAINT_STATUS_BAR)
00852 
00853     def topLevelMessageLoop(self):
00854 
00855         def onCandidate( update_info ):
00856 
00857             left = update_info.text[ : update_info.selection[0] ]
00858             left_lower = left.lower()
00859             pos_arg = left.rfind(";")+1
00860             arg = left[ pos_arg : ]
00861             pos_dir = max( arg.rfind("/")+1, arg.rfind("\\")+1 )
00862             directory = arg[:pos_dir]
00863             directory_lower = directory.lower()
00864             name_prefix = arg[pos_dir:].lower()
00865 
00866             candidate_list = []
00867             candidate_map = {}
00868 
00869             for item in self.commandline_history:
00870                 item_lower = item.lower()
00871                 if item_lower.startswith(left_lower) and len(item_lower)!=len(left_lower):
00872                     cand = item[ pos_arg + pos_dir : ]
00873                     if not candidate_map.has_key(cand):
00874                         candidate_list.append( cand )
00875                         candidate_map[cand] = True
00876 
00877             for commandline_function in self.commandline_list:
00878                 for cand in commandline_function.onCandidate( update_info ):
00879                     if not candidate_map.has_key(cand):
00880                         candidate_list.append( cand )
00881                         candidate_map[cand] = True
00882 
00883             return candidate_list, pos_arg + pos_dir
00884 
00885         def statusString( update_info ):
00886             if update_info.text:
00887                 for commandline_function in self.commandline_list:
00888                     s = commandline_function.onStatusString(update_info.text)
00889                     if s!=None:
00890                         return s
00891             return None
00892 
00893         def onKeyDown( commandline, vk, mod ):
00894             try:
00895                 func = self.cmd_keymap[ KeyMapCondition( KeyEvent(vk,mod) ) ]
00896                 quit = True
00897             except KeyError:
00898                 try:
00899                     func = self.cmd_keymap2[ KeyMapCondition( KeyEvent(vk,mod) ) ]
00900                     quit = False
00901                 except KeyError:
00902                     return
00903             text = commandline.getText()    
00904             args = text.split(';')
00905             clnch_commandline.executeCommand( commandline, func, args, 0, text, quit=quit )
00906             return True
00907 
00908         def onChar( commandline, ch, mod ):
00909             try:
00910                 func = self.cmd_keymap[ KeyMapCondition( ChrEvent(ch) ) ]
00911             except KeyError:
00912                 try:
00913                     func = self.cmd_keymap2[ KeyMapCondition( ChrEvent(ch) ) ]
00914                     quit = False
00915                 except KeyError:
00916                     return
00917             text = commandline.getText()    
00918             args = text.split(';')
00919             clnch_commandline.executeCommand( commandline, func, args, 0, text, quit=quit )
00920             return True
00921 
00922         def onEnter( commandline, text, mod ):
00923             for commandline_function in self.commandline_list:
00924                 if commandline_function.onEnter( commandline, text, mod ):
00925                     break
00926             return True
00927 
00928         def onEscape( commandline ):
00929             self.console_window.show(False)
00930             self.resetPos()
00931             self.inactivate()
00932             return True
00933 
00934         while not self.quit_requested:
00935 
00936             if self.active:
00937                 auto_complete = clnch_ini.getint( "MISC", "auto_complete", "1" )
00938                 self.commandLine( u"", auto_complete=auto_complete, autofix_list=["\\/",".",";"], candidate_handler=onCandidate, status_handler=statusString, keydown_handler=onKeyDown, char_handler=onChar, enter_handler=onEnter, escape_handler=onEscape )
00939             else:
00940                 self._inactiveMessageLoop()
00941 
00942     #--------------------------------------------------------------------------
00943 
00944     def hotkey_Activate(self):
00945         self.restore()
00946         self.foreground()
00947         if self.isEnabled():
00948             self.activate()
00949 
00950     def updateHotKey(self):
00951 
00952         activate_vk = clnch_ini.getint( "HOTKEY", "activate_vk", 0 )
00953         activate_mod = clnch_ini.getint( "HOTKEY", "activate_mod", 0 )
00954 
00955         self.killHotKey( self.hotkey_Activate )
00956         self.setHotKey( activate_vk, activate_mod, self.hotkey_Activate )
00957 
00958     #--------------------------------------------------------
00959     # ここから下のメソッドはキーに割り当てることができる
00960     #--------------------------------------------------------
00961 
00962     def command_Edit( self, args ):
00963 
00964         def edit():
00965             for arg in args:
00966                 if not os.path.isfile(arg) : continue
00967                 if callable(self.editor):
00968                     self.editor(arg)
00969                 else:
00970                     directory, tmp = os.path.split(arg)
00971                     clnch_misc.shellExecute( None, None, self.editor, arg, directory )
00972 
00973         self.subThreadCall( edit, () )
00974 
00975     def command_ContextMenu( self, args ):
00976         
00977         if len(args)<=0 :
00978             return
00979         if not os.path.exists(args[0]) :
00980             return
00981         dirname, name = os.path.split( os.path.normpath(args[0]) )
00982         
00983         self.commandline_edit.closeList()
00984         
00985         pos = self.charToScreen( self.commandline_edit.x + self.commandline_edit.width, 1 )
00986         self.removeKeyMessage()
00987         clnch_native.popupContextMenu( self.getHWND(), pos[0], pos[1], dirname, [name] )
00988 
00989     def command_Quit(self):
00990         self.quit_requested = True
00991         self.quit()
00992 
00993     def command_MusicList(self):
00994 
00995         if not self.musicplayer:
00996             self.setStatusMessage( u"Musicがありません", 1000, error=True )
00997             return
00998 
00999         musicplayer_items, selection = self.musicplayer.getPlayList()
01000 
01001         items = []
01002         for music_item in musicplayer_items:
01003             items.append( music_item )
01004 
01005         def onKeyDown( vk, mod ):
01006 
01007             if vk==VK_OEM_PERIOD and mod==MODKEY_CTRL:
01008                 self.musicplayer.pause()
01009                 if self.musicplayer.isPlaying():
01010                     self.setStatusMessage( u"Music : 再開", 3000 )
01011                 else:
01012                     self.setStatusMessage( u"Music : 一時停止", 3000 )
01013                 list_window.cancel()
01014                 return True
01015 
01016             elif vk==VK_OEM_PERIOD and mod==MODKEY_CTRL|MODKEY_SHIFT:
01017                 self.command_MusicStop()
01018                 list_window.cancel()
01019                 return True
01020 
01021             elif vk==VK_LEFT and mod==MODKEY_CTRL:
01022                 self.musicplayer.advance( -10.0 )
01023 
01024             elif vk==VK_RIGHT and mod==MODKEY_CTRL:
01025                 self.musicplayer.advance( 10.0 )
01026 
01027         def onStatusMessage( width, select ):
01028             return u""
01029 
01030         pos = self.centerOfWindowInPixel()
01031         list_window = clnch_listwindow.ListWindow( pos[0], pos[1], 5, 1, 80, 16, self, False, u"music player", items, initial_select=selection, keydown_hook=onKeyDown, onekey_search=False, statusbar_handler=onStatusMessage )
01032         clnch_misc.adjustWindowPosition( self, list_window, default_up=False )
01033         list_window.show(True)
01034         self.enable(False)
01035         list_window.messageLoop()
01036         result = list_window.getResult()
01037         self.enable(True)
01038         self.activate()
01039         list_window.destroy()
01040 
01041         if result<0 : return
01042 
01043         self.musicplayer.select(result)
01044 
01045     def command_MusicPlay( self, args ):
01046 
01047         playlist = []
01048         selection = 0
01049 
01050         for arg in args:
01051             dirname, name = os.path.split(arg)
01052             ext = os.path.splitext(arg)[1].lower()
01053             fileinfo_list = clnch_native.findFile( os.path.join(dirname,"*") )
01054             for fileinfo in fileinfo_list:
01055                 if os.path.splitext(fileinfo[0])[1].lower()==ext:
01056                     if not (fileinfo[3] & clnch_misc.FILE_ATTRIBUTE_DIRECTORY):
01057                         playlist.append( clnch_misc.joinPath( dirname, fileinfo[0] ) )
01058                         if arg==args[0] and fileinfo[0].lower()==name.lower():
01059                             selection = len(playlist)-1
01060 
01061         if len(playlist) :
01062             if self.musicplayer==None:
01063                 self.musicplayer = clnch_musicplayer.MusicPlayer(self)
01064             self.musicplayer.setPlayList( playlist, selection )
01065             self.musicplayer.play()
01066 
01067     def command_MusicStop(self):
01068         if self.musicplayer:
01069             self.musicplayer.destroy()
01070             self.musicplayer = None
01071             self.setStatusMessage( u"Music : 停止", 3000 )
01072 
01073     def command_ShellExecute( self, verb, file, param, directory, swmode=clnch_misc.SW_NORMAL ):
01074 
01075         def jobShellExecute( job_item ):
01076         
01077             _file = file
01078             _param = param
01079             _directory = directory
01080 
01081             if _param==None or len(_param)==0:
01082                 _param = u"%param%"
01083             
01084             joint_args = clnch_misc.joinArgs(job_item.args)
01085 
01086             _file = clnch_misc.replaceMacro( _file, { "%%":"%", "%param%":joint_args }, environ=True )
01087             _param = clnch_misc.replaceMacro( _param, { "%%":"%", "%param%":joint_args }, environ=True )
01088             _directory = clnch_misc.replaceMacro( _directory, { "%%":"%", "%param%":joint_args }, environ=True )
01089             
01090             try:
01091                 clnch_misc.shellExecute( None, verb, file, _param, directory, swmode, raise_error=True )
01092             except Exception, e:
01093                 print u'Error : 実行に失敗'
01094                 print u"  %s" % unicode(str(e),'mbcs')
01095 
01096         def jobShellExecuteFinished( job_item ):
01097             pass
01098 
01099         def _shellExecute( args ):
01100             job_item = clnch_threadutil.JobItem( jobShellExecute, jobShellExecuteFinished )
01101             job_item.args = args
01102             self.taskEnqueue( job_item, u"ShellExecute" )
01103 
01104         return _shellExecute
01105 
01106     def command_URL( self, url, encoding=u"utf8" ):
01107 
01108         def jobShellExecute( job_item ):
01109         
01110             _url = url
01111             
01112             if len(job_item.args) > 0 :
01113                 import urllib
01114                 keyword = job_item.args[0].encode(encoding)
01115                 keyword = urllib.quote_plus(keyword)
01116             else:
01117                 keyword = u""
01118 
01119             _url = clnch_misc.replaceMacro( _url, { "%%":"%", "%param%":keyword }, environ=False )
01120 
01121             clnch_misc.shellExecute( None, None, _url, u"", u"" )
01122 
01123         def jobShellExecuteFinished( job_item ):
01124             pass
01125 
01126         def _shellExecute( args ):
01127             job_item = clnch_threadutil.JobItem( jobShellExecute, jobShellExecuteFinished )
01128             job_item.args = args
01129             self.taskEnqueue( job_item, u"URL" )
01130 
01131         return _shellExecute
01132 
01133     def command_History( self, args, mod ):
01134 
01135         items = []
01136         
01137         for item in self.commandline_history:
01138             if item:
01139                 items.append( ( item, ) )
01140 
01141         initial_select = 0
01142         max_width = clnch_ini.getint( "GEOMETRY", "max_width", 80 )
01143 
01144         def onKeyDown( vk, mod ):
01145             if vk==VK_DELETE and mod==0:
01146                 select = list_window.getResult()
01147                 self.commandline_history.remove(items[select][0])
01148                 list_window.remove(select)
01149                 return True
01150 
01151         def onStatusMessage( width, select ):
01152             return u""
01153 
01154         pos = self.centerOfWindowInPixel()
01155         list_window = clnch_listwindow.ListWindow( pos[0], pos[1], 5, 1, max_width, 16, self, False, u"履歴リスト", items, initial_select=0, keydown_hook=onKeyDown, onekey_search=False, statusbar_handler=onStatusMessage )
01156         clnch_misc.adjustWindowPosition( self, list_window, default_up=True )
01157         list_window.show(True)
01158         self.enable(False)
01159         list_window.messageLoop()
01160         result = list_window.getResult()
01161         self.enable(True)
01162         self.activate()
01163         list_window.destroy()
01164 
01165         if result<0 : return
01166 
01167         return items[result][0]
01168 
01169     def command_ConfigMenu(self):
01170         clnch_configmenu.doConfigMenu(self)
01171 
01172     def command_Reload(self):
01173         self.configure()
01174         print u"設定スクリプトをリロードしました.\n"
01175 
01176     def command_ConsoleOpen(self):
01177         self.console_window.show(True)
01178         self.activate()
01179 
01180     def command_ConsoleClose(self):
01181         self.console_window.show(False)
01182 
01183     def command_ConsoleToggle(self):
01184         if self.console_window.isVisible():
01185             self.command_ConsoleClose()
01186         else:
01187             self.command_ConsoleOpen()
01188 
01189     def command_AutoCompleteOn(self):
01190         if self.commandline_edit:
01191             print u"自動補完 ON\n"
01192             self.commandline_edit.setAutoComplete(True)
01193 
01194     def command_AutoCompleteOff(self):
01195         if self.commandline_edit:
01196             print u"自動補完 OFF\n"
01197             self.commandline_edit.setAutoComplete(False)
01198 
01199     def command_AutoCompleteToggle(self):
01200         if self.commandline_edit:
01201             if self.commandline_edit.getAutoComplete():
01202                 self.command_AutoCompleteOff()
01203             else:    
01204                 self.command_AutoCompleteOn()
01205 
01206     def command_About(self):
01207         print clnch_resource.startupString()
01208 
01209 #--------------------------------------------------------------------

Copyright © 2009 craftware. All rights reserved.