Changeset 2498

Show
Ignore:
Timestamp:
11/13/08 05:49:59 (8 weeks ago)
Author:
bzr
Message:

The default appModule is no longer a separate level, rather all all other appModules inherit from default. Advantages of this are:
*Scripts and events do not have to go through so many levels.
*appModules can override or extend scripts in the default appModule with out having to provide their own kbd files if they do not have any custom bindings.

Also:
*kbd files are only loaded for actual appModules and their super classes, rather than just by the application name. This means that it is now impossible to for instance have a notepad_desktop.kbd but no notepad appModule.
*kbd files are loaded over the top of each other. For instance if you had a thunderbird appModule which inherited from a gecko appModule which inherited from the default appModule, bindings from all three kbd files would be loaded (if they existed), in reverse order (default, gecko, thunderbird).
*Fixed a memory leak caused by bindKey_runtime.

Location:
trunk
Files:
22 modified

Legend:

Unmodified
Added
Removed
  • trunk

    • Property bzr:revision-info
      •  

        old new  
        1 timestamp: 2008-11-12 16:22:44.319999933 +0100 
        2 committer: Peter Vágner <peter.v@datagate.sk> 
         1timestamp: 2008-11-13 16:40:49.467999935 +1100 
         2committer: Michael Curran <mick@kulgan.net> 
        33properties:  
        4         branch-nick: main 
         4        branch-nick: default 
    • Property bzr:revision-id:v3-list-QlpoOTFBWSZTWbrL2vUAAB1VgAAQABCAQDrrnqAgAFCgaaGRkxBoTIJ6mmaNRwhndFAoNhZjh_YY4a01fOg1ulgNNC2UrzPdXXEnDpX8XckU4UJC6y9r1A..
      •  

        old new  
        2672672295 jamie@jantrid.net-20081112030302-5v0cz8up9xybol1i 
        2682682296 peter.v@datagate.sk-20081112152244-yxpiodwvl042ktaf 
         2692297 mick@kulgan.net-20081113054049-kmiq89owi6y0b0bv 
    • Property bzr:file-ids
      •  

        old new  
        1 source/locale/cs/LC_MESSAGES/nvda.po    792@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2Flocale%2Fcs%2FLC_MESSAGES%2Fnvda.po 
         1source/appModuleHandler.py      97@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModuleHandler.py 
         2source/appModules/_default.py   92@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2F_default.py 
         3source/appModules/audacity.py   1216@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Faudacity.py 
         4source/appModules/calc.py       363@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fcalc.py 
         5source/appModules/dosvox.py     2397@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fdosvox.py 
         6source/appModules/firefox.py    firefox.py-20080409115008-7r27cnprsh8y66ow-1 
         7source/appModules/miranda32.py  1236@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fmiranda32.py 
         8source/appModules/mplayerc.py   1633@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fmplayerc.py 
         9source/appModules/msimn.py      354@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fmsimn.py 
         10source/appModules/msnmsgr.py    564@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fmsnmsgr.py 
         11source/appModules/nvda.py       nvda.py-20080306082146-2y8yib3dfdftv11a-1 
         12source/appModules/outlook.py    1063@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Foutlook.py 
         13source/appModules/skype.py      1329@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fskype.py 
         14source/appModules/soffice.py    981@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fsoffice.py 
         15source/appModules/thunderbird.py        thunderbird.py-20080516033845-htxz6c2wvmpmtnfi-1 
         16source/appModules/totalcmd.py   2026@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Ftotalcmd.py 
         17source/appModules/winamp.py     1059@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FappModules%2Fwinamp.py 
         18source/baseObject.py    378@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FbaseObject.py 
         19source/eventHandler.py  378@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FeventHandler.py 
         20source/gui/settingsDialogs.py   299@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2Fgui%2FsettingsDialogs.py 
         21source/scriptHandler.py 362@dbe06fc7-9119-0410-a01d-9dbf589ecbba:trunk:source%2FscriptHandler.py 
  • trunk/source/appModuleHandler.py

    r2416 r2498  
    1414""" 
    1515 
     16import itertools 
    1617import re 
    1718import ctypes 
     
    3233#Dictionary of processID:appModule paires used to hold the currently running modules 
    3334runningTable={} 
    34 #Variable to hold the active (focused) appModule 
    35 activeModule=None 
    36 #variable to hold the default appModule instance 
    37 default=None 
    3835#: The process ID of NVDA itself. 
    3936NVDAProcessID=None 
     
    111108                return None 
    112109 
    113 def getActiveModule(): 
    114         """Finds the appModule that is for the current foreground window. 
    115         @returns: the active appModule 
    116         @rtype: appModule 
    117         """ 
    118         fg=winUser.getForegroundWindow() 
    119         mod=getAppModuleFromWindow(fg) 
    120         if log.isEnabledFor(log.DEBUG): 
    121                 log.debug("Using window %s (%s), got appModule %s"%(fg,winUser.getClassName(fg),mod)) 
    122         return mod 
    123  
    124110def getAppModuleForNVDAObject(obj): 
    125111        if not isinstance(obj,NVDAObjects.window.Window): 
     
    137123        if not mod: 
    138124                appName=getAppNameFromProcessID(processID) 
    139                 modClass=fetchAppModuleClass(appName) 
    140                 if modClass:  
    141                         mod=modClass(processID,appName=appName) 
    142                         if modClass!=AppModule: 
    143                                 log.info("Loaded appModule %s"%(mod.appName)) 
    144                         loadKeyMap(mod.appName,mod) 
     125                mod=fetchAppModule(processID,appName) 
     126                if not mod: 
     127                        mod=fetchAppModule(processID,appName,useDefault=True) 
     128                if not mod: 
     129                        raise RuntimeError("error fetching default appModule") 
    145130                runningTable[processID]=mod 
    146131        return mod 
     
    159144                getAppModuleFromProcessID(processID) 
    160145 
    161 def loadKeyMap(appName,mod): 
    162         """Loads a key map in to the given appModule, with the given name. if the key map exists. It takes in to account what layout NVDA is currently set to. 
    163         @param appName: the application name 
    164         @type appName: str 
    165         @param mod: the appModule 
    166         @type mod: appModule 
    167         """   
    168         layout=config.conf["keyboard"]["keyboardLayout"] 
    169         keyMapFileName=getKeyMapFileName(appName,layout) 
    170         if not keyMapFileName: 
    171                 return False 
    172         keyMapFile=open(keyMapFileName,'r') 
    173         bindCount=0 
    174         #If the appModule already has a running keyMap, clear it 
    175         if '_keyMap' in mod.__dict__: 
    176                 mod._keyMap={} 
    177         for line in (x for x in keyMapFile if not x.startswith('#') and not x.isspace()): 
    178                 m=re_keyScript.match(line) 
    179                 if m: 
    180                         try: 
    181                                 mod.bindKey_runtime(m.group('key'),m.group('script')) 
    182                                 bindCount+=1 
    183                         except: 
    184                                 log.error("error binding %s to %s in module %s"%(m.group('script'),m.group('key'),appName)) 
    185         log.debug("added %s bindings to module %s from file %s"%(bindCount,appName,keyMapFileName)) 
    186         return True 
    187  
    188 def fetchAppModuleClass(appName): 
     146def fetchAppModule(processID,appName,useDefault=False): 
    189147        """Returns an appModule found in the appModules directory, for the given application name. 
    190         It only returns the class, it must be initialized with a name and a window to actually be used. 
     148        @param processID: process ID for it to be associated with 
     149        @type processID: integer 
    191150        @param appName: the application name for which an appModule should be found. 
    192151        @type appName: str 
     
    195154        """   
    196155        mod=None 
     156        friendlyAppName=appName 
     157        if useDefault: 
     158                appName='_default' 
    197159        if moduleExists(appName): 
    198160                try: 
    199                         mod=__import__(appName,globals(),locals(),[]).AppModule 
     161                        mod=__import__(appName,globals(),locals(),[]).AppModule(processID,friendlyAppName) 
    200162                except: 
    201                         log.error("Error in appModule %s"%appName,exc_info=True) 
     163                        log.error("error in appModule %s"%appName,exc_info=True) 
    202164                        speech.speakMessage(_("Error in appModule %s")%appName) 
    203                         raise RuntimeError 
    204         if mod is None: 
    205                 return AppModule 
    206         return mod 
     165        if mod and isinstance(mod,AppModule): 
     166                mod.loadKeyMap() 
     167                return mod 
     168 
    207169 
    208170def initialize(): 
     
    211173        global NVDAProcessID,default 
    212174        NVDAProcessID=os.getpid() 
    213         defaultModClass=fetchAppModuleClass('_default') 
    214         if defaultModClass: 
    215                 default=defaultModClass('_default',winUser.getDesktopWindow()) 
    216         if default: 
    217                 if loadKeyMap('_default',default): 
    218                         log.info("loaded default appModule") 
    219                 else: 
    220                         speech.speakMessage(_("Could not load default module keyMap")) 
    221                         raise RuntimeError("appModuleHandler.initialize: could not load default module keymap") 
    222         else: 
    223                 speech.speakMessage(_("Could not load default module ")) 
    224                 raise RuntimeError("appModuleHandler.initialize: could not load default module ") 
    225175 
    226176#base class for appModules 
     
    241191 
    242192        def __repr__(self): 
    243                 return "AppModule (appName %s, process ID %s) at address %x"%(self.appName,self.processID,id(self)) 
     193                return "<%s (appName %s, process ID %s) at address %x>"%(self.appModuleName,self.appName,self.processID,id(self)) 
     194 
     195        def _get_appModuleName(self): 
     196                return "%s.%s"%(self.__class__.__module__.split('.')[-1],self.__class__.__name__) 
    244197 
    245198        def _get_isAlive(self): 
     
    248201        def __del__(self): 
    249202                winKernel.closeHandle(self.processHandle) 
     203 
     204        def loadKeyMap(self): 
     205                """Loads a key map in to this appModule . if the key map exists. It takes in to account what layout NVDA is currently set to. 
     206                """   
     207                if '_keyMap' in self.__dict__: 
     208                        self._keyMap={} 
     209                layout=config.conf["keyboard"]["keyboardLayout"] 
     210                for modClass in reversed(list(itertools.takewhile(lambda x: issubclass(x,AppModule) and x is not AppModule,self.__class__.__mro__))): 
     211                        name=modClass.__module__.split('.')[-1] 
     212                        keyMapFileName=getKeyMapFileName(name,layout) 
     213                        if not keyMapFileName: 
     214                                continue 
     215                        keyMapFile=open(keyMapFileName,'r') 
     216                        bindCount=0 
     217                        #If the appModule already has a running keyMap, clear it 
     218                        for line in (x for x in keyMapFile if not x.startswith('#') and not x.isspace()): 
     219                                m=re_keyScript.match(line) 
     220                                if m: 
     221                                        try: 
     222                                                self.bindKey_runtime(m.group('key'),m.group('script')) 
     223                                                bindCount+=1 
     224                                        except: 
     225                                                log.error("error binding %s to %s in appModule %s"%(m.group('script'),m.group('key'),self)) 
     226                        log.debug("added %s bindings to appModule %s from file %s"%(bindCount,self,keyMapFileName)) 
  • trunk/source/appModules/_default.py

    r2494 r2498  
    761761                mod=focus.appModule 
    762762                if isinstance(mod,appModuleHandler.AppModule) and type(mod)!=appModuleHandler.AppModule: 
    763                         speech.speakMessage(_("and currently loaded module is %s") % mod.appName) 
     763                        speech.speakMessage(_("and currently loaded module is %s") % mod.appModuleName) 
    764764        script_speakApplicationName.__doc__ = _("Speaks filename of the active application along with name of the currently loaded appmodule") 
    765765 
  • trunk/source/appModules/audacity.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import winUser 
    99import controlTypes 
    1010from NVDAObjects.IAccessible import edit 
    1111 
    12 class AppModule(appModuleHandler.AppModule): 
     12class AppModule(_default.AppModule): 
    1313 
    1414        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/calc.py

    r2413 r2498  
    1 import appModuleHandler 
     1import _default 
    22import speech 
    33 
    4 class AppModule(appModuleHandler.AppModule): 
     4class AppModule(_default.AppModule): 
    55 
    66        def __init__(self,*args,**kwargs): 
  • trunk/source/appModules/dosvox.py

    r2410 r2498  
    1 import appModuleHandler 
     1import _default 
    22import speech 
    33 
    4 class AppModule(appModuleHandler.AppModule): 
     4class AppModule(_default.AppModule): 
    55 
    66        def event_appGainFocus(self): 
  • trunk/source/appModules/firefox.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import controlTypes 
    99import api 
     
    1111import winUser 
    1212 
    13 class AppModule(appModuleHandler.AppModule): 
     13class AppModule(_default.AppModule): 
    1414 
    1515        def event_stateChange(self, obj, nextHandler): 
  • trunk/source/appModules/miranda32.py

    r2490 r2498  
    1010import winUser 
    1111from NVDAObjects.IAccessible import IAccessible, PropertyPage 
    12 import appModuleHandler 
     12import _default 
    1313import speech 
    1414import controlTypes 
     
    7272ANSILOGS=(1001,1006) 
    7373 
    74 class AppModule(appModuleHandler.AppModule): 
     74class AppModule(_default.AppModule): 
    7575 
    7676        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/mplayerc.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import controlTypes 
    99 
    10 class AppModule(appModuleHandler.AppModule): 
     10class AppModule(_default.AppModule): 
    1111 
    1212        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/msimn.py

    r2410 r2498  
    1111import eventHandler 
    1212import IAccessibleHandler 
    13 import appModuleHandler 
     13import _default 
    1414import speech 
    1515from keyUtils import key, sendKey 
     
    3333} 
    3434 
    35 class AppModule(appModuleHandler.AppModule): 
     35class AppModule(_default.AppModule): 
    3636 
    3737        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/msnmsgr.py

    r2410 r2498  
    1111import controlTypes 
    1212import textHandler 
    13 import appModuleHandler 
     13import _default 
    1414import speech 
    1515import cursorManager 
     
    3232]) 
    3333 
    34 class AppModule(appModuleHandler.AppModule): 
     34class AppModule(_default.AppModule): 
    3535 
    3636        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/nvda.py

    r2410 r2498  
    1 import appModuleHandler 
     1import _default 
    22import controlTypes 
    33import gui 
    44 
    5 class AppModule(appModuleHandler.AppModule): 
     5class AppModule(_default.AppModule): 
    66 
    77        def event_NVDAObject_init(self, obj): 
  • trunk/source/appModules/outlook.py

    r2410 r2498  
    77import time 
    88import win32com.client 
    9 import appModuleHandler 
     9import _default 
    1010import api 
    1111import eventHandler 
     
    4545        return ", ".join(nameList) 
    4646 
    47 class AppModule(appModuleHandler.AppModule): 
     47class AppModule(_default.AppModule): 
    4848 
    4949        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/skype.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import controlTypes 
    99import winUser 
    1010 
    11 class AppModule(appModuleHandler.AppModule): 
     11class AppModule(_default.AppModule): 
    1212 
    1313        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/soffice.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import controlTypes 
    99import speech 
     
    1212inDocument=False 
    1313 
    14 class AppModule(appModuleHandler.AppModule): 
     14class AppModule(_default.AppModule): 
    1515 
    1616        def event_gainFocus(self,obj,nextHandler): 
  • trunk/source/appModules/thunderbird.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88import controlTypes 
    99import api 
     
    1111import winUser 
    1212 
    13 class AppModule(appModuleHandler.AppModule): 
     13class AppModule(_default.AppModule): 
    1414 
    1515        def event_gainFocus(self, obj, nextHandler): 
  • trunk/source/appModules/totalcmd.py

    r2410 r2498  
    55#See the file COPYING for more details. 
    66 
    7 import appModuleHandler 
     7import _default 
    88from NVDAObjects.IAccessible import IAccessible 
    99import speech 
     
    1212oldActivePannel=0 
    1313 
    14 class AppModule(appModuleHandler.AppModule): 
     14class AppModule(_default.AppModule): 
    1515 
    1616        def event_NVDAObject_init(self,obj): 
  • trunk/source/appModules/winamp.py

    r2410 r2498  
    1212from scriptHandler import isScriptWaiting 
    1313from NVDAObjects.IAccessible import IAccessible  
    14 import appModuleHandler 
     14import _default 
    1515import speech 
    1616import locale 
     
    5252        return winUser.sendMessage(hwndWinamp,WM_WA_IPC,0,IPC_GET_REPEAT) 
    5353 
    54 class AppModule(appModuleHandler.AppModule): 
     54class AppModule(_default.AppModule): 
    5555 
    5656        def event_NVDAObject_init(self,obj): 
  • trunk/source/baseObject.py

    r1926 r2498  
    6363""" 
    6464                scriptName="script_%s"%scriptName 
    65                 func=getattr(self,scriptName,None) 
     65                func=getattr(self.__class__,scriptName,None) 
    6666                if func: 
    6767                                self.bindKeyToFunc_runtime(keyName,func) 
  • trunk/source/eventHandler.py

    r2468 r2498  
    122122        appModule=obj.appModule 
    123123        if hasattr(appModule,"event_%s"%name): 
    124                 getattr(appModule,"event_%s"%name)(obj,lambda: executeEvent_defaultAppModuleLevel(name,obj,**kwargs),**kwargs)  
    125         else: 
    126                 executeEvent_defaultAppModuleLevel(name,obj,**kwargs) 
    127  
    128 def executeEvent_defaultAppModuleLevel(name,obj,**kwargs): 
    129         default=appModuleHandler.default 
    130         if hasattr(default,"event_%s"%name): 
    131                 getattr(default,"event_%s"%name)(obj,lambda: executeEvent_virtualBufferLevel(name,obj,**kwargs),**kwargs)  
     124                getattr(appModule,"event_%s"%name)(obj,lambda: executeEvent_virtualBufferLevel(name,obj,**kwargs),**kwargs) 
    132125        else: 
    133126                executeEvent_virtualBufferLevel(name,obj,**kwargs) 
  • trunk/source/gui/settingsDialogs.py

    r2482 r2498  
    411411                        config.conf['keyboard']['keyboardLayout']=layout 
    412412                        for m in appModuleHandler.runningTable.values(): 
    413                                 if m.__class__==appModuleHandler.AppModule: 
    414                                         continue 
    415                                 appModuleHandler.loadKeyMap(m.appName,m) 
    416                 appModuleHandler.loadKeyMap(appModuleHandler.default.appName,appModuleHandler.default) 
     413                                m.loadKeyMap() 
    417414                config.conf["keyboard"]["useCapsLockAsNVDAModifierKey"]=self.capsAsNVDAModifierCheckBox.IsChecked() 
    418415                config.conf["keyboard"]["useNumpadInsertAsNVDAModifierKey"]=self.numpadInsertAsNVDAModifierCheckBox.IsChecked() 
  • trunk/source/scriptHandler.py

    r2468 r2498  
    2929        appModule=focusObject.appModule 
    3030        func=appModule.getScript(keyPress) if appModule else None 
    31         if func: 
    32                 return func 
    33         return findScript_defaultAppModuleLevel(keyPress) 
    34  
    35 def findScript_defaultAppModuleLevel(keyPress): 
    36         default=appModuleHandler.default 
    37         func=default.getScript(keyPress) 
    3831        if func: 
    3932                return func