Changeset 1745

Show
Ignore:
Timestamp:
02/29/08 05:32:20 (10 months ago)
Author:
jteh
Message:

Merge from guiRefactor branch:

1551 James Teh 2008-02-28

Some major changes to the GUI:
Get rid of the old NVDA main window. This includes the quick start text, which is extremely outdated, full of errors, difficult for translators and otherwise abominable.
Instead, move to a system tray popup menu. This is activated when NVDA+N is pressed or when the system tray icon is right clicked.
As a result, the shortcut keys to access menu items (e.g. Control+Shift+V for Voice Settings) can no longer be used, so remove them from the menu item text.
We still have a main frame to handle events and act as the main app window which causes the app to exit once destroyed. Showing and hiding this window briefly at startup also seems to make Windows more readily disposed to allowing NVDA popups to come to the foreground later. I suspect this has something to do with the application receiving permission to set the foreground window, but I don't really understand it.
All dialogs are no longer children of the mainFrame. This isn't necessary and causes foreground window problems.
Change all occurrences of the literal -1 to wx.ID_ANY.

1554 James Teh 2008-02-28

Major rework of the settingsDialogs code.

All settings dialogs now inherit from the new SettingsDialog? class. SettingsDialog? encapsulates functionality common to all settings dialogs.
Aside from its cosmetic and design appeal, all dialogs are now destroyed properly after they are dismissed.
The dialog title is now maintained inside the dialog class instead of in the caller.
The ID is wx.ID_ANY for all dialogs; this is no longer passed from the caller.
Also, all settings dialog class names now start with a capital letter.

1555 James Teh 2008-02-28

Remove the NVDA menu. Move User Dictionaries into the Preferences menu. Move Revert to Save configuration, Save Configuration and Exit to the bottom of the root sys tray menu.

1556 James Teh 2008-02-29

Fix a bug whereby NVDAObjectTextInfo.find() would land on an incorrect position if searching from anywhere but the start. This was exhibited in the cursor manager find text functionality.
Fix the code which handles reverse searching in NVDAObjectTextInfo.find(). Note that this is not yet accessible from the cursor manager UI.
CursorManager?: Add NVDA+Control+f to activate the find dialog. NVDA+f3 now searches for the next occurrence of the string or brings up the find dialog if no string has yet been entered.
Minor tweaks to some text and add code comments.

Location:
trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk

    • Property bzr:revision-id:v3-list-QlpoOTFBWSZTWbrL2vUAAB1VgAAQABCAQDrrnqAgAFCgaaGRkxBoTIJ6mmaNRwhndFAoNhZjh_YY4a01fOg1ulgNNC2UrzPdXXEnDpX8XckU4UJC6y9r1A..
      •  

        old new  
        19191530 jamie@jantrid.net-20080215080141-qov11ehariolqw9r 
        20201550 jamie@jantrid.net-20080225041147-i0y220xihclzjie9 
         211560 jamie@jantrid.net-20080229052638-g5ue0zyljknt2jcm 
    • Property bzr:revision-info
      •  

        old new  
        1 timestamp: 2008-02-25 14:11:47.684000015 +1000 
         1timestamp: 2008-02-29 15:26:38.703000069 +1000 
        22committer: James Teh <jamie@jantrid.net> 
        33properties:  
    • Property bzr:ancestry:v3-list-QlpoOTFBWSZTWbrL2vUAAB1VgAAQABCAQDrrnqAgAFCgaaGRkxBoTIJ6mmaNRwhndFAoNhZjh_YY4a01fOg1ulgNNC2UrzPdXXEnDpX8XckU4UJC6y9r1A..
      •  

        old new  
        22jamie@jantrid.net-20080211041432-1l2b1pi3k3iso2kg 
        33jamie@jantrid.net-20080212104116-78n366kl7diwve24 
         4jamie@jantrid.net-20080229050825-20q1xhb2t4c0zcza 
  • trunk/source/NVDAObjects/__init__.py

    r1722 r1745  
    292292 
    293293        def find(self,text,caseSensitive=False,reverse=False): 
    294                 if not reverse: 
     294                if reverse: 
     295                        # When searching in reverse, we reverse both strings and do a forwards search. 
     296                        text = text[::-1] 
     297                        # Start searching one before the start to avoid finding the current match. 
     298                        inText=self._getTextRange(0,self._startOffset)[::-1] 
     299                else: 
     300                        # Start searching one past the start to avoid finding the current match. 
    295301                        inText=self._getTextRange(self._startOffset+1,self._getStoryLength()) 
    296                 else: 
    297                         inText=self._getTextRange(0,self._startOffset)[::-1] 
    298302                m=re.search(re.escape(text),inText,re.IGNORECASE) 
    299303                if not m: 
    300304                        return False 
    301                 offset=m.start() 
    302305                if reverse: 
    303                         offset=self._startOffset-offset 
     306                        offset=self._startOffset-m.end() 
     307                else: 
     308                        offset=self._startOffset+1+m.start() 
    304309                self._startOffset=self._endOffset=offset 
    305310                return True 
  • trunk/source/cursorManager.py

    r1723 r1745  
    8080 
    8181        def doFindTextDialogHelper(self,text): 
     82                if not text: 
     83                        self._inFind=False 
     84                        return 
    8285                info=self.makeTextInfo(textHandler.POSITION_CARET) 
    8386                res=info.find(text) 
     
    9194                                speech.speakFormattedText(info) 
    9295                else: 
    93                         errorDialog=gui.scriptUI.MessageDialog(_("text: \"%s\" not found")%text,title=_("Find Error")) 
     96                        errorDialog=gui.scriptUI.MessageDialog(_("text \"%s\" not found")%text,title=_("Find Error"),style=gui.scriptUI.wx.OK|gui.scriptUI.wx.ICON_ERROR) 
    9497                        errorDialog.run() 
    9598                self._lastFindText=text 
     
    98101        def script_find(self,keyPress,nextScript):  
    99102                self.doFindTextDialog() 
    100         script_find.__doc__ = _("find a text pattern from the current cursor's position") 
     103        script_find.__doc__ = _("find a text string from the current cursor position") 
     104 
     105        def script_findNext(self, keyPress, nextScript): 
     106                if not self._lastFindText: 
     107                        self.doFindTextDialog() 
     108                        return 
     109                self.doFindTextDialogHelper(self._lastFindText) 
     110        script_findNext.__doc__ = _("find the next occurrence of the previously entered text string from the current cursor's position") 
    101111 
    102112        def script_pageUp(self,keyPress,nextScript): 
     
    262272                        ("control+a","selectAll"), 
    263273                        ("control+c","copyToClipboard"), 
    264                         ("NVDA+f3","find"), 
     274                        ("NVDA+Control+f","find"), 
     275                        ("NVDA+f3","findNext"), 
    265276                ): 
    266277                        self.bindKey_runtime(keyName, scriptName) 
  • trunk/source/gui/__init__.py

    r1713 r1745  
    1717from settingsDialogs import * 
    1818import userDictHandler 
     19#import winUser 
    1920 
    2021### Constants 
    2122appTitle = "NVDA" 
    22 quickStartMessage=_("""NVDA - Quick Start document 
    23  
    24 NVDA (%(description)s) 
    25 Version: %(version)s 
    26 URL: %(url)s 
    27 Please send bugs and suggestions to: %(maintainer)s <%(maintainer_email)s>. 
    28  
    29 --- Copyright Info --- 
    30 %(copyrightInfo)s 
    31 ---------------------- 
    32  
    33 This is the NVDA interface window. It enables you to control NVDA's settings, and also to exit NVDA altogether. 
    34  
    35 To bring this window up at any time, press insert+n. To close this window without exiting NVDA, press alt+f4. 
    36  
    37 To exit NVDA completely, either press insert+q from anywhere, or choose 'exit' from the NVDA menuin this window. NVDA will then bring up a dialog box asking you if you want to exit, and you can either press the OK or Cancel button. 
    38  
    39 To set the preferences (such as voice settings, key Settings, reading of tooltips etc), 
    40 Use the alt key to move to the menu bar and then use the arrow keys to navigate the menus and find the settings you want to change. Pressing enter on many of the menu items will bring up a dialog box in which you can change the individual settings. Most settings will take effect straight away (such as changing the rate or pitch of the voice) so you can easily find what settings most suit you. However, if you cancel out of the dialog box the settings will go back to what they were before you changed them.  
    41  
    42 By default settings are not kept for the next time you run NVDA unless you press ctrl+s or choose 'save configuration' from the NVDA menu. You can set NVDA to automatically save the settings on exit by going to 'general settings...' in the Preferences menu and checking the 'Save configuration on exit' checkbox and press ing ok. 
    43  
    44 Some usefull key commands when using NVDA are: 
    45  
    46 General key strokes: 
    47 control - interupt/pause speech 
    48 shift - unpause speech 
    49 NVDA+1 - turns keyboard help on and off 
    50 NVDA+upArrow - reports the object with focus 
    51 NVDA+downArrow - starts sayAll (press control or any other key to stop) 
    52 NVDA+tab - report the object currently in focus 
    53 NVDA+t speak title 
    54 NVDA+f12 - report time and date 
    55 NVDA+2 - turn speaking of typed characters on and off 
    56 NVDA+3 turn speaking of typed words on and off 
    57 NVDA+4 - turn speaking of typed command keys (such as space, arrows, control and shift combinations) on and off 
    58 NVDA+pageUp - increase rate of speech 
    59 NVDA+pageDown - decrease rate of speech 
    60 NVDA+p - turn reading of punctuation on and off 
    61 NVDA+s - toggle speech modes (off, talk and beeps) 
    62 NVDA+m - turn  reading of objects under the mouse on and off 
    63 NVDA+f - report current font (when in a document) 
    64  
    65 Object navigation: 
    66 NVDA+numpadAdd - Where am I 
    67 NVDA+numpad5 - current object 
    68 shift+NVDA+numpad5 - dimensions and location of current object 
    69 NVDA+numpad8 - parent object 
    70 NVDA+numpad4 - previous object 
    71 NVDA+numpad6 - next object 
    72 NVDA+numpad2 - first child object 
    73 NVDA+numpadMinus - move to focus object 
    74 NVDA+end - move to statusbar 
    75 NVDA+numpadDivide - Move mouse to current navigator object 
    76 NVDA+numpadMultiply - move to mouse 
    77 nvda+numpadEnter - activate current object 
    78  
    79 Reviewing the current object: 
    80 shift+numpad7 - move to top line 
    81 numpad7 - previous line 
    82 numpad8 - current line 
    83 numpad9 - next line 
    84 shift+numpad9 - bottom line 
    85 numpad4 - previous word 
    86 numpad5 - current word 
    87 numpad6 - next word 
    88 shift+numpad1 - start of line 
    89 numpad1 - previous character 
    90 numpad2 - current character 
    91 numpad3 - next character 
    92 shift+numpad3 - end of line 
    93 """)%vars(versionInfo) 
    94   
    9523iconPath="%s/images/icon.png"%os.getcwd() 
    9624 
     
    13058                self.Bind(evt_externalCommand, self.onShowGuiCommand, id=id_showGuiCommand) 
    13159                wx.EVT_COMMAND(self,wx.ID_ANY,evt_externalExecute,lambda evt: evt.run()) 
    132                 self.Bind(wx.EVT_CLOSE, self.onHideGuiCommand) 
    133                 menuBar=wx.MenuBar() 
    134                 self.sysTrayMenu=wx.Menu() 
    135                 menu_NVDA = wx.Menu() 
    136                 item = menu_NVDA.Append(wx.ID_ANY, _("&Revert to saved configuration\tCtrl+R"),_("Reset all settings to saved state")) 
    137                 self.Bind(wx.EVT_MENU, self.onRevertToSavedConfigurationCommand, item) 
    138                 item = menu_NVDA.Append(wx.ID_SAVE, _("&Save configuration\tCtrl+S"), _("Write the current configuration to nvda.ini")) 
    139                 self.Bind(wx.EVT_MENU, self.onSaveConfigurationCommand, item) 
    140                 subMenu_userDicts = wx.Menu() 
    141                 item = subMenu_userDicts.Append(wx.ID_ANY,_("&Default dictionary..."),_("dialog where you can set default dictionary by adding dictionary entries to the list")) 
    142                 self.Bind(wx.EVT_MENU, self.onDefaultDictionaryCommand, item) 
    143                 item = subMenu_userDicts.Append(wx.ID_ANY,_("&Voice dictionary..."),_("dialog where you can set voice-specific dictionary by adding dictionary entries to the list")) 
    144                 self.Bind(wx.EVT_MENU, self.onVoiceDictionaryCommand, item) 
    145                 item = subMenu_userDicts.Append(wx.ID_ANY,_("&Temporary dictionary..."),_("dialog where you can set temporary dictionary by adding dictionary entries to the edit box")) 
    146                 self.Bind(wx.EVT_MENU, self.onTemporaryDictionaryCommand, item) 
    147                 menu_NVDA.AppendMenu(wx.ID_ANY,_("User &dictionaries"),subMenu_userDicts) 
    148                 menu_NVDA.AppendSeparator() 
    149                 item = menu_NVDA.Append(wx.ID_EXIT, _("E&xit"),_("Exit NVDA")) 
    150                 self.Bind(wx.EVT_MENU, self.onExitCommand, item) 
    151                 menuBar.Append(menu_NVDA,_("&NVDA")) 
    152                 self.sysTrayMenu.AppendMenu(wx.ID_ANY,_("&NVDA"),menu_NVDA) 
    153                 menu_preferences=wx.Menu() 
    154                 item = menu_preferences.Append(wx.ID_ANY,_("&General settings...\tCtrl+Shift+G"),_("General settings")) 
    155                 self.Bind(wx.EVT_MENU, self.onGeneralSettingsCommand, item) 
    156                 item = menu_preferences.Append(wx.ID_ANY,_("&Synthesizer...\tCtrl+Shift+S"),_(" the synthesizer to use")) 
    157                 self.Bind(wx.EVT_MENU, self.onSynthesizerCommand, item) 
    158                 item = menu_preferences.Append(wx.ID_ANY,_("&Voice settings...\tCtrl+Shift+V"),_("Choose the voice, rate, pitch and volume  to use")) 
    159                 self.Bind(wx.EVT_MENU, self.onVoiceCommand, item) 
    160                 item = menu_preferences.Append(wx.ID_ANY,_("&Keyboard Settings...\tCtrl+K"),_("Configure keyboard layout, speaking of typed characters, words or command keys")) 
    161                 self.Bind(wx.EVT_MENU, self.onKeyboardSettingsCommand, item) 
    162                 item = menu_preferences.Append(wx.ID_ANY, _("&Mouse settings...\tCtrl+M"),_("Change reporting of mouse sape, object under mouse")) 
    163                 self.Bind(wx.EVT_MENU, self.onMouseSettingsCommand, item) 
    164                 item = menu_preferences.Append(wx.ID_ANY,_("&Object presentation...\tCtrl+Shift+O"),_("Change reporting of objects"))  
    165                 self.Bind(wx.EVT_MENU, self.onObjectPresentationCommand, item) 
    166                 item = menu_preferences.Append(wx.ID_ANY,_("Virtual &buffers...\tCtrl+Shift+B"),_("Change virtual buffers specific settings"))  
    167                 self.Bind(wx.EVT_MENU, self.onVirtualBuffersCommand, item) 
    168                 item = menu_preferences.Append(wx.ID_ANY,_("Document &formatting...\tCtrl+Shift+F"),_("Change Settings of document properties"))  
    169                 self.Bind(wx.EVT_MENU, self.onDocumentFormattingCommand, item) 
    170                 menuBar.Append(menu_preferences,_("&Preferences")) 
    171                 self.sysTrayMenu.AppendMenu(wx.ID_ANY,_("&Preferences"),menu_preferences) 
    172                 menu_help = wx.Menu() 
    173                 item = menu_help.Append(wx.ID_ANY, _("NVDA homepage"), _("Opens NVDA homepage in the default browser")) 
    174                 self.Bind(wx.EVT_MENU, self.onHomePageCommand, item) 
    175                 item = menu_help.Append(wx.ID_ANY, _("NVDA wiki"), _("Opens NVDA wiki in the default browser")) 
    176                 self.Bind(wx.EVT_MENU, self.onNvdaWikiCommand, item) 
    177                 item = menu_help.Append(wx.ID_ABOUT, _("About..."), _("About NVDA")) 
    178                 self.Bind(wx.EVT_MENU, self.onAboutCommand, item) 
    179                 menuBar.Append(menu_help,_("&Help")) 
    180                 self.sysTrayMenu.AppendMenu(wx.ID_ANY,_("&Help"),menu_help) 
    181                 self.SetMenuBar(menuBar) 
    182                 sizer=wx.BoxSizer(wx.VERTICAL) 
    183                 textCtrl=wx.TextCtrl(self,wx.ID_ANY,size=(500,500),style=wx.TE_RICH2|wx.TE_READONLY|wx.TE_MULTILINE) 
    184                 sizer.Add(textCtrl) 
    185                 sizer.Fit(self) 
    186                 self.SetSizer(sizer) 
    187                 textCtrl.AppendText(quickStartMessage) 
    188                 textCtrl.SetSelection(0,0) 
    189                 icon=wx.Icon(iconPath,wx.BITMAP_TYPE_PNG) 
    190                 self.SetIcon(icon) 
    191                 self.sysTrayButton=wx.TaskBarIcon() 
    192                 self.sysTrayButton.SetIcon(icon,_("NVDA")) 
    193                 self.sysTrayButton.Bind(wx.EVT_TASKBAR_LEFT_DCLICK,self.onShowGuiCommand) 
    194                 self.Center() 
     60                self.sysTrayIcon = SysTrayIcon(self) 
    19561                self.Show(True) 
    196                 if globalVars.appArgs.minimal or config.conf["general"]["hideInterfaceOnStartup"]: 
    197                         self.Show(False) 
     62                self.Show(False) 
     63 
     64        def Destroy(self): 
     65                self.sysTrayIcon.Destroy() 
     66                super(MainFrame, self).Destroy() 
    19867 
    19968        def onAbortCommand(self,evt): 
     
    20170 
    20271        def onShowGuiCommand(self,evt): 
    203                 self.Center() 
    204                 self.Show(True) 
    205                 self.Raise() 
    206                 #self.sysTrayButton.PopupMenu(self.sysTrayMenu) 
    207  
    208         def onHideGuiCommand(self,evt): 
    209                 time.sleep(0.01) 
    210                 self.Show(False) 
     72                self.sysTrayIcon.onActivate(None) 
    21173 
    21274        def onRevertToSavedConfigurationCommand(self,evt): 
     
    22183 
    22284        def onDefaultDictionaryCommand(self,evt): 
    223                 d=DictionaryDialog(self,-1,_("Default dictionary"),userDictHandler.dictionaries["default"]) 
     85                d=DictionaryDialog(None,_("Default dictionary"),userDictHandler.dictionaries["default"]) 
    22486                d.Show(True) 
    22587 
    22688        def onVoiceDictionaryCommand(self,evt): 
    227                 d=DictionaryDialog(self,-1,_("Voice dictionary (%s)")%userDictHandler.dictionaries["voice"].fileName,userDictHandler.dictionaries["voice"]) 
     89                d=DictionaryDialog(None,_("Voice dictionary (%s)")%userDictHandler.dictionaries["voice"].fileName,userDictHandler.dictionaries["voice"]) 
    22890                d.Show(True) 
    22991 
    23092        def onTemporaryDictionaryCommand(self,evt): 
    231                 d=DictionaryDialog(self,-1,_("Temporary dictionary"),userDictHandler.dictionaries["temp"]) 
     93                d=DictionaryDialog(None,_("Temporary dictionary"),userDictHandler.dictionaries["temp"]) 
    23294                d.Show(True) 
    23395 
     
    23597                canExit=False 
    23698                if config.conf["general"]["askToExit"]: 
    237                         wasShown=self.IsShown() 
    238                         if not wasShown: 
    239                                 self.onShowGuiCommand(None) 
    240                         self.Raise() 
    241                         self.SetFocus() 
    242                         d = wx.MessageDialog(self, _("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES|wx.NO|wx.ICON_WARNING) 
     99                        d = wx.MessageDialog(None, _("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES|wx.NO|wx.ICON_WARNING) 
    243100                        if d.ShowModal() == wx.ID_YES: 
    244101                                canExit=True 
    245                         elif not wasShown: 
    246                                 self.onHideGuiCommand(None) 
    247102                else: 
    248103                        canExit=True 
     
    256111 
    257112        def onGeneralSettingsCommand(self,evt): 
    258                 d=generalSettingsDialog(self,-1,_("General settings")) 
     113                d=GeneralSettingsDialog(None) 
    259114                d.Show(True) 
    260115 
    261116        def onSynthesizerCommand(self,evt): 
    262                 d=synthesizerDialog(self,-1,_("Synthesizer")) 
     117                d=SynthesizerDialog(None) 
    263118                d.Show(True) 
    264119 
    265120        def onVoiceCommand(self,evt): 
    266                 d=voiceSettingsDialog(self,-1,_("Voice settings")) 
     121                d=VoiceSettingsDialog(None) 
    267122                d.Show(True) 
    268123 
    269124        def onKeyboardSettingsCommand(self,evt): 
    270                 d=keyboardSettingsDialog(self,-1,_("Keyboard Settings")) 
     125                d=KeyboardSettingsDialog(None) 
    271126                d.Show(True) 
    272127 
    273128        def onMouseSettingsCommand(self,evt): 
    274                 d=mouseSettingsDialog(self,-1,_("Mouse settings")) 
     129                d=MouseSettingsDialog(None) 
    275130                d.Show(True) 
    276131 
    277132        def onObjectPresentationCommand(self,evt): 
    278                 d=objectPresentationDialog(self,-1,_("Object presentation")) 
     133                d=ObjectPresentationDialog(None) 
    279134                d.Show(True) 
    280135 
    281136        def onVirtualBuffersCommand(self,evt): 
    282                 d=virtualBuffersDialog(self,-1,_("virtual buffers")) 
     137                d=VirtualBuffersDialog(None) 
    283138                d.Show(True) 
    284139 
    285140        def onDocumentFormattingCommand(self,evt): 
    286                 d=documentFormattingDialog(self,-1,_("Document formatting")) 
     141                d=DocumentFormattingDialog(None) 
    287142                d.Show(True) 
    288143 
     
    300155%s: %s <%s> 
    301156%s: %s"""%(versionInfo.longName,_("version"),versionInfo.version,_("url"),versionInfo.url,_("maintainer"),versionInfo.maintainer,versionInfo.maintainer_email,_("copyright"),versionInfo.copyrightInfo) 
    302                         d = wx.MessageDialog(self, aboutInfo, _("About NVDA"), wx.OK) 
     157                        d = wx.MessageDialog(None, aboutInfo, _("About NVDA"), wx.OK) 
    303158                        d.ShowModal() 
    304159                except: 
    305160                        globalVars.log.error("gui.mainFrame.onAbout", exc_info=True) 
     161 
     162class SysTrayIcon(wx.TaskBarIcon): 
     163 
     164        def __init__(self, frame): 
     165                super(SysTrayIcon, self).__init__() 
     166                icon=wx.Icon(iconPath,wx.BITMAP_TYPE_PNG) 
     167                self.SetIcon(icon, appTitle) 
     168 
     169                self.menu=wx.Menu() 
     170                menu_preferences=wx.Menu() 
     171                item = menu_preferences.Append(wx.ID_ANY,_("&General settings..."),_("General settings")) 
     172                self.Bind(wx.EVT_MENU, frame.onGeneralSettingsCommand, item) 
     173                item = menu_preferences.Append(wx.ID_ANY,_("&Synthesizer..."),_(" the synthesizer to use")) 
     174                self.Bind(wx.EVT_MENU, frame.onSynthesizerCommand, item) 
     175                item = menu_preferences.Append(wx.ID_ANY,_("&Voice settings..."),_("Choose the voice, rate, pitch and volume  to use")) 
     176                self.Bind(wx.EVT_MENU, frame.onVoiceCommand, item) 
     177                item = menu_preferences.Append(wx.ID_ANY,_("&Keyboard Settings..."),_("Configure keyboard layout, speaking of typed characters, words or command keys")) 
     178                self.Bind(wx.EVT_MENU, frame.onKeyboardSettingsCommand, item) 
     179                item = menu_preferences.Append(wx.ID_ANY, _("&Mouse settings..."),_("Change reporting of mouse sape, object under mouse")) 
     180                self.Bind(wx.EVT_MENU, frame.onMouseSettingsCommand, item) 
     181                item = menu_preferences.Append(wx.ID_ANY,_("&Object presentation..."),_("Change reporting of objects"))  
     182                self.Bind(wx.EVT_MENU, frame.onObjectPresentationCommand, item) 
     183                item = menu_preferences.Append(wx.ID_ANY,_("Virtual &buffers..."),_("Change virtual buffers specific settings"))  
     184                self.Bind(wx.EVT_MENU, frame.onVirtualBuffersCommand, item) 
     185                item = menu_preferences.Append(wx.ID_ANY,_("Document &formatting..."),_("Change Settings of document properties"))  
     186                self.Bind(wx.EVT_MENU, frame.onDocumentFormattingCommand, item) 
     187                subMenu_userDicts = wx.Menu() 
     188                item = subMenu_userDicts.Append(wx.ID_ANY,_("&Default dictionary..."),_("dialog where you can set default dictionary by adding dictionary entries to the list")) 
     189                self.Bind(wx.EVT_MENU, frame.onDefaultDictionaryCommand, item) 
     190                item = subMenu_userDicts.Append(wx.ID_ANY,_("&Voice dictionary..."),_("dialog where you can set voice-specific dictionary by adding dictionary entries to the list")) 
     191                self.Bind(wx.EVT_MENU, frame.onVoiceDictionaryCommand, item) 
     192                item = subMenu_userDicts.Append(wx.ID_ANY,_("&Temporary dictionary..."),_("dialog where you can set temporary dictionary by adding dictionary entries to the edit box")) 
     193                self.Bind(wx.EVT_MENU, frame.onTemporaryDictionaryCommand, item) 
     194                menu_preferences.AppendMenu(wx.ID_ANY,_("User &dictionaries"),subMenu_userDicts) 
     195                self.menu.AppendMenu(wx.ID_ANY,_("&Preferences"),menu_preferences) 
     196                menu_help = wx.Menu() 
     197                item = menu_help.Append(wx.ID_ANY, _("NVDA homepage"), _("Opens NVDA homepage in the default browser")) 
     198                self.Bind(wx.EVT_MENU, frame.onHomePageCommand, item) 
     199                item = menu_help.Append(wx.ID_ANY, _("NVDA wiki"), _("Opens NVDA wiki in the default browser")) 
     200                self.Bind(wx.EVT_MENU, frame.onNvdaWikiCommand, item) 
     201                item = menu_help.Append(wx.ID_ABOUT, _("About..."), _("About NVDA")) 
     202                self.Bind(wx.EVT_MENU, frame.onAboutCommand, item) 
     203                self.menu.AppendMenu(wx.ID_ANY,_("&Help"),menu_help) 
     204                self.menu.AppendSeparator() 
     205                item = self.menu.Append(wx.ID_ANY, _("&Revert to saved configuration"),_("Reset all settings to saved state")) 
     206                self.Bind(wx.EVT_MENU, frame.onRevertToSavedConfigurationCommand, item) 
     207                item = self.menu.Append(wx.ID_SAVE, _("&Save configuration"), _("Write the current configuration to nvda.ini")) 
     208                self.Bind(wx.EVT_MENU, frame.onSaveConfigurationCommand, item) 
     209                self.menu.AppendSeparator() 
     210                item = self.menu.Append(wx.ID_EXIT, _("E&xit"),_("Exit NVDA")) 
     211                self.Bind(wx.EVT_MENU, frame.onExitCommand, item) 
     212 
     213                self.Bind(wx.EVT_TASKBAR_RIGHT_UP, self.onActivate) 
     214 
     215        def Destroy(self): 
     216                self.menu.Destroy() 
     217                super(SysTrayIcon, self).Destroy() 
     218 
     219        def onActivate(self, evt): 
     220                self.PopupMenu(self.menu) 
     221                # Showing and hiding our main frame seems to cause Windows to switch to the previous foreground window. 
     222                # If we don't do this and no dialog was displayed, the user will be dumped in the invisible system tray window, which is bad. 
     223                # It is even worse than expected because the user can close the system tray window, breaking the system tray icon. 
     224                # Even if a dialog is displayed, this does no harm. 
     225                mainFrame.Show() 
     226                mainFrame.Hide() 
    306227 
    307228def initialize(app): 
  • trunk/source/gui/settingsDialogs.py

    r1738 r1745  
    3333        ] 
    3434 
    35 class generalSettingsDialog(wx.Dialog): 
    36  
    37         def __init__(self,parent,ID,title): 
    38                 wx.Dialog.__init__(self,parent,ID,title) 
     35class SettingsDialog(wx.Dialog): 
     36        """A settings dialog. 
     37        A settings dialog consists of one or more settings controls and OK and Cancel buttons. 
     38        Action may be taken in response to the OK or Cancel buttons. 
     39 
     40        To use this dialog: 
     41                * Set L{title} to the title of the dialog. 
     42                * Override L{makeSettings} to populate a given sizer with the settings controls. 
     43                * Optionally, override L{postInit} to perform actions after the dialog is created, such as setting the focus. 
     44                * Optionally, extend one or both of L{onOk} or L{onCancel} to perform actions in response to the OK or Cancel buttons, respectively. 
     45 
     46        @ivar title: The title of the dialog. 
     47        @type title: str 
     48        """ 
     49        title = "" 
     50 
     51        def __init__(self, parent): 
     52                """ 
     53                @param parent: The parent for this dialog; C{None} for no parent. 
     54                @type parent: wx.Window 
     55                """ 
     56                super(SettingsDialog, self).__init__(parent, wx.ID_ANY, self.title) 
    3957                mainSizer=wx.BoxSizer(wx.VERTICAL) 
    4058                settingsSizer=wx.BoxSizer(wx.VERTICAL) 
     59                self.makeSettings(settingsSizer) 
     60                mainSizer.Add(settingsSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.TOP) 
     61                buttonSizer=self.CreateButtonSizer(wx.OK|wx.CANCEL) 
     62                mainSizer.Add(buttonSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.BOTTOM) 
     63                mainSizer.Fit(self) 
     64                self.SetSizer(mainSizer) 
     65                self.Bind(wx.EVT_BUTTON,self.onOk,id=wx.ID_OK) 
     66                self.Bind(wx.EVT_BUTTON,self.onCancel,id=wx.ID_CANCEL) 
     67                self.postInit() 
     68 
     69        def makeSettings(self, sizer): 
     70                """Populate the dialog with settings controls. 
     71                Subclasses must override this method. 
     72                @param sizer: The sizer to which to add the settings controls. 
     73                @type sizer: wx.Sizer 
     74                """ 
     75                raise NotImplementedError 
     76 
     77        def postInit(self): 
     78                """Called after the dialog has been created. 
     79                For example, this might be used to set focus to the desired control. 
     80                Sub-classes may override this method. 
     81                """ 
     82 
     83        def onOk(self, evt): 
     84                """Take action in response to the OK button being pressed. 
     85                Sub-classes may extend this method. 
     86                This base method should always be called to clean up the dialog. 
     87                """ 
     88                self.Destroy() 
     89 
     90        def onCancel(self, evt): 
     91                """Take action in response to the Cancel button being pressed. 
     92                Sub-classes may extend this method. 
     93                This base method should always be called to clean up the dialog. 
     94                """ 
     95                self.Destroy() 
     96 
     97class GeneralSettingsDialog(SettingsDialog): 
     98        title = _("General settings") 
     99 
     100        def makeSettings(self, settingsSizer): 
    41101                languageSizer=wx.BoxSizer(wx.HORIZONTAL) 
    42102                languageLabel=wx.StaticText(self,-1,label=_("&Language (requires restart to fully take affect)")) 
     
    75135                logLevelSizer.Add(self.logLevelList) 
    76136                settingsSizer.Add(logLevelSizer,border=10,flag=wx.BOTTOM) 
    77                 mainSizer.Add(settingsSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.TOP) 
    78                 buttonSizer=self.CreateButtonSizer(wx.OK|wx.CANCEL) 
    79                 mainSizer.Add(buttonSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.BOTTOM) 
    80                 mainSizer.Fit(self) 
    81                 self.SetSizer(mainSizer) 
    82                 self.Bind(wx.EVT_BUTTON,self.onOk,id=wx.ID_OK) 
     137 
     138        def postInit(self): 
    83139                self.languageList.SetFocus() 
    84140 
     
    103159                                config.save() 
    104160                                queueHandler.queueFunction(queueHandler.interactiveQueue,gui.restart) 
    105                 self.Destroy() 
    106  
    107 class synthesizerDialog(wx.Dialog): 
    108  
    109         def __init__(self,parent,ID,title): 
    110                 wx.Dialog.__init__(self,parent,ID,title) 
    111                 mainSizer=wx.BoxSizer(wx.VERTICAL) 
    112                 settingsSizer=wx.BoxSizer(wx.VERTICAL) 
     161                super(GeneralSettingsDialog, self).onOk(evt) 
     162 
     163class SynthesizerDialog(SettingsDialog): 
     164        title = _("Synthesizer") 
     165 
     166        def makeSettings(self, settingsSizer): 
    113167                synthListSizer=wx.BoxSizer(wx.HORIZONTAL) 
    114168                synthListLabel=wx.StaticText(self,-1,label=_("&Synthesizer")) 
     
    149203                deviceListSizer.Add(self.deviceList) 
    150204                settingsSizer.Add(deviceListSizer,border=10,flag=wx.BOTTOM) 
    151                 mainSizer.Add(settingsSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.TOP) 
    152                 buttonSizer=wx.BoxSizer(wx.HORIZONTAL) 
    153                 buttonSizer=self.CreateButtonSizer(wx.OK|wx.CANCEL) 
    154                 mainSizer.Add(buttonSizer,border=20,flag=wx.LEFT|wx.RIGHT|wx.BOTTOM) 
    155                 mainSizer.Fit(self) 
    156                 self.SetSizer(mainSizer) 
    157                 self.Bind(wx.EVT_BUTTON,self.onOk,id=wx.ID_OK) 
     205 
     206        def postInit(self): 
    158207                self.synthList.SetFocus() 
    159208 
     
    164213                        wx.MessageDialog(self,_("Could not load the %s synthesizer.")%newSynth,_("Synthesizer Error"),wx.OK|wx.ICON_WARNING).ShowModal() 
    165214                        return  
    166                 self.Destroy() 
    167  
    168 class voiceSettingsDialog(wx.Dialog): 
    169  
    170         def __init__(self,parent,ID,title): 
    171                 wx.Dialog.__init__(self,parent,ID,title) 
    172                 mainSizer=wx.BoxSizer(wx.VERTICAL) 
    173                 settingsSizer=wx.BoxSizer(wx.VERTICAL) 
     215                super(SynthesizerDialog, self).onOk(evt) 
     216 
     217class VoiceSettingsDialog(SettingsDialog): 
     218        title = _("Voice settings") 
     219 
     220        def makeSettings(self, settingsSizer): 
    174221                if getSynth().hasVoice: 
    175222                        voiceListSizer=wx.BoxSizer(wx.HORIZONTAL) 
     
    250297