Module globalCommands
[hide private]
[frames] | no frames]

Source Code for Module globalCommands

#globalCommands.py
#A part of NonVisual Desktop Access (NVDA)
#This file is covered by the GNU General Public License.
#See the file COPYING for more details.
#Copyright (C) 2006-2010 Michael Curran , James Teh , Peter Vágner , Aleksey Sadovoy , Rui Batista

import time
import tones
import keyboardHandler
import mouseHandler
import eventHandler
import controlTypes
import api
import textInfos
import speech
import sayAllHandler
from NVDAObjects import NVDAObject, NVDAObjectTextInfo
import globalVars
from logHandler import log
from synthDriverHandler import *
import gui
import wx
import config
import winUser
import appModuleHandler
import winKernel
from gui import mainFrame
import treeInterceptorHandler
import scriptHandler
import ui
import braille
import inputCore
import virtualBuffers
import characterProcessing
from baseObject import ScriptableObject

class GlobalCommands(ScriptableObject):
        """Commands that are available at all times, regardless of the current focus.
        """

        def script_toggleInputHelp(self,gesture):
                inputCore.manager.isInputHelpActive = not inputCore.manager.isInputHelpActive
                state = _("on") if inputCore.manager.isInputHelpActive else _("off")
                ui.message(_("input help %s")%state)
        script_toggleInputHelp.__doc__=_("Turns input help on or off. When on, any input such as pressing a key on the keyboard will tell you what script is associated with that input, if any.")

        def script_toggleCurrentAppSleepMode(self,gesture):
                curFocus=api.getFocusObject()
                curApp=curFocus.appModule
                if curApp.sleepMode:
                        curApp.sleepMode=False
                        ui.message(_("Sleep mode off"))
                        eventHandler.executeEvent("gainFocus",curFocus)
                else:
                        eventHandler.executeEvent("loseFocus",curFocus)
                        curApp.sleepMode=True
                        ui.message(_("Sleep mode on"))
        script_toggleCurrentAppSleepMode.__doc__=_("Toggles  sleep mode on and off for  the active application.")
        script_toggleCurrentAppSleepMode.allowInSleepMode=True

        def script_reportCurrentLine(self,gesture):
                obj=api.getFocusObject()
                treeInterceptor=obj.treeInterceptor
                if hasattr(treeInterceptor,'TextInfo') and not treeInterceptor.passThrough:
                        obj=treeInterceptor
                try:
                        info=obj.makeTextInfo(textInfos.POSITION_CARET)
                except (NotImplementedError, RuntimeError):
                        info=obj.makeTextInfo(textInfos.POSITION_FIRST)
                info.expand(textInfos.UNIT_LINE)
                if scriptHandler.getLastScriptRepeatCount()==0:
                        speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
                else:
                        speech.speakSpelling(info.text)
        script_reportCurrentLine.__doc__=_("Reports the current line under the application cursor. Pressing this key twice will spell the current line")

        def script_leftMouseClick(self,gesture):
                ui.message(_("left click"))
                winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN,0,0,None,None)
                winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP,0,0,None,None)
        script_leftMouseClick.__doc__=_("Clicks the left mouse button once at the current mouse position")

        def script_rightMouseClick(self,gesture):
                ui.message(_("right click"))
                winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTDOWN,0,0,None,None)
                winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTUP,0,0,None,None)
        script_rightMouseClick.__doc__=_("Clicks the right mouse button once at the current mouse position")

        def script_toggleLeftMouseButton(self,gesture):
                if winUser.getKeyState(winUser.VK_LBUTTON)&32768:
                        ui.message(_("left mouse button unlock"))
                        winUser.mouse_event(winUser.MOUSEEVENTF_LEFTUP,0,0,None,None)
                else:
                        ui.message(_("left mouse button lock"))
                        winUser.mouse_event(winUser.MOUSEEVENTF_LEFTDOWN,0,0,None,None)
        script_toggleLeftMouseButton.__doc__=_("Locks or unlocks the left mouse button")

        def script_toggleRightMouseButton(self,gesture):
                if winUser.getKeyState(winUser.VK_RBUTTON)&32768:
                        ui.message(_("right mouse button unlock"))
                        winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTUP,0,0,None,None)
                else:
                        ui.message(_("right mouse button lock"))
                        winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTDOWN,0,0,None,None)
        script_toggleRightMouseButton.__doc__=_("Locks or unlocks the right mouse button")

        def script_reportCurrentSelection(self,gesture):
                obj=api.getFocusObject()
                treeInterceptor=obj.treeInterceptor
                if hasattr(treeInterceptor,'TextInfo') and not treeInterceptor.passThrough:
                        obj=treeInterceptor
                try:
                        info=obj.makeTextInfo(textInfos.POSITION_SELECTION)
                except (RuntimeError, NotImplementedError):
                        info=None
                if not info or info.isCollapsed:
                        speech.speakMessage(_("no selection"))
                else:
                        speech.speakMessage(_("selected %s")%info.text)
        script_reportCurrentSelection.__doc__=_("Announces the current selection in edit controls and documents. If there is no selection it says so.")

        def script_dateTime(self,gesture):
                if scriptHandler.getLastScriptRepeatCount()==0:
                        text=winKernel.GetTimeFormat(winKernel.LOCALE_USER_DEFAULT, winKernel.TIME_NOSECONDS, None, None)
                else:
                        text=winKernel.GetDateFormat(winKernel.LOCALE_USER_DEFAULT, winKernel.DATE_LONGDATE, None, None)
                ui.message(text)
        script_dateTime.__doc__=_("If pressed once, reports the current time. If pressed twice, reports the current date")

        def script_increaseSynthSetting(self,gesture):
                settingName=globalVars.settingsRing.currentSettingName
                if not settingName:
                        ui.message(_("No settings"))
                        return
                settingValue=globalVars.settingsRing.increase()
                ui.message("%s %s" % (settingName,settingValue))
        script_increaseSynthSetting.__doc__=_("Increases the currently active setting in the synth settings ring")

        def script_decreaseSynthSetting(self,gesture):
                settingName=globalVars.settingsRing.currentSettingName
                if not settingName:
                        ui.message(_("No settings"))
                        return
                settingValue=globalVars.settingsRing.decrease()
                ui.message("%s %s" % (settingName,settingValue))
        script_decreaseSynthSetting.__doc__=_("Decreases the currently active setting in the synth settings ring")

        def script_nextSynthSetting(self,gesture):
                nextSettingName=globalVars.settingsRing.next()
                if not nextSettingName:
                        ui.message(_("No settings"))
                        return
                nextSettingValue=globalVars.settingsRing.currentSettingValue
                ui.message("%s %s"%(nextSettingName,nextSettingValue))
        script_nextSynthSetting.__doc__=_("Moves to the next available setting in the synth settings ring")

        def script_previousSynthSetting(self,gesture):
                previousSettingName=globalVars.settingsRing.previous()
                if not previousSettingName:
                        ui.message(_("No settings"))
                        return
                previousSettingValue=globalVars.settingsRing.currentSettingValue
                ui.message("%s %s"%(previousSettingName,previousSettingValue))
        script_previousSynthSetting.__doc__=_("Moves to the previous available setting in the synth settings ring")

        def script_toggleSpeakTypedCharacters(self,gesture):
                if config.conf["keyboard"]["speakTypedCharacters"]:
                        onOff=_("off")
                        config.conf["keyboard"]["speakTypedCharacters"]=False
                else:
                        onOff=_("on")
                        config.conf["keyboard"]["speakTypedCharacters"]=True
                ui.message(_("speak typed characters")+" "+onOff)
        script_toggleSpeakTypedCharacters.__doc__=_("Toggles on and off the speaking of typed characters")

        def script_toggleSpeakTypedWords(self,gesture):
                if config.conf["keyboard"]["speakTypedWords"]:
                        onOff=_("off")
                        config.conf["keyboard"]["speakTypedWords"]=False
                else:
                        onOff=_("on")
                        config.conf["keyboard"]["speakTypedWords"]=True
                ui.message(_("speak typed words")+" "+onOff)
        script_toggleSpeakTypedWords.__doc__=_("Toggles on and off the speaking of typed words")

        def script_toggleSpeakCommandKeys(self,gesture):
                if config.conf["keyboard"]["speakCommandKeys"]:
                        onOff=_("off")
                        config.conf["keyboard"]["speakCommandKeys"]=False
                else:
                        onOff=_("on")
                        config.conf["keyboard"]["speakCommandKeys"]=True
                ui.message(_("speak command keys")+" "+onOff)
        script_toggleSpeakCommandKeys.__doc__=_("Toggles on and off the speaking of typed keys, that are not specifically characters")

        def script_cycleSpeechSymbolLevel(self,gesture):
                curLevel = config.conf["speech"]["symbolLevel"]
                for level in characterProcessing.CONFIGURABLE_SPEECH_SYMBOL_LEVELS:
                        if level > curLevel:
                                break
                else:
                        level = characterProcessing.SYMLVL_NONE
                name = characterProcessing.SPEECH_SYMBOL_LEVEL_LABELS[level]
                config.conf["speech"]["symbolLevel"] = level
                ui.message(_("symbol level %s") % name)
        script_cycleSpeechSymbolLevel.__doc__=_("Cycles through speech symbol levels which determine what symbols are spoken")

        def script_moveMouseToNavigatorObject(self,gesture):
                obj=api.getNavigatorObject() 
                try:
                        p=api.getReviewPosition().pointAtStart
                except (NotImplementedError, LookupError):
                        p=None
                if p:
                        x=p.x
                        y=p.y
                else:
                        try:
                                (left,top,width,height)=obj.location
                        except:
                                ui.message(_("object has no location"))
                                return
                        x=left+(width/2)
                        y=top+(height/2)
                winUser.setCursorPos(x,y)
                mouseHandler.executeMouseMoveEvent(x,y)
        script_moveMouseToNavigatorObject.__doc__=_("Moves the mouse pointer to the current navigator object")

        def script_moveNavigatorObjectToMouse(self,gesture):
                ui.message(_("Move navigator object to mouse"))
                obj=api.getMouseObject()
                api.setNavigatorObject(obj)
                speech.speakObject(obj)
        script_moveNavigatorObjectToMouse.__doc__=_("Sets the navigator object to the current object under the mouse pointer and speaks it")

        def script_navigatorObject_moveToFlatReviewAtObjectPosition(self,gesture):
                obj=api.getNavigatorObject()
                pos=obj.flatReviewPosition
                if pos:
                        api.setReviewPosition(pos)
                        pos=pos.copy()
                        obj=api.getNavigatorObject()
                        speech.speakObjectProperties(obj,name=True,role=True)
                        pos.expand(textInfos.UNIT_LINE)
                        speech.speakTextInfo(pos)
                else:
                        speech.speakMessage(_("No flat review for this object"))
        script_navigatorObject_moveToFlatReviewAtObjectPosition.__doc__=_("Moves to flat review for the screen (or document if currently inside one) and positions the review cursor at the location of the current object")

        def script_navigatorObject_moveToObjectAtFlatReviewPosition(self,gesture):
                pos=api.getReviewPosition()
                try:
                        obj=pos.NVDAObjectAtStart
                except NotImplementedError:
                        obj=None
                if obj and obj!=pos.obj:
                        api.setNavigatorObject(obj)
                        speech.speakObject(obj)
                else:
                        speech.speakMessage(_("No object at flat review position"))
        script_navigatorObject_moveToObjectAtFlatReviewPosition.__doc__=_("Moves to the object represented by the text at the position of the review cursor within flat review")

        def script_navigatorObject_current(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                if scriptHandler.getLastScriptRepeatCount()>=1:
                        if curObject.TextInfo!=NVDAObjectTextInfo:
                                textList=[]
                                if curObject.name and isinstance(curObject.name, basestring) and not curObject.name.isspace():
                                        textList.append(curObject.name)
                                try:
                                        info=curObject.makeTextInfo(textInfos.POSITION_SELECTION)
                                        if not info.isCollapsed:
                                                textList.append(info.text)
                                        else:
                                                info.expand(textInfos.UNIT_LINE)
                                                if not info.isCollapsed:
                                                        textList.append(info.text)
                                except (RuntimeError, NotImplementedError):
                                        # No caret or selection on this object.
                                        pass
                        else:
                                textList=[prop for prop in (curObject.name, curObject.value) if prop and isinstance(prop, basestring) and not prop.isspace()]
                        text=" ".join(textList)
                        if len(text)>0 and not text.isspace():
                                if scriptHandler.getLastScriptRepeatCount()==1:
                                        speech.speakSpelling(text)
                                else:
                                        if api.copyToClip(text):
                                                speech.speakMessage(_("%s copied to clipboard")%text)
                else:
                        speech.speakObject(curObject,reason=speech.REASON_QUERY)
        script_navigatorObject_current.__doc__=_("Reports the current navigator object. Pressing twice spells this information,and pressing three times Copies name and value of this  object to the clipboard")

        def script_navigatorObject_currentDimensions(self,gesture):
                obj=api.getNavigatorObject()
                if not obj:
                        ui.message(_("no navigator object"))
                location=obj.location
                if not location:
                        ui.message(_("No location information for navigator object"))
                (left,top,width,height)=location
                deskLocation=api.getDesktopObject().location
                if not deskLocation:
                        ui.message(_("No location information for screen"))
                (deskLeft,deskTop,deskWidth,deskHeight)=deskLocation
                percentFromLeft=(float(left-deskLeft)/deskWidth)*100
                percentFromTop=(float(top-deskTop)/deskHeight)*100
                percentWidth=(float(width)/deskWidth)*100
                percentHeight=(float(height)/deskHeight)*100
                ui.message(_("Object edges positioned %.1f per cent from left edge of screen, %.1f per cent from top edge of screen, width is %.1f per cent of screen, height is %.1f per cent of screen")%(percentFromLeft,percentFromTop,percentWidth,percentHeight))
        script_navigatorObject_currentDimensions.__doc__=_("Reports the hight, width and position of the current navigator object")

        def script_navigatorObject_toFocus(self,gesture):
                obj=api.getFocusObject()
                try:
                        pos=obj.makeTextInfo(textInfos.POSITION_CARET)
                except (NotImplementedError,RuntimeError):
                        pos=obj.makeTextInfo(textInfos.POSITION_FIRST)
                api.setReviewPosition(pos)
                speech.speakMessage(_("move to focus"))
                speech.speakObject(obj,reason=speech.REASON_QUERY)
        script_navigatorObject_toFocus.__doc__=_("Sets the navigator object to the current focus, and the review cursor to the position of the caret inside it, if possible.")

        def script_navigatorObject_moveFocus(self,gesture):
                obj=api.getNavigatorObject()
                if not isinstance(obj,NVDAObject):
                        speech.speakMessage(_("no focus"))
                if scriptHandler.getLastScriptRepeatCount()==0:
                        ui.message(_("move focus"))
                        obj.setFocus()
                else:
                        review=api.getReviewPosition()
                        try:
                                review.updateCaret()
                        except NotImplementedError:
                                ui.message(_("no caret"))
                                return
                        info=review.copy()
                        info.expand(textInfos.UNIT_LINE)
                        speech.speakTextInfo(info,reason=speech.REASON_CARET)
        script_navigatorObject_moveFocus.__doc__=_("Pressed once Sets the keyboard focus to the navigator object, pressed twice sets the system caret to the position of the review cursor")

        def script_navigatorObject_parent(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                simpleReviewMode=config.conf["reviewCursor"]["simpleReviewMode"]
                curObject=curObject.simpleParent if simpleReviewMode else curObject.parent
                if curObject is not None:
                        api.setNavigatorObject(curObject)
                        speech.speakObject(curObject,reason=speech.REASON_QUERY)
                else:
                        speech.speakMessage(_("No parents"))
        script_navigatorObject_parent.__doc__=_("Moves the navigator object to the object containing it")

        def script_navigatorObject_next(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                simpleReviewMode=config.conf["reviewCursor"]["simpleReviewMode"]
                curObject=curObject.simpleNext if simpleReviewMode else curObject.next
                if curObject is not None:
                        api.setNavigatorObject(curObject)
                        speech.speakObject(curObject,reason=speech.REASON_QUERY)
                else:
                        speech.speakMessage(_("No next"))
        script_navigatorObject_next.__doc__=_("Moves the navigator object to the next object")

        def script_navigatorObject_previous(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                simpleReviewMode=config.conf["reviewCursor"]["simpleReviewMode"]
                curObject=curObject.simplePrevious if simpleReviewMode else curObject.previous
                if curObject is not None:
                        api.setNavigatorObject(curObject)
                        speech.speakObject(curObject,reason=speech.REASON_QUERY)
                else:
                        speech.speakMessage(_("No previous"))
        script_navigatorObject_previous.__doc__=_("Moves the navigator object to the previous object")

        def script_navigatorObject_firstChild(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                simpleReviewMode=config.conf["reviewCursor"]["simpleReviewMode"]
                curObject=curObject.simpleFirstChild if simpleReviewMode else curObject.firstChild
                if curObject is not None:
                        api.setNavigatorObject(curObject)
                        speech.speakObject(curObject,reason=speech.REASON_QUERY)
                else:
                        speech.speakMessage(_("No children"))
        script_navigatorObject_firstChild.__doc__=_("Moves the navigator object to the first object it contains")

        def script_navigatorObject_doDefaultAction(self,gesture):
                curObject=api.getNavigatorObject()
                if not isinstance(curObject,NVDAObject):
                        speech.speakMessage(_("no navigator object"))
                        return
                try:
                        action=curObject.getActionName()
                except NotImplementedError:
                        ui.message(_("No default action"))
                        return
                try:
                        curObject.doAction()
                except NotImplementedError:
                        ui.message(_("default action failed"))
                        return
                ui.message("%s"%action)
        script_navigatorObject_doDefaultAction.__doc__=_("Performs the default action on the current navigator object (example: presses it if it is a button).")

        def script_review_top(self,gesture):
                info=api.getReviewPosition().obj.makeTextInfo(textInfos.POSITION_FIRST)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_LINE)
                speech.speakMessage(_("top"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
        script_review_top.__doc__=_("Moves the review cursor to the top line of the current navigator object and speaks it")

        def script_review_previousLine(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_LINE)
                info.collapse()
                res=info.move(textInfos.UNIT_LINE,-1)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_LINE)
                if res==0:
                        speech.speakMessage(_("top"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
        script_review_previousLine.__doc__=_("Moves the review cursor to the previous line of the current navigator object and speaks it")

        def script_review_currentLine(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_LINE)
                scriptCount=scriptHandler.getLastScriptRepeatCount()
                if scriptCount==0:
                        speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
                else:
                        speech.spellTextInfo(info,useCharacterDescriptions=scriptCount>1)
        script_review_currentLine.__doc__=_("Reports the line of the current navigator object where the review cursor is situated. If this key is pressed twice, the current line will be spelled. Pressing three times will spell the line using character descriptions.")
 
        def script_review_nextLine(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_LINE)
                info.collapse()
                res=info.move(textInfos.UNIT_LINE,1)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_LINE)
                if res==0:
                        speech.speakMessage(_("bottom"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
        script_review_nextLine.__doc__=_("Moves the review cursor to the next line of the current navigator object and speaks it")

        def script_review_bottom(self,gesture):
                info=api.getReviewPosition().obj.makeTextInfo(textInfos.POSITION_LAST)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_LINE)
                speech.speakMessage(_("bottom"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
        script_review_bottom.__doc__=_("Moves the review cursor to the bottom line of the current navigator object and speaks it")

        def script_review_previousWord(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_WORD)
                info.collapse()
                res=info.move(textInfos.UNIT_WORD,-1)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_WORD)
                if res==0:
                        speech.speakMessage(_("top"))
                speech.speakTextInfo(info,reason=speech.REASON_CARET,unit=textInfos.UNIT_WORD)
        script_review_previousWord.__doc__=_("Moves the review cursor to the previous word of the current navigator object and speaks it")

        def script_review_currentWord(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_WORD)
                scriptCount=scriptHandler.getLastScriptRepeatCount()
                if scriptCount==0:
                        speech.speakTextInfo(info,reason=speech.REASON_CARET,unit=textInfos.UNIT_WORD)
                else:
                        speech.spellTextInfo(info,useCharacterDescriptions=scriptCount>1)
        script_review_currentWord.__doc__=_("Speaks the word of the current navigator object where the review cursor is situated. Pressing twice spells the word. Pressing three times spells the word using character descriptions")

        def script_review_nextWord(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_WORD)
                info.collapse()
                res=info.move(textInfos.UNIT_WORD,1)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_WORD)
                if res==0:
                        speech.speakMessage(_("bottom"))
                speech.speakTextInfo(info,reason=speech.REASON_CARET,unit=textInfos.UNIT_WORD)
        script_review_nextWord.__doc__=_("Moves the review cursor to the next word of the current navigator object and speaks it")

        def script_review_startOfLine(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_LINE)
                info.collapse()
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_CHARACTER)
                speech.speakMessage(_("left"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
        script_review_startOfLine.__doc__=_("Moves the review cursor to the first character of the line where it is situated in the current navigator object and speaks it")

        def script_review_previousCharacter(self,gesture):
                lineInfo=api.getReviewPosition().copy()
                lineInfo.expand(textInfos.UNIT_LINE)
                charInfo=api.getReviewPosition().copy()
                charInfo.expand(textInfos.UNIT_CHARACTER)
                charInfo.collapse()
                res=charInfo.move(textInfos.UNIT_CHARACTER,-1)
                if res==0 or charInfo.compareEndPoints(lineInfo,"startToStart")<0:
                        speech.speakMessage(_("left"))
                        reviewInfo=api.getReviewPosition().copy()
                        reviewInfo.expand(textInfos.UNIT_CHARACTER)
                        speech.speakTextInfo(reviewInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
                else:
                        api.setReviewPosition(charInfo.copy())
                        charInfo.expand(textInfos.UNIT_CHARACTER)
                        speech.speakTextInfo(charInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
        script_review_previousCharacter.__doc__=_("Moves the review cursor to the previous character of the current navigator object and speaks it")

        def script_review_currentCharacter(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_CHARACTER)
                scriptCount=scriptHandler.getLastScriptRepeatCount()
                if scriptCount==0:
                        speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
                elif scriptCount==1:
                        speech.spellTextInfo(info,useCharacterDescriptions=True)
                else:
                        try:
                                c = ord(info.text)
                                speech.speakMessage("%d," % c)
                                speech.speakSpelling(hex(c))
                        except:
                                speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
        script_review_currentCharacter.__doc__=_("Reports the character of the current navigator object where the review cursor is situated. Pressing twice reports a description or example of that character. Pressing three times reports the numeric value of the character in decimal and hexadecimal")

        def script_review_nextCharacter(self,gesture):
                lineInfo=api.getReviewPosition().copy()
                lineInfo.expand(textInfos.UNIT_LINE)
                charInfo=api.getReviewPosition().copy()
                charInfo.expand(textInfos.UNIT_CHARACTER)
                charInfo.collapse()
                res=charInfo.move(textInfos.UNIT_CHARACTER,1)
                if res==0 or charInfo.compareEndPoints(lineInfo,"endToEnd")>=0:
                        speech.speakMessage(_("right"))
                        reviewInfo=api.getReviewPosition().copy()
                        reviewInfo.expand(textInfos.UNIT_CHARACTER)
                        speech.speakTextInfo(reviewInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
                else:
                        api.setReviewPosition(charInfo.copy())
                        charInfo.expand(textInfos.UNIT_CHARACTER)
                        speech.speakTextInfo(charInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
        script_review_nextCharacter.__doc__=_("Moves the review cursor to the next character of the current navigator object and speaks it")

        def script_review_endOfLine(self,gesture):
                info=api.getReviewPosition().copy()
                info.expand(textInfos.UNIT_LINE)
                info.collapse(end=True)
                info.move(textInfos.UNIT_CHARACTER,-1)
                api.setReviewPosition(info.copy())
                info.expand(textInfos.UNIT_CHARACTER)
                speech.speakMessage(_("right"))
                speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
        script_review_endOfLine.__doc__=_("Moves the review cursor to the last character of the line where it is situated in the current navigator object and speaks it")

        def script_speechMode(self,gesture):
                curMode=speech.speechMode
                speech.speechMode=speech.speechMode_talk
                newMode=(curMode+1)%3
                if newMode==speech.speechMode_off:
                        name=_("off")
                elif newMode==speech.speechMode_beeps:
                        name=_("beeps")
                elif newMode==speech.speechMode_talk:
                        name=_("talk")
                speech.cancelSpeech()
                ui.message(_("speech mode %s")%name)
                speech.speechMode=newMode
        script_speechMode.__doc__=_("Toggles between the speech modes of off, beep and talk. When set to off NVDA will not speak anything. If beeps then NVDA will simply beep each time it its supposed to speak something. If talk then NVDA wil just speak normally.")

        def script_moveToParentTreeInterceptor(self,gesture):
                obj=api.getFocusObject()
                parent=obj.parent
                #Move up parents untill  the tree interceptor of the parent is different to the tree interceptor of the object.
                #Note that this could include the situation where the parent has no tree interceptor but the object did.
                while parent and parent.treeInterceptor==obj.treeInterceptor:
                        parent=parent.parent
                #If the parent has no tree interceptor, keep moving up the parents until we find a parent that does have one.
                while parent and not parent.treeInterceptor:
                        parent=parent.parent
                if parent:
                        parent.treeInterceptor.rootNVDAObject.setFocus()
                        import eventHandler
                        import wx
                        wx.CallLater(50,eventHandler.executeEvent,"gainFocus",parent.treeInterceptor.rootNVDAObject)
        script_moveToParentTreeInterceptor.__doc__=_("Moves the focus to the next closest document that contains the focus")

        def script_toggleVirtualBufferPassThrough(self,gesture):
                vbuf = api.getFocusObject().treeInterceptor
                if not vbuf or not isinstance(vbuf, virtualBuffers.VirtualBuffer):
                        return
                # Toggle virtual buffer pass-through.
                vbuf.passThrough = not vbuf.passThrough
                # If we are enabling pass-through, the user has explicitly chosen to do so, so disable auto-pass-through.
                # If we're disabling pass-through, re-enable auto-pass-through.
                vbuf.disableAutoPassThrough = vbuf.passThrough
                virtualBuffers.reportPassThrough(vbuf)
        script_toggleVirtualBufferPassThrough.__doc__=_("Toggles between browse mode and focus mode. When in focus mode, keys will pass straight through to the application, allowing you to interact directly with a control. When in browse mode, you can navigate the document with the cursor, quick navigation keys, etc.")

        def script_quit(self,gesture):
                gui.quit()
        script_quit.__doc__=_("Quits NVDA!")

        def script_showGui(self,gesture):
                gui.showGui()
        script_showGui.__doc__=_("Shows the NVDA menu")

        def script_review_sayAll(self,gesture):
                info=api.getReviewPosition().copy()
                sayAllHandler.readText(info,sayAllHandler.CURSOR_REVIEW)
        script_review_sayAll.__doc__ = _("reads from the review cursor  up to end of current text, moving the review cursor as it goes")

        def script_sayAll(self,gesture):
                o=api.getFocusObject()
                ti=o.treeInterceptor
                if ti and not ti.passThrough:
                        o=ti
                try:
                        info=o.makeTextInfo(textInfos.POSITION_CARET)
                except (NotImplementedError, RuntimeError):
                        return
                sayAllHandler.readText(info,sayAllHandler.CURSOR_CARET)
        script_sayAll.__doc__ = _("reads from the system caret up to the end of the text, moving the caret as it goes")

        def script_reportFormatting(self,gesture):
                formatConfig={
                        "detectFormatAfterCursor":False,
                        "reportFontName":True,"reportFontSize":True,"reportFontAttributes":True,"reportColor":True,
                        "reportStyle":True,"reportAlignment":True,"reportSpellingErrors":True,
                        "reportPage":False,"reportLineNumber":False,"reportTables":False,
                        "reportLinks":False,"reportHeadings":False,"reportLists":False,
                        "reportBlockQuotes":False,
                }
                textList=[]
                info=api.getReviewPosition()

                # First, fetch indentation.
                line=info.copy()
                line.expand(textInfos.UNIT_LINE)
                indentation,content=speech.splitTextIndentation(line.text)
                if indentation:
                        textList.append(speech.getIndentationSpeech(indentation))
                
                info.expand(textInfos.UNIT_CHARACTER)
                formatField=textInfos.FormatField()
                for field in info.getTextWithFields(formatConfig):
                        if isinstance(field,textInfos.FieldCommand) and isinstance(field.field,textInfos.FormatField):
                                formatField.update(field.field)
                text=speech.getFormatFieldSpeech(formatField,formatConfig=formatConfig) if formatField else None
                if text:
                        textList.append(text)

                if not textList:
                        ui.message(_("No formatting information"))
                        return

                ui.message(" ".join(textList))
        script_reportFormatting.__doc__ = _("Reports formatting info for the current review cursor position within a document")

        def script_reportCurrentFocus(self,gesture):
                focusObject=api.getFocusObject()
                if isinstance(focusObject,NVDAObject):
                        if scriptHandler.getLastScriptRepeatCount()==0:
                                speech.speakObject(focusObject, reason=speech.REASON_QUERY)
                        else:
                                speech.speakSpelling(focusObject.name)
                else:
                        speech.speakMessage(_("no focus"))
        script_reportCurrentFocus.__doc__ = _("reports the object with focus")

        def script_reportStatusLine(self,gesture):
                obj = api.getStatusBar()
                found=False
                if obj:
                        text = api.getStatusBarText(obj)
                        api.setNavigatorObject(obj)
                        found=True
                else:
                        info=api.getForegroundObject().flatReviewPosition
                        if info:
                                info.expand(textInfos.UNIT_STORY)
                                info.collapse(True)
                                info.expand(textInfos.UNIT_LINE)
                                text=info.text
                                info.collapse()
                                api.setReviewPosition(info)
                                found=True
                if not found:
                        ui.message(_("No status line found"))
                        return
                if scriptHandler.getLastScriptRepeatCount()==0:
                        ui.message(text)
                else:
                        speech.speakSpelling(text)
        script_reportStatusLine.__doc__ = _("reads the current application status bar and moves the navigator to it")

        def script_toggleMouseTracking(self,gesture):
                if config.conf["mouse"]["enableMouseTracking"]:
                        onOff=_("off")
                        config.conf["mouse"]["enableMouseTracking"]=False
                else:
                        onOff=_("on")
                        config.conf["mouse"]["enableMouseTracking"]=True
                ui.message(_("Mouse tracking")+" "+onOff)
        script_toggleMouseTracking.__doc__=_("Toggles the reporting of information as the mouse moves")

        def script_title(self,gesture):
                obj=api.getForegroundObject()
                title=obj.name
                if not isinstance(title,basestring) or not title or title.isspace():
                        title=obj.appModule.appName  if obj.appModule else None
                        if not isinstance(title,basestring) or not title or title.isspace():
                                title=_("no title")
                repeatCount=scriptHandler.getLastScriptRepeatCount()
                if repeatCount==0:
                        ui.message(title)
                elif repeatCount==1:
                        speech.speakSpelling(title)
                else:
                        if api.copyToClip(title):
                                ui.message(_("%s copied to clipboard")%title)
        script_title.__doc__=_("Reports the title of the current application or foreground window. If pressed twice, spells the title. If pressed thrice, copies the title to the clipboard")

        def script_speakForeground(self,gesture):
                obj=api.getForegroundObject()
                if obj:
                        sayAllHandler.readObjects(obj)
        script_speakForeground.__doc__ = _("speaks the current foreground object")

        def script_test_navigatorDisplayModelText(self,gesture):
                obj=api.getNavigatorObject()
                text=obj.displayText
                speech.speakMessage(text)
                log.info(text)

        def script_navigatorObject_devInfo(self,gesture):
                obj=api.getNavigatorObject()
                log.info("Developer info for navigator object:\n%s" % "\n".join(obj.devInfo), activateLogViewer=True)
        script_navigatorObject_devInfo.__doc__ = _("Logs information about the current navigator object which is useful to developers and activates the log viewer so the information can be examined.")

        def script_toggleProgressBarOutput(self,gesture):
                outputMode=config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]
                if outputMode=="both":
                        outputMode="off"
                        ui.message(_("no progress bar updates"))
                elif outputMode=="off":
                        outputMode="speak"
                        ui.message(_("speak progress bar updates"))
                elif outputMode=="speak":
                        outputMode="beep"
                        ui.message(_("beep for progress bar updates"))
                else:
                        outputMode="both"
                        ui.message(_("beep and speak progress bar updates"))
                config.conf["presentation"]["progressBarUpdates"]["progressBarOutputMode"]=outputMode
        script_toggleProgressBarOutput.__doc__=_("Toggles between beeps, speech, beeps and speech, and off, for reporting progress bar updates")

        def script_toggleReportDynamicContentChanges(self,gesture):
                if config.conf["presentation"]["reportDynamicContentChanges"]:
                        onOff=_("off")
                        config.conf["presentation"]["reportDynamicContentChanges"]=False
                else:
                        onOff=_("on")
                        config.conf["presentation"]["reportDynamicContentChanges"]=True
                ui.message(_("report dynamic content changes")+" "+onOff)
        script_toggleReportDynamicContentChanges.__doc__=_("Toggles on and off the reporting of dynamic content changes, such as new text in dos console windows")

        def script_toggleCaretMovesReviewCursor(self,gesture):
                if config.conf["reviewCursor"]["followCaret"]:
                        onOff=_("off")
                        config.conf["reviewCursor"]["followCaret"]=False
                else:
                        onOff=_("on")
                        config.conf["reviewCursor"]["followCaret"]=True
                ui.message(_("caret moves review cursor")+" "+onOff)
        script_toggleCaretMovesReviewCursor.__doc__=_("Toggles on and off the movement of the review cursor due to the caret moving.")

        def script_toggleFocusMovesNavigatorObject(self,gesture):
                if config.conf["reviewCursor"]["followFocus"]:
                        onOff=_("off")
                        config.conf["reviewCursor"]["followFocus"]=False
                else:
                        onOff=_("on")
                        config.conf["reviewCursor"]["followFocus"]=True
                ui.message(_("focus moves navigator object")+" "+onOff)
        script_toggleFocusMovesNavigatorObject.__doc__=_("Toggles on and off the movement of the navigator object due to focus changes") 

        #added by Rui Batista to implement a battery status script
        def script_say_battery_status(self,gesture):
                UNKNOWN_BATTERY_STATUS = 0xFF
                AC_ONLINE = 0X1
                NO_SYSTEM_BATTERY = 0X80
                sps = winKernel.SYSTEM_POWER_STATUS()
                if not winKernel.GetSystemPowerStatus(sps) or sps.BatteryFlag is UNKNOWN_BATTERY_STATUS:
                        log.error("error accessing system power status")
                        return
                if sps.BatteryFlag & NO_SYSTEM_BATTERY:
                        ui.message(_("no system battery"))
                        return
                text = _("%d percent") % sps.BatteryLifePercent + " "
                if sps.ACLineStatus & AC_ONLINE: text += _("AC power on")
                elif sps.BatteryLifeTime!=0xffffffff: 
                        text += _("%d hours and %d minutes remaining") % (sps.BatteryLifeTime / 3600, (sps.BatteryLifeTime % 3600) / 60)
                ui.message(text)
        script_say_battery_status.__doc__ = _("reports battery status and time remaining if AC is not plugged in")

        def script_passNextKeyThrough(self,gesture):
                keyboardHandler.passNextKeyThrough()
                ui.message(_("Pass next key through"))
        script_passNextKeyThrough.__doc__=_("The next key that is pressed will not be handled at all by NVDA, it will be passed directly through to Windows.")

        def script_reportAppModuleInfo(self,gesture):
                focus=api.getFocusObject()
                appName=appModuleHandler.getAppNameFromProcessID(focus.processID,True)
                message = _("Currently running application is %s") % appName
                mod=focus.appModule
                if isinstance(mod,appModuleHandler.AppModule) and type(mod)!=appModuleHandler.AppModule:
                        message += _(" and currently loaded module is %s") % mod.appModuleName.split(".")[0]
                ui.message(message)
        script_reportAppModuleInfo.__doc__ = _("Speaks the filename of the active application along with the name of the currently loaded appModule")

        def script_activateGeneralSettingsDialog(self, gesture):
                wx.CallAfter(mainFrame.onGeneralSettingsCommand, None)
        script_activateGeneralSettingsDialog.__doc__ = _("Shows the NVDA general settings dialog")

        def script_activateSynthesizerDialog(self, gesture):
                wx.CallAfter(mainFrame.onSynthesizerCommand, None)
        script_activateSynthesizerDialog.__doc__ = _("Shows the NVDA synthesizer dialog")

        def script_activateVoiceDialog(self, gesture):
                wx.CallAfter(mainFrame.onVoiceCommand, None)
        script_activateVoiceDialog.__doc__ = _("Shows the NVDA voice settings dialog")

        def script_activateKeyboardSettingsDialog(self, gesture):
                wx.CallAfter(mainFrame.onKeyboardSettingsCommand, None)
        script_activateKeyboardSettingsDialog.__doc__ = _("Shows the NVDA keyboard settings dialog")

        def script_activateMouseSettingsDialog(self, gesture):
                wx.CallAfter(mainFrame.onMouseSettingsCommand, None)
        script_activateMouseSettingsDialog.__doc__ = _("Shows the NVDA mouse settings dialog")

        def script_activateObjectPresentationDialog(self, gesture):
                wx.CallAfter(mainFrame. onObjectPresentationCommand, None)
        script_activateObjectPresentationDialog.__doc__ = _("Shows the NVDA object presentation settings dialog")

        def script_activateBrowseModeDialog(self, gesture):
                wx.CallAfter(mainFrame.onBrowseModeCommand, None)
        script_activateBrowseModeDialog.__doc__ = _("Shows the NVDA browse mode settings dialog")

        def script_activateDocumentFormattingDialog(self, gesture):
                wx.CallAfter(mainFrame.onDocumentFormattingCommand, None)
        script_activateDocumentFormattingDialog.__doc__ = _("Shows the NVDA document formatting settings dialog")

        def script_saveConfiguration(self,gesture):
                wx.CallAfter(mainFrame.onSaveConfigurationCommand, None)
        script_saveConfiguration.__doc__ = _("Saves the current NVDA configuration")

        def script_revertToSavedConfiguration(self,gesture):
                mainFrame.onRevertToSavedConfigurationCommand(None)
        script_revertToSavedConfiguration.__doc__ = _("loads the saved NVDA configuration, overriding current changes")

        def script_activatePythonConsole(self,gesture):
                if globalVars.appArgs.secure:
                        return
                import pythonConsole
                if not pythonConsole.consoleUI:
                        pythonConsole.initialize()
                pythonConsole.consoleUI.console.updateNamespaceSnapshotVars()
                pythonConsole.activate()
        script_activatePythonConsole.__doc__ = _("Activates the NVDA Python Console, primarily useful for development")

        def script_braille_toggleTether(self, gesture):
                if braille.handler.tether == braille.handler.TETHER_FOCUS:
                        braille.handler.tether = braille.handler.TETHER_REVIEW
                        tetherMsg = _("review")
                else:
                        braille.handler.tether = braille.handler.TETHER_FOCUS
                        tetherMsg = _("focus")
                ui.message(_("Braille tethered to %s") % tetherMsg)
        script_braille_toggleTether.__doc__ = _("Toggle tethering of braille between the focus and the review position")

        def script_reportClipboardText(self,gesture):
                try:
                        text = api.getClipData()
                except:
                        text = None
                if not text or not isinstance(text,basestring) or text.isspace():
                        ui.message(_("There is no text on the clipboard"))
                        return
                if len(text) < 1024: 
                        ui.message(text)
                else:
                        ui.message(_("The clipboard contains a large portion of text. It is %s characters long") % len(text))
        script_reportClipboardText.__doc__ = _("Reports the text on the Windows clipboard")

        def script_review_markStartForCopy(self, gesture):
                self._copyStartMarker = api.getReviewPosition().copy()
                ui.message(_("Start marked"))
        script_review_markStartForCopy.__doc__ = _("Marks the current position of the review cursor as the start of text to be copied")

        def script_review_copy(self, gesture):
                if not getattr(self, "_copyStartMarker", None):
                        ui.message(_("No start marker set"))
                        return
                pos = api.getReviewPosition().copy()
                if self._copyStartMarker.obj != pos.obj:
                        ui.message(_("The start marker must reside within the same object"))
                        return
                pos.move(textInfos.UNIT_CHARACTER, 1, endPoint="end")
                pos.setEndPoint(self._copyStartMarker, "startToStart")
                if pos.compareEndPoints(pos, "startToEnd") < 0 and pos.copyToClipboard():
                        ui.message(_("Review selection copied to clipboard"))
                else:
                        ui.message(_("No text to copy"))
                        return
                self._copyStartMarker = None
        script_review_copy.__doc__ = _("Retrieves the text from the previously set start marker up to and including the current position of the review cursor and copies it to the clipboard")

        def script_braille_scrollBack(self, gesture):
                braille.handler.scrollBack()
        script_braille_scrollBack.__doc__ = _("Scrolls the braille display back")
        script_braille_scrollBack.bypassInputHelp = True

        def script_braille_scrollForward(self, gesture):
                braille.handler.scrollForward()
        script_braille_scrollForward.__doc__ = _("Scrolls the braille display forward")
        script_braille_scrollForward.bypassInputHelp = True

        def script_braille_routeTo(self, gesture):
                braille.handler.routeTo(gesture.routingIndex)
        script_braille_routeTo.__doc__ = _("Routes the cursor to or activates the object under this braille cell")

        def script_braille_previousLine(self, gesture):
                if braille.handler.buffer.regions: 
                        braille.handler.buffer.regions[-1].previousLine(start=True)
        script_braille_previousLine.__doc__ = _("Moves the braille display to the previous line")

        def script_braille_nextLine(self, gesture):
                if braille.handler.buffer.regions: 
                        braille.handler.buffer.regions[-1].nextLine()
        script_braille_nextLine.__doc__ = _("Moves the braille display to the next line")

        def script_reloadPlugins(self, gesture):
                import globalPluginHandler
                appModuleHandler.reloadAppModules()
                globalPluginHandler.reloadGlobalPlugins()
                NVDAObject.clearDynamicClassCache()
                ui.message(_("Plugins reloaded"))
        script_reloadPlugins.__doc__=_("Reloads app modules and global plugins without restarting NVDA, which can be Useful for developers")

        __gestures = {
                # Basic
                "kb:NVDA+n": "showGui",
                "kb:NVDA+1": "toggleInputHelp",
                "kb:NVDA+q": "quit",
                "kb:NVDA+f2": "passNextKeyThrough",
                "kb:NVDA+shift+s":"toggleCurrentAppSleepMode",

                # System status
                "kb:NVDA+f12": "dateTime",
                "kb:NVDA+shift+b": "say_battery_status",
                "kb:NVDA+c": "reportClipboardText",

                # System focus
                "kb:NVDA+tab": "reportCurrentFocus",
                "kb:NVDA+t": "title",
                "kb:NVDA+b": "speakForeground",
                "kb:NVDA+end": "reportStatusLine",

                # System caret
                "kb:NVDA+downArrow": "sayAll",
                "kb:NVDA+upArrow": "reportCurrentLine",
                "kb:NVDA+shift+upArrow": "reportCurrentSelection",
                "kb:NVDA+f": "reportFormatting",

                # Object navigation
                "kb:NVDA+numpad5": "navigatorObject_current",
                "kb(laptop):NVDA+control+i": "navigatorObject_current",
                "kb:NVDA+numpad8": "navigatorObject_parent",
                "kb(laptop):NVDA+shift+i": "navigatorObject_parent",
                "kb:NVDA+numpad4": "navigatorObject_previous",
                "kb(laptop):NVDA+control+j": "navigatorObject_previous",
                "kb:NVDA+numpad6": "navigatorObject_next",
                "kb(laptop):NVDA+control+l": "navigatorObject_next",
                "kb:NVDA+numpad2": "navigatorObject_firstChild",
                "kb(laptop):NVDA+shift+,": "navigatorObject_firstChild",
                "kb:NVDA+numpadMinus": "navigatorObject_toFocus",
                "kb(laptop):NVDA+backspace": "navigatorObject_toFocus",
                "kb:NVDA+numpadEnter": "navigatorObject_doDefaultAction",
                "kb(laptop):NVDA+enter": "navigatorObject_doDefaultAction",
                "kb:NVDA+shift+numpadMinus": "navigatorObject_moveFocus",
                "kb(laptop):NVDA+shift+backspace": "navigatorObject_moveFocus",
                "kb:NVDA+numpadDelete": "navigatorObject_currentDimensions",
                "kb(laptop):NVDA+delete": "navigatorObject_currentDimensions",

                # Review cursor
                "kb:shift+numpad7": "review_top",
                "kb(laptop):NVDA+7": "review_top",
                "kb:numpad7": "review_previousLine",
                "kb(laptop):NVDA+u": "review_previousLine",
                "kb:numpad8": "review_currentLine",
                "kb(laptop):NVDA+i": "review_currentLine",
                "kb:numpad9": "review_nextLine",
                "kb(laptop):NVDA+o": "review_nextLine",
                "kb:shift+numpad9": "review_bottom",
                "kb(laptop):NVDA+9": "review_bottom",
                "kb:numpad4": "review_previousWord",
                "kb(laptop):NVDA+j": "review_previousWord",
                "kb:numpad5": "review_currentWord",
                "kb(laptop):NVDA+k": "review_currentWord",
                "kb:numpad6": "review_nextWord",
                "kb(laptop):NVDA+l": "review_nextWord",
                "kb:shift+numpad1": "review_startOfLine",
                "kb(laptop):NVDA+shift+u": "review_startOfLine",
                "kb:numpad1": "review_previousCharacter",
                "kb(laptop):NVDA+m": "review_previousCharacter",
                "kb:numpad2": "review_currentCharacter",
                "kb(laptop):NVDA+,": "review_currentCharacter",
                "kb:numpad3": "review_nextCharacter",
                "kb(laptop):NVDA+.": "review_nextCharacter",
                "kb:shift+numpad3": "review_endOfLine",
                "kb(laptop):NVDA+shift+o": "review_endOfLine",
                "kb:numpadPlus": "review_sayAll",
                "kb(laptop):NVDA+shift+downArrow": "review_sayAll",
                "kb:NVDA+f9": "review_markStartForCopy",
                "kb:NVDA+f10": "review_copy",

                # Flat review
                "kb:NVDA+numpad7": "navigatorObject_moveToFlatReviewAtObjectPosition",
                "kb(laptop):NVDA+pageUp": "navigatorObject_moveToFlatReviewAtObjectPosition",
                "kb:NVDA+numpad1": "navigatorObject_moveToObjectAtFlatReviewPosition",
                "kb(laptop):NVDA+pageDown": "navigatorObject_moveToObjectAtFlatReviewPosition",

                # Mouse
                "kb:numpadDivide": "leftMouseClick",
                "kb(laptop):NVDA+leftArrow": "leftMouseClick",
                "kb:shift+numpadDivide": "toggleLeftMouseButton",
                "kb(laptop):NVDA+shift+leftArrow": "toggleLeftMouseButton",
                "kb:numpadMultiply": "rightMouseClick",
                "kb(laptop):NVDA+rightArrow": "rightMouseClick",
                "kb:shift+numpadMultiply": "toggleRightMouseButton",
                "kb(laptop):NVDA+shift+rightArrow": "toggleRightMouseButton",
                "kb:NVDA+numpadDivide": "moveMouseToNavigatorObject",
                "kb(laptop):NVDA+shift+f9": "moveMouseToNavigatorObject",
                "kb:NVDA+numpadMultiply": "moveNavigatorObjectToMouse",
                "kb(laptop):NVDA+shift+f10": "moveNavigatorObjectToMouse",

                # Tree interceptors
                "kb:NVDA+space": "toggleVirtualBufferPassThrough",
                "kb:NVDA+control+space": "moveToParentTreeInterceptor",

                # Preferences dialogs
                "kb:NVDA+control+g": "activateGeneralSettingsDialog",
                "kb:NVDA+control+s": "activateSynthesizerDialog",
                "kb:NVDA+control+v": "activateVoiceDialog",
                "kb:NVDA+control+k": "activateKeyboardSettingsDialog",
                "kb:NVDA+control+m": "activateMouseSettingsDialog",
                "kb:NVDA+control+o": "activateObjectPresentationDialog",
                "kb:NVDA+control+b": "activateBrowseModeDialog",
                "kb:NVDA+control+d": "activateDocumentFormattingDialog",

                # Save/reload configuration
                "kb:NVDA+control+c": "saveConfiguration",
                "kb:NVDA+control+r": "revertToSavedConfiguration",

                # Settings
                "kb:NVDA+2": "toggleSpeakTypedCharacters",
                "kb:NVDA+3": "toggleSpeakTypedWords",
                "kb:NVDA+4": "toggleSpeakCommandKeys",
                "kb:NVDA+p": "cycleSpeechSymbolLevel",
                "kb:NVDA+s": "speechMode",
                "kb(desktop):NVDA+m": "toggleMouseTracking",
                "kb(laptop):NVDA+shift+m": "toggleMouseTracking",
                "kb(desktop):NVDA+u": "toggleProgressBarOutput",
                "kb(laptop):NVDA+control+f2": "toggleProgressBarOutput",
                "kb:NVDA+5": "toggleReportDynamicContentChanges",
                "kb:NVDA+6": "toggleCaretMovesReviewCursor",
                "kb(desktop):NVDA+7": "toggleFocusMovesNavigatorObject",
                "kb(laptop):NVDA+control+7": "toggleFocusMovesNavigatorObject",
                "kb:NVDA+control+t": "braille_toggleTether",

                # Synth settings ring
                "kb:NVDA+control+leftArrow": "previousSynthSetting",
                "kb:NVDA+control+rightArrow": "nextSynthSetting",
                "kb:NVDA+control+upArrow": "increaseSynthSetting",
                "kb:NVDA+control+downArrow": "decreaseSynthSetting",

                # Tools
                "kb:NVDA+f1": "navigatorObject_devInfo",
                "kb:NVDA+control+f1": "reportAppModuleInfo",
                "kb:NVDA+control+z": "activatePythonConsole",
                "kb:NVDA+control+f3": "reloadPlugins",
                "kb(desktop):NVDA+control+f2": "test_navigatorDisplayModelText",
        }

#: The single global commands instance.
#: @type: L{GlobalCommands}
commands = GlobalCommands()