NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

command.py (28218B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\carbonui\services\command.py
      2 import sys
      3 import blue
      4 import bluepy
      5 import carbon.client.script.sys.appUtils as appUtils
      6 import carbonui.const as uiconst
      7 import localization
      8 import log
      9 import trinity
     10 import uthread
     11 from auraguidance.client import aura_guidance_signals
     12 from carbon.common.script.sys.service import Service
     13 from carbonui.control.contextMenu.menuUtil import CloseContextMenus
     14 from carbonui.control.window import Window
     15 from carbonui.uicore import uicore
     16 from carbonui.util.various_unsorted import GetClipboardData
     17 from eve.client.script.ui.inflight import actionConst
     18 from eve.devtools.script.enginetools import EngineToolsLauncher
     19 from eveprefs import boot
     20 from jobboard.client import job_board_signals
     21 from player_messaging.client.ui_message import prompt_player_fsd_dialog
     22 from threadutils import throttled
     23 NUMPAD_KEYS = []
     24 for num in range(0, 10):
     25     NUMPAD_KEYS.append(getattr(uiconst, 'VK_NUMPAD%s' % num, num + 96))
     26 
     27 VK_KEYS = [ key for key in dir(uiconst) if key.startswith('VK_') ]
     28 RENAMEMAP = {'CONTROL': 'CTRL',
     29  'MENU': 'ALT',
     30  'MBUTTON': 'MOUSE3',
     31  'XBUTTON1': 'MOUSE4',
     32  'XBUTTON2': 'MOUSE5',
     33  'SNAPSHOT': 'PRINTSCREEN',
     34  'NEXT': 'PAGEDOWN',
     35  'PRIOR': 'PAGEUP'}
     36 labelsByFuncName = {'CmdCloseActiveWindow': '/Carbon/UI/Commands/CmdCloseActiveWindow',
     37  'CmdCloseAllWindows': '/Carbon/UI/Commands/CmdCloseAllWindows',
     38  'CmdLogOff': 'UI/Commands/CmdLogOff',
     39  'CmdMinimizeActiveWindow': '/Carbon/UI/Commands/CmdMinimizeActiveWindow',
     40  'CmdToggleMinimizeMaximizeAllWindows': '/Carbon/UI/Commands/CmdMinimizeAllWindows',
     41  'CmdToggleCollapseAllWindows': '/Carbon/UI/Commands/ToggleCollapseAllWindows',
     42  'CmdQuitGame': 'UI/Commands/CmdQuitGame',
     43  'CmdResetMonitor': '/Carbon/UI/Commands/CmdResetMonitor',
     44  'CmdToggleAudio': '/Carbon/UI/Commands/CmdToggleAudio',
     45  'OnCtrlA': '/Carbon/UI/Commands/OnCtrlA',
     46  'OnCtrlC': '/Carbon/UI/Commands/OnCtrlC',
     47  'OnCtrlShiftTab': '/Carbon/UI/Commands/OnCtrlShiftTab',
     48  'OnCtrlTab': '/Carbon/UI/Commands/OnCtrlTab',
     49  'OnCtrlV': '/Carbon/UI/Commands/OnCtrlV',
     50  'OnCtrlX': '/Carbon/UI/Commands/OnCtrlX',
     51  'OnEsc': '/Carbon/UI/Commands/OnEsc',
     52  'OnReturn': '/Carbon/UI/Commands/OnReturn',
     53  'OnShiftTab': '/Carbon/UI/Commands/OnShiftTab',
     54  'OnTab': '/Carbon/UI/Commands/OnTab',
     55  'OpenMonitor': '/Carbon/UI/Commands/OpenMonitor',
     56  'PrintScreen': '/Carbon/UI/Commands/PrintScreen',
     57  'WinCmdToggleWindowed': '/Carbon/UI/Commands/WinCmdToggleWindowed',
     58  'CmdBack': '/Carbon/UI/Commands/Back',
     59  'CmdForward': '/Carbon/UI/Commands/Forward'}
     60 
     61 def GetKeyName(key):
     62     import trinity
     63     newKey = trinity.app.GetKeyNameText(key)
     64     if not newKey:
     65         newKey = ', '.join([ each[3:] for each in VK_KEYS if getattr(uiconst, each) == key ])
     66         newKey = RENAMEMAP.get(newKey, newKey)
     67     return newKey
     68 
     69 
     70 class CommandMapping:
     71 
     72     def __init__(self, callback, shortcut, category = None, isLocked = False, enabled = True, ignoreModifierKey = False, repeatable = False, hintPath = None):
     73         self.callback = callback
     74         self.name = self.callback.__name__
     75         self.SetShortcut(shortcut)
     76         self.category = category or 'general'
     77         self.isLocked = isLocked
     78         self.ignoreModifierKey = ignoreModifierKey
     79         self.repeatable = repeatable
     80         self.hint = hintPath
     81 
     82     def __repr__(self):
     83         return "<CommandMapping instance -  name='%s', shortcut='%s', callback=%s>" % (self.name, self.shortcut, self.callback)
     84 
     85     def GetShortcutAsString(self):
     86         if not self.shortcut:
     87             return ''
     88         retString = uicore.cmd.GetStringFromShortcutKeys(self.shortcut)
     89         return retString
     90 
     91     def GetDescription(self):
     92         if hasattr(self.callback, 'nameLabelPath'):
     93             return localization.GetByLabel(self.callback.nameLabelPath)
     94         if getattr(self.callback, 'nameString', None):
     95             return self.callback.nameString
     96         return uicore.cmd.FuncToDesc(self.name)
     97 
     98     def GetIcon(self):
     99         action_id = actionConst.ACTION_ID_BY_CMD.get(self.name, None)
    100         return actionConst.ICON_BY_ACTIONID.get(action_id, None)
    101 
    102     def GetName(self):
    103         if getattr(self.callback, 'nameFunc', None):
    104             return self.callback.nameFunc()
    105         if getattr(self.callback, 'nameLabelPath', None):
    106             return localization.GetByLabel(self.callback.nameLabelPath)
    107         if getattr(self.callback, 'nameString', None):
    108             return self.callback.nameString
    109 
    110     def GetDetailedDescription(self):
    111         if hasattr(self.callback, 'detailedDescription'):
    112             return localization.GetByLabel(self.callback.detailedDescription)
    113         if getattr(self.callback, 'descriptionLabelPath', None):
    114             return localization.GetByLabel(self.callback.descriptionLabelPath)
    115         if getattr(self.callback, 'descriptionString', None):
    116             return self.callback.descriptionString
    117         if getattr(self.callback, 'descriptionFunc', None):
    118             return self.callback.descriptionFunc()
    119 
    120     def SetShortcut(self, shortcut):
    121         self.shortcut = self._ValidateShortcut(shortcut)
    122 
    123     def _ValidateShortcut(self, shortcut):
    124         if shortcut is None:
    125             return
    126         if type(shortcut) is int:
    127             shortcut = (shortcut,)
    128         return shortcut
    129 
    130     def GetAccelerator(self):
    131         if not self.shortcut:
    132             return None
    133         vkey = self.shortcut[-1]
    134         shortcutModKeys = self.shortcut[:-1]
    135         modKeys = []
    136         for modKey in uiconst.MODKEYS:
    137             modKeys.append(modKey in shortcutModKeys)
    138 
    139         return (tuple(modKeys), vkey)
    140 
    141 
    142 class CommandMap:
    143 
    144     def __init__(self, defaultCmds = [], customCmds = {}):
    145         self.commandsByName = {}
    146         self.commandsByShortcut = {}
    147         self.accelerators = {}
    148         self.customCmds = customCmds
    149         for c in defaultCmds:
    150             self.AddCommand(c)
    151 
    152     def HasCommand(self, commandName):
    153         return commandName in self.commandsByName
    154 
    155     def AddCommand(self, command):
    156         for shortcut in self.customCmds.itervalues():
    157             if command.shortcut == shortcut:
    158                 command.shortcut = None
    159 
    160         if command.name in self.customCmds:
    161             command.shortcut = self.customCmds[command.name]
    162             command.shortcut = self._ModernizeOldTypeShortcut(command.shortcut)
    163         if self.GetCommandByName(command.name) is None:
    164             self.commandsByName[command.name] = command
    165             if command.shortcut is not None:
    166                 self.commandsByShortcut[command.shortcut] = command
    167         else:
    168             log.LogWarn('Trying to add the same command twice: %s' % command.name)
    169 
    170     def RemoveCommand(self, command):
    171         if command and self.GetCommandByName(command.name):
    172             del self.commandsByName[command.name]
    173             if command.shortcut is not None:
    174                 del self.commandsByShortcut[command.shortcut]
    175 
    176     def RemapCommand(self, cmdname, newShortcut = None):
    177         if newShortcut:
    178             newShortcut = tuple(newShortcut)
    179         cmd = self.GetCommandByName(cmdname)
    180         self.UnloadAccelerator(cmd)
    181         oldShortcut = cmd.shortcut
    182         if oldShortcut and oldShortcut in self.commandsByShortcut:
    183             self.commandsByShortcut.pop(tuple(cmd.shortcut))
    184         self.customCmds[cmdname] = newShortcut
    185         if newShortcut:
    186             self.commandsByShortcut[newShortcut] = cmd
    187         settings.user.cmd.customCmds[cmdname] = newShortcut
    188         cmd.SetShortcut(newShortcut)
    189         self.LoadAccelerator(cmd)
    190 
    191     def _ModernizeOldTypeShortcut(self, shortcut):
    192         if not shortcut or len(shortcut) != 4:
    193             return shortcut
    194         for i in xrange(3):
    195             if shortcut[i] not in (0, 1):
    196                 return shortcut
    197 
    198         newShortcut = []
    199         if shortcut[0]:
    200             newShortcut.append(uiconst.VK_CONTROL)
    201         if shortcut[1]:
    202             newShortcut.append(uiconst.VK_MENU)
    203         if shortcut[2]:
    204             newShortcut.append(uiconst.VK_SHIFT)
    205         try:
    206             vkKey = getattr(uiconst, 'VK_%s' % shortcut[-1].upper())
    207         except:
    208             return None
    209 
    210         newShortcut.append(vkKey)
    211         return tuple(newShortcut)
    212 
    213     def GetAllCommands(self):
    214         return self.commandsByName.values()
    215 
    216     def Reset(self):
    217         self.UnloadAccelerators()
    218 
    219     def GetAllUnmappedCommands(self):
    220         retCmds = []
    221         for c in self.commandsByName.values():
    222             if c.shortcut is None:
    223                 retCmds.append(c)
    224 
    225         return retCmds
    226 
    227     def GetAllMappedCommands(self):
    228         retCmds = []
    229         for c in self.commandsByName.values():
    230             if c.shortcut is not None:
    231                 retCmds.append(c)
    232 
    233         return retCmds
    234 
    235     def GetCommandByShortcut(self, shortcut):
    236         return self.commandsByShortcut.get(shortcut)
    237 
    238     def GetCommandByName(self, cmdname):
    239         return self.commandsByName.get(cmdname)
    240 
    241     def GetCommandCategoryNames(self):
    242         categories = []
    243         for c in self.GetAllCommands():
    244             if c.category not in categories:
    245                 categories.append(c.category)
    246 
    247         return categories
    248 
    249     def UnloadAcceleratorsByCategory(self, category):
    250         for cmd in self.commandsByName.values():
    251             if cmd.category == category:
    252                 self.UnloadAccelerator(cmd)
    253 
    254     def LoadAcceleratorsByCategory(self, category):
    255         for cmd in self.commandsByName.values():
    256             if cmd.category == category:
    257                 self.LoadAccelerator(cmd)
    258 
    259     def LoadAccelerator(self, cmd):
    260         accelerator = cmd.GetAccelerator()
    261         if accelerator is None:
    262             return
    263         self.accelerators[accelerator] = cmd
    264 
    265     def UnloadAccelerator(self, cmd):
    266         accelerator = cmd.GetAccelerator()
    267         if accelerator is None or accelerator not in self.accelerators:
    268             return
    269         del self.accelerators[accelerator]
    270 
    271     def LoadAllAccelerators(self):
    272         for c in self.GetAllCommands():
    273             self.LoadAccelerator(c)
    274 
    275     def UnloadAllAccelerators(self):
    276         for c in self.commandsByName.values():
    277             self.UnloadAccelerator(c)
    278 
    279 
    280 class CommandService(Service):
    281     __guid__ = 'svc.cmd'
    282     __update_on_reload__ = 1
    283     __startupdependencies__ = ['settings']
    284     __notifyevents__ = ['OnSessionChanged']
    285 
    286     def Run(self, memStream = None):
    287         super(CommandService, self).Run(memStream)
    288         self.labelsByFuncName = labelsByFuncName
    289         self.Reload()
    290         job_board_signals.on_job_board_feature_availability_changed.connect(self.OnJobBoardAvailabilityChanged)
    291         job_board_signals.on_missions_feature_availability_changed.connect(self.OnJobBoardAvailabilityChanged)
    292         aura_guidance_signals.on_availability_changed.connect(self.OnAuraGuidanceAvailabilityChanged)
    293 
    294     def Reload(self, forceGenericOnly = False):
    295         self.settings.LoadSettings()
    296         if not settings.user.cmd.customCmds:
    297             settings.user.cmd.customCmds = {}
    298         self.defaultShortcutMapping = self.SetDefaultShortcutMappingCORE()
    299         self.defaultShortcutMapping.extend(self.SetDefaultShortcutMappingGAME())
    300         self.CheckDuplicateShortcuts()
    301         if hasattr(self, 'commandMap'):
    302             self.commandMap.UnloadAllAccelerators()
    303         self.commandMap = CommandMap(defaultCmds=self.defaultShortcutMapping, customCmds=settings.user.cmd.customCmds)
    304         if session.charid is not None and forceGenericOnly is False:
    305             self.commandMap.LoadAllAccelerators()
    306         else:
    307             self.commandMap.LoadAcceleratorsByCategory('general')
    308 
    309     def Stop(self, memStream):
    310         super(CommandService, self).Stop(memStream)
    311 
    312     @throttled(1.0)
    313     def OnJobBoardAvailabilityChanged(self, *args, **kwargs):
    314         self.Reload()
    315 
    316     def OnAuraGuidanceAvailabilityChanged(self, _evaluate_flag):
    317         self.Reload()
    318 
    319     def CheckDuplicateShortcuts(self):
    320         for cmd in self.defaultShortcutMapping:
    321             for cmdCheck in self.defaultShortcutMapping:
    322                 if cmdCheck.shortcut:
    323                     sameName = cmdCheck.name == cmd.name
    324                     sameShortcut = cmdCheck.shortcut == cmd.shortcut
    325                     if sameShortcut and not sameName:
    326                         self.LogError('Same default shortcut used for multiple commands:', cmd)
    327 
    328     def OnSessionChanged(self, isRemote, sess, change):
    329         if 'userid' in change:
    330             self.Reload()
    331         if 'charid' in change:
    332             self.commandMap.LoadAllAccelerators()
    333 
    334     def SetDefaultShortcutMappingCORE(self):
    335         ret = []
    336         c = CommandMapping
    337         CTRL = uiconst.VK_CONTROL
    338         ALT = uiconst.VK_MENU
    339         SHIFT = uiconst.VK_SHIFT
    340         COMMAND = uiconst.VK_LWIN
    341 
    342         def k(win, mac):
    343             if sys.platform.startswith('darwin'):
    344                 return mac
    345             return win
    346 
    347         m = [c(self.OnReturn, uiconst.VK_RETURN),
    348          c(self.OnCtrlA, (k(win=CTRL, mac=COMMAND), uiconst.VK_A)),
    349          c(self.OnCtrlC, (k(win=CTRL, mac=COMMAND), uiconst.VK_C)),
    350          c(self.OnCtrlX, (k(win=CTRL, mac=COMMAND), uiconst.VK_X)),
    351          c(self.OnCtrlV, (k(win=CTRL, mac=COMMAND), uiconst.VK_V)),
    352          c(self.OnEsc, uiconst.VK_ESCAPE),
    353          c(self.OnCtrlShiftTab, (CTRL, SHIFT, uiconst.VK_TAB)),
    354          c(self.OnCtrlTab, (CTRL, uiconst.VK_TAB)),
    355          c(self.OnTab, uiconst.VK_TAB),
    356          c(self.OnShiftTab, (SHIFT, uiconst.VK_TAB))]
    357         for cm in m:
    358             cm.category = 'general'
    359             cm.isLocked = True
    360             ret.append(cm)
    361 
    362         m = [c(self.CmdQuitGame, (ALT, SHIFT, uiconst.VK_Q)),
    363          c(self.CmdLogOff, None),
    364          c(self.CmdToggleAudio, (CTRL,
    365           ALT,
    366           SHIFT,
    367           uiconst.VK_F12)),
    368          c(self.WinCmdToggleWindowed, (ALT, uiconst.VK_RETURN)),
    369          c(self.CmdResetMonitor, (CTRL, ALT, uiconst.VK_RETURN)),
    370          c(self.OpenMonitor, (CTRL,
    371           ALT,
    372           SHIFT,
    373           uiconst.VK_M)),
    374          c(self.CmdBack, uiconst.VK_XBUTTON1),
    375          c(self.CmdForward, uiconst.VK_XBUTTON2)]
    376         if sys.platform.startswith('darwin'):
    377             m.append(c(self.PrintScreen, (CTRL, uiconst.VK_P)))
    378         else:
    379             m.append(c(self.PrintScreen, uiconst.VK_SNAPSHOT))
    380         for cm in m:
    381             cm.category = 'general'
    382             ret.append(cm)
    383 
    384         m = [c(self.CmdCloseAllWindows, (CTRL, ALT, uiconst.VK_W)),
    385          c(self.CmdToggleMinimizeMaximizeAllWindows, None),
    386          c(self.CmdMinimizeActiveWindow, None),
    387          c(self.CmdCloseActiveWindow, (CTRL, uiconst.VK_W)),
    388          c(self.CmdToggleCollapseAllWindows, None)]
    389         for cm in m:
    390             cm.category = 'window'
    391             ret.append(cm)
    392 
    393         return ret
    394 
    395     def SetDefaultShortcutMappingGAME(self):
    396         return []
    397 
    398     def EditCmd(self, cmdname, context = None):
    399         if self.IsLocked(cmdname):
    400             prompt_player_fsd_dialog('ShortcutLocked')
    401             return
    402         command = self.commandMap.GetCommandByName(cmdname)
    403         self.MapCmd(cmdname, context)
    404 
    405     def MapCmd(self, *args, **kwds):
    406         pass
    407 
    408     def CheckKeyDown(self, edit, vkey, flag):
    409         if vkey == uiconst.VK_RETURN:
    410             return
    411         edit.SetValue(self.GetKeyNameFromVK(vkey))
    412 
    413     def MapCmdErrorCheck(self, retval):
    414         return ''
    415 
    416     def ClearMappedCmd(self, cmdname, showMsg = 1):
    417         if self.IsLocked(cmdname):
    418             if showMsg:
    419                 prompt_player_fsd_dialog('ShortcutLocked')
    420             return
    421         self.commandMap.RemapCommand(cmdname, None)
    422         sm.ScatterEvent('OnMapShortcut', cmdname, None, None, None, None)
    423 
    424     def RestoreDefaults(self):
    425         settings.user.cmd.customCmds = {}
    426         self.Reload()
    427         sm.ScatterEvent('OnRestoreDefaultShortcuts')
    428 
    429     def IsLocked(self, cmdname):
    430         command = self.commandMap.GetCommandByName(cmdname)
    431         if command and command.isLocked:
    432             return True
    433         else:
    434             return False
    435 
    436     def IsTaken(self, cmdname):
    437         return self.GetFuncByShortcut(cmdname) is None
    438 
    439     def MapKeys(self, VK):
    440         if VK in NUMPAD_KEYS:
    441             num = NUMPAD_KEYS.index(VK)
    442             VK = getattr(uiconst, 'VK_%s' % num)
    443         return VK
    444 
    445     def GetCommandCategoryNames(self):
    446         return self.commandMap.GetCommandCategoryNames()
    447 
    448     def GetKeyNameFromVK(self, VK):
    449         VK = self.MapKeys(VK)
    450         return ', '.join([ each[3:] for each in VK_KEYS if getattr(uiconst, each) == VK ])
    451 
    452     def GetVKFromChar(self, char):
    453         return [ each for each in VK_KEYS if unichr(getattr(uiconst, each)) == char ]
    454 
    455     def GetFuncByShortcut(self, shortcut):
    456         command = self.commandMap.GetCommandByShortcut(shortcut)
    457         if command:
    458             return command.name
    459         else:
    460             return None
    461 
    462     def GetShortcutByFuncName(self, funcname, format = False):
    463         command = self.commandMap.GetCommandByName(funcname)
    464         if command:
    465             if format:
    466                 return command.GetShortcutAsString()
    467             else:
    468                 return command.shortcut
    469         else:
    470             return None
    471 
    472     def GetShortcutStringByFuncName(self, funcname):
    473         command = self.commandMap.GetCommandByName(funcname)
    474         if command:
    475             return command.GetShortcutAsString()
    476         else:
    477             return ''
    478 
    479     def GetShortcutByString(self, stringfunc):
    480         command = self.commandMap.GetCommandByName(stringfunc)
    481         if command and command.shortcut:
    482             return command.GetShortcutAsString()
    483         else:
    484             return None
    485 
    486     def UnpackFuncName(self, funcname):
    487         nameSpace, className, funcname = funcname.split('.')
    488         return funcname
    489 
    490     def FuncToDesc(self, funcname):
    491         if funcname in self.labelsByFuncName:
    492             return localization.GetByLabel(self.labelsByFuncName[funcname])
    493         try:
    494             myCmd = self.commandMap.GetCommandByName(funcname)
    495             if myCmd and myCmd.callback and getattr(myCmd.callback, 'nameLabelPath', None):
    496                 return localization.GetByLabel(myCmd.callback.nameLabelPath)
    497         except Exception:
    498             pass
    499 
    500         return funcname
    501 
    502     def GetActiveCmds(self):
    503         return self.commandMap.GetAllMappedCommands()
    504 
    505     def GetUnmappedCmds(self):
    506         return self.commandMap.GetAllUnmappedCommands()
    507 
    508     def GetCustomCmd(self, cmdname):
    509         return self.customCmds.get(cmdname, None)
    510 
    511     def CheckCtrlUp(self, wnd, msgID, ckey):
    512         chooseWndMenu = getattr(self, 'chooseWndMenu', None)
    513         if chooseWndMenu and not chooseWndMenu.destroyed and chooseWndMenu.state != uiconst.UI_HIDDEN:
    514             chooseWndMenu.ChooseHilited()
    515         self.chooseWndMenu = None
    516         return 1
    517 
    518     def _AppQuitGame(self):
    519         bluepy.Terminate(0, 'User requesting close')
    520 
    521     def CmdQuitGame(self):
    522         if prompt_player_fsd_dialog('AskQuitGame', {}, uiconst.YESNO, uiconst.ID_YES) == uiconst.ID_YES:
    523             self.settings.SaveSettings()
    524             self._AppQuitGame()
    525 
    526     def CmdLogOff(self):
    527         if prompt_player_fsd_dialog('AskLogoffGame', {}, uiconst.YESNO, uiconst.ID_YES) == uiconst.ID_YES:
    528             appUtils.Reboot('Generic Logoff')
    529 
    530     def CmdToggleAudio(self):
    531         settings.public.audio.Set('audioEnabled', not settings.public.audio.Get('audioEnabled', 1))
    532         if settings.public.audio.audioEnabled:
    533             uicore.audioHandler.Activate()
    534         else:
    535             uicore.audioHandler.Deactivate()
    536         return True
    537 
    538     def WinCmdToggleWindowed(self):
    539         uicore.device.ToggleWindowed()
    540         return True
    541 
    542     def CmdCloseAllWindows(self):
    543         for wnd in uicore.registry.GetWindows()[:]:
    544             if not uicore.registry.IsWindow(wnd):
    545                 continue
    546             if wnd.IsKillable():
    547                 if hasattr(wnd, 'CloseByUser'):
    548                     wnd.CloseByUser()
    549                 else:
    550                     try:
    551                         wnd.Close()
    552                     except:
    553                         log.LogException()
    554 
    555             elif not wnd.InStack():
    556                 wnd.Minimize()
    557 
    558         return True
    559 
    560     def CmdMinimizeAllWindows(self):
    561         wnds = uicore.registry.GetValidWindows()
    562         for wnd in wnds:
    563             if wnd.InStack() or wnd.align == uiconst.TOALL:
    564                 continue
    565             uthread.new(wnd.Minimize)
    566 
    567         return True
    568 
    569     def CmdMaximizeAllWindows(self):
    570         for wnd in uicore.registry.GetWindows():
    571             if wnd.InStack():
    572                 continue
    573             uthread.new(wnd.Maximize)
    574 
    575     def CmdToggleMinimizeMaximizeAllWindows(self):
    576         wnds = uicore.registry.GetValidWindows()
    577         if False in [ w.IsMinimized() for w in wnds ]:
    578             self.CmdMinimizeAllWindows()
    579         else:
    580             self.CmdMaximizeAllWindows()
    581 
    582     def CmdMinimizeActiveWindow(self):
    583         activeWnd = uicore.registry.GetActiveStackOrWindow()
    584         if activeWnd:
    585             if activeWnd.align == uiconst.TOALL or not hasattr(activeWnd, 'Minimize'):
    586                 return
    587             activeWnd.Minimize()
    588             return True
    589 
    590     def CmdToggleCollapseAllWindows(self):
    591         uicore.registry.ToggleCollapseAllWindows()
    592 
    593     def CmdCloseActiveWindow(self):
    594         activeWnd = uicore.registry.GetActive()
    595         if not isinstance(activeWnd, Window):
    596             return
    597         if activeWnd and getattr(activeWnd, 'canCloseActiveWnd', 1):
    598             if hasattr(activeWnd, 'CloseByUser'):
    599                 activeWnd.CloseByUser()
    600                 return True
    601             if hasattr(activeWnd, 'Close'):
    602                 activeWnd.Close()
    603                 return True
    604 
    605     def CmdResetMonitor(self):
    606         uicore.device.ResetMonitor()
    607         return True
    608 
    609     def OnUp(self):
    610         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    611         if fa and hasattr(fa, 'OnUp'):
    612             uthread.pool('commandSvc::OnKey OnUp', fa.OnUp)
    613 
    614     def OnDown(self):
    615         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    616         if fa and hasattr(fa, 'OnDown'):
    617             uthread.pool('commandSvc::OnKey OnDown', fa.OnDown)
    618 
    619     def OnLeft(self):
    620         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    621         if fa and hasattr(fa, 'OnLeft'):
    622             uthread.pool('commandSvc::OnKey OnLeft', fa.OnLeft)
    623 
    624     def OnRight(self):
    625         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    626         if fa and hasattr(fa, 'OnRight'):
    627             uthread.pool('commandSvc::OnKey OnRight', fa.OnRight)
    628 
    629     def OnHome(self):
    630         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    631         if fa and hasattr(fa, 'OnHome'):
    632             uthread.pool('commandSvc::OnKey OnHome', fa.OnHome)
    633 
    634     def OnEnd(self):
    635         fa = uicore.registry.GetFocus() or uicore.registry.GetActive()
    636         if fa and hasattr(fa, 'OnEnd'):
    637             uthread.pool('commandSvc::OnKey OnEnd', fa.OnEnd)
    638 
    639     def OnShiftTab(self):
    640         self.OnTab()
    641 
    642     def OnTab(self):
    643         oldfoc = uicore.registry.GetFocus()
    644         if oldfoc is None or oldfoc == uicore.desktop:
    645             uicore.registry.ToggleCollapseAllWindows()
    646         else:
    647             uicore.registry.FindFocus([1, -1][uicore.uilib.Key(uiconst.VK_SHIFT)])
    648 
    649     def CmdBack(self):
    650         activeWnd = uicore.registry.GetActive()
    651         focus = uicore.registry.GetFocus()
    652         if activeWnd and isinstance(activeWnd, Window) and hasattr(activeWnd, 'OnBack'):
    653             activeWnd.OnBack()
    654         elif focus:
    655             while focus.parent:
    656                 if hasattr(focus, 'OnBack'):
    657                     focus.OnBack()
    658                 focus = focus.parent
    659 
    660     def CmdForward(self):
    661         activeWnd = uicore.registry.GetActive()
    662         focus = uicore.registry.GetFocus()
    663         if activeWnd and isinstance(activeWnd, Window) and hasattr(activeWnd, 'OnForward'):
    664             activeWnd.OnForward()
    665         elif focus and hasattr(focus, 'OnForward'):
    666             focus.OnForward()
    667 
    668     def OnReturn(self):
    669         uicore.registry.Confirm()
    670 
    671     def OnCtrlA(self):
    672         focus = uicore.registry.GetFocus()
    673         if focus and hasattr(focus, 'SelectAll'):
    674             focus.SelectAll()
    675             return True
    676         active = uicore.registry.GetActive()
    677         if active and hasattr(active, 'SelectAll'):
    678             active.SelectAll()
    679             return True
    680 
    681     def OnCtrlC(self):
    682         focus = uicore.registry.GetFocus()
    683         if getattr(focus, 'Copy', None):
    684             return focus.Copy()
    685 
    686     def OnCtrlX(self):
    687         focus = uicore.registry.GetFocus()
    688         if getattr(focus, 'Cut', None):
    689             return focus.Cut()
    690 
    691     def OnCtrlV(self):
    692         text = GetClipboardData()
    693         if not text:
    694             return False
    695         focus = uicore.registry.GetFocus()
    696         if focus and hasattr(focus, 'Paste'):
    697             focus.Paste(text)
    698             return True
    699 
    700     def OnCtrlTab(self):
    701         w = self.GetWndMenu()
    702         if w:
    703             w.Next()
    704             return True
    705 
    706     def OnCtrlShiftTab(self):
    707         w = self.GetWndMenu()
    708         if w:
    709             w.Prev()
    710             return True
    711 
    712     def GetWndMenu(self):
    713         pass
    714 
    715     def _CheckWndMenu(self, *args):
    716         ctrl = uicore.uilib.Key(uiconst.VK_CONTROL)
    717         if not ctrl:
    718             self.wmTimer = None
    719         chooseWndMenu = getattr(self, 'chooseWndMenu', None)
    720         if chooseWndMenu and not chooseWndMenu.destroyed and chooseWndMenu.state != uiconst.UI_HIDDEN:
    721             chooseWndMenu.ChooseHilited()
    722         self.chooseWndMenu = None
    723 
    724     def OnEsc(self, stopLoading = True):
    725         if CloseContextMenus():
    726             return 1
    727         modalResult = uicore.registry.GetModalResult(uiconst.ID_CANCEL, 'btn_cancel')
    728         if modalResult is not None:
    729             uicore.registry.GetModalWindow().SetModalResult(modalResult)
    730             return True
    731         if stopLoading and uicore.layer.loading.state == uiconst.UI_NORMAL:
    732             uthread.new(sm.GetService('loading').HideAllLoad)
    733             return True
    734         sys = uicore.layer.systemmenu
    735         if sys:
    736             if sys.isopen:
    737                 uthread.new(sys.CloseMenu)
    738             else:
    739                 uthread.new(sys.OpenView)
    740             return True
    741 
    742     OnEsc_Core = OnEsc
    743 
    744     def _BuildScreenshotName(self, fileName = None):
    745         year, month, weekday, day, hour, minute, second, msec = blue.os.GetTimeParts(blue.os.GetWallclockTime())
    746         date = '%d.%.2d.%.2d.%.2d.%.2d.%.2d' % (year,
    747          month,
    748          day,
    749          hour,
    750          minute,
    751          second)
    752         return u'{fileName}{separation}{date}.{extension}'.format(fileName=fileName or '', separation='_' if fileName else '', date=date, extension='png')
    753 
    754     def _GetDefaultScreenshotsDirectory(self):
    755         return u'{documentsPath}/{applicationName}/capture/Screenshots'.format(documentsPath=blue.sysinfo.GetUserDocumentsDirectory(), applicationName=boot.appname)
    756 
    757     def PrintScreen(self, directory = None, fileName = None):
    758         path = u'{directory}/{fileName}'.format(directory=directory or self._GetDefaultScreenshotsDirectory(), fileName=self._BuildScreenshotName(fileName))
    759         rt = trinity.device.GetRenderContext().GetDefaultBackBuffer()
    760         if not rt.isReadable:
    761             readable = trinity.Tr2RenderTarget(rt.width, rt.height, 1, rt.format)
    762             rt.Resolve(readable)
    763             bmp = trinity.Tr2HostBitmap(readable)
    764         else:
    765             bmp = trinity.Tr2HostBitmap(rt)
    766         if bmp.format == trinity.PIXEL_FORMAT.B8G8R8A8_UNORM:
    767             bmp.ChangeFormat(trinity.PIXEL_FORMAT.B8G8R8X8_UNORM)
    768         bmp.Save(path)
    769         return True
    770 
    771     def OpenMonitor(self, *args):
    772         EngineToolsLauncher.Open()
    773 
    774     def GetStringFromShortcutKeys(self, shortcut):
    775         retString = ''
    776         for key in shortcut:
    777             if key:
    778                 newKey = GetKeyName(key)
    779                 retString += '%s-' % newKey
    780 
    781         retString = retString[:-1]
    782         retString = localization.uiutil.PrepareLocalizationSafeString(retString, messageID='commandShortcut')
    783         try:
    784             retString.decode('cp1252')
    785         except UnicodeDecodeError:
    786             retString = '???'
    787 
    788         return retString