1
2
3
4
5
6
7 import time
8 import os
9 import sys
10 import wx
11 import globalVars
12 import ui
13 from logHandler import log
14 import config
15 import versionInfo
16 import speech
17 import queueHandler
18 import core
19 from settingsDialogs import *
20 import speechDictHandler
21 import languageHandler
22 import logViewer
23 import speechViewer
24 import winUser
25 import api
26
27
28 NVDA_PATH = os.getcwdu()
29 ICON_PATH=os.path.join(NVDA_PATH, "images", "nvda.ico")
30
31
32 mainFrame = None
33 isInMessageBox = False
36 if not getDocFilePath.rootPath:
37 if hasattr(sys, "frozen"):
38 getDocFilePath.rootPath = os.path.join(NVDA_PATH, "documentation")
39 else:
40 getDocFilePath.rootPath = os.path.abspath(os.path.join("..", "user_docs"))
41
42 if localized:
43 lang = languageHandler.getLanguage()
44 tryLangs = [lang]
45 if "_" in lang:
46
47 tryLangs.append(lang.split("_")[0])
48
49 tryLangs.append("en")
50
51 fileName, fileExt = os.path.splitext(fileName)
52 for tryLang in tryLangs:
53 tryDir = os.path.join(getDocFilePath.rootPath, tryLang)
54 if not os.path.isdir(tryDir):
55 continue
56
57
58
59 for tryExt in ("html", "txt"):
60 tryPath = os.path.join(tryDir, "%s.%s" % (fileName, tryExt))
61 if os.path.isfile(tryPath):
62 return tryPath
63
64 else:
65
66 if not hasattr(sys, "frozen") and fileName in ("copying.txt", "contributors.txt"):
67
68 return os.path.join(NVDA_PATH, "..", fileName)
69 else:
70 return os.path.join(getDocFilePath.rootPath, fileName)
71 getDocFilePath.rootPath = None
72
73 -class MainFrame(wx.Frame):
74
76 style = wx.DEFAULT_FRAME_STYLE ^ wx.MAXIMIZE_BOX ^ wx.MINIMIZE_BOX | wx.FRAME_NO_TASKBAR
77 super(MainFrame, self).__init__(None, wx.ID_ANY, versionInfo.name, size=(1,1), style=style)
78 self.Bind(wx.EVT_CLOSE, self.onExitCommand)
79 self.sysTrayIcon = SysTrayIcon(self)
80
81 self.Show()
82 self.Hide()
83 if winUser.isWindowVisible(self.Handle):
84
85
86
87 self.Show()
88 self.Hide()
89
91 self.sysTrayIcon.Destroy()
92 super(MainFrame, self).Destroy()
93
95 """Prepare for a popup.
96 This should be called before any dialog or menu which should pop up for the user.
97 L{postPopup} should be called after the dialog or menu has been shown.
98 @postcondition: A dialog or menu may be shown.
99 """
100 if winUser.getWindowThreadProcessID(winUser.getForegroundWindow())[0] != os.getpid():
101
102 self.Raise()
103
104 - def postPopup(self):
105 """Clean up after a popup dialog or menu.
106 This should be called after a dialog or menu was popped up for the user.
107 """
108 if not winUser.isWindowVisible(winUser.getForegroundWindow()):
109
110
111 self.Show()
112 self.Hide()
113
115
116
117 left, top, width, height = api.getDesktopObject().location
118 x = width / 2
119 y = height / 2
120 winUser.setCursorPos(x, y)
121 self.sysTrayIcon.onActivate(None)
122
126
128 if globalVars.appArgs.secure:
129 queueHandler.queueFunction(queueHandler.eventQueue,ui.message,_("Cannot save configuration - NVDA in secure mode"))
130 return
131 try:
132 config.save()
133 queueHandler.queueFunction(queueHandler.eventQueue,ui.message,_("configuration saved"))
134 except:
135 messageBox(_("Could not save configuration - probably read only file system"),_("Error"),wx.OK | wx.ICON_ERROR)
136
137 - def _popupSettingsDialog(self, dialog, *args, **kwargs):
138 if isInMessageBox:
139 return
140 self.prePopup()
141 try:
142 dialog(self, *args, **kwargs).Show()
143 except SettingsDialog.MultiInstanceError:
144 messageBox(_("Please close the other NVDA settings dialog first"),_("Error"),style=wx.OK | wx.ICON_ERROR)
145 self.postPopup()
146
149
152
155
156 - def onExitCommand(self, evt):
157 canExit=False
158 if config.conf["general"]["askToExit"]:
159 if isInMessageBox:
160 return
161 if messageBox(_("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES_NO|wx.ICON_WARNING) == wx.YES:
162 canExit=True
163 else:
164 canExit=True
165 if canExit:
166 wx.GetApp().ExitMainLoop()
167
170
173
174 - def onVoiceCommand(self,evt):
176
177 - def onBrailleCommand(self,evt):
179
182
185
188
191
192 - def onBrowseModeCommand(self,evt):
194
197
200
201 - def onAboutCommand(self,evt):
203
204 - def onViewLogCommand(self, evt):
206
208 if not speechViewer.isActive:
209 speechViewer.activate()
210 self.sysTrayIcon.menu_tools_toggleSpeechViewer.Check(True)
211 else:
212 speechViewer.deactivate()
213 self.sysTrayIcon.menu_tools_toggleSpeechViewer.Check(False)
214
220
227
229
231 super(SysTrayIcon, self).__init__()
232 icon=wx.Icon(ICON_PATH,wx.BITMAP_TYPE_ICO)
233 self.SetIcon(icon, versionInfo.name)
234
235 self.menu=wx.Menu()
236 menu_preferences=wx.Menu()
237 item = menu_preferences.Append(wx.ID_ANY,_("&General settings..."),_("General settings"))
238 self.Bind(wx.EVT_MENU, frame.onGeneralSettingsCommand, item)
239 item = menu_preferences.Append(wx.ID_ANY,_("&Synthesizer..."),_(" the synthesizer to use"))
240 self.Bind(wx.EVT_MENU, frame.onSynthesizerCommand, item)
241 item = menu_preferences.Append(wx.ID_ANY,_("&Voice settings..."),_("Choose the voice, rate, pitch and volume to use"))
242 self.Bind(wx.EVT_MENU, frame.onVoiceCommand, item)
243 item = menu_preferences.Append(wx.ID_ANY,_("B&raille settings..."))
244 self.Bind(wx.EVT_MENU, frame.onBrailleCommand, item)
245 item = menu_preferences.Append(wx.ID_ANY,_("&Keyboard Settings..."),_("Configure keyboard layout, speaking of typed characters, words or command keys"))
246 self.Bind(wx.EVT_MENU, frame.onKeyboardSettingsCommand, item)
247 item = menu_preferences.Append(wx.ID_ANY, _("&Mouse settings..."),_("Change reporting of mouse shape and object under mouse"))
248 self.Bind(wx.EVT_MENU, frame.onMouseSettingsCommand, item)
249 item = menu_preferences.Append(wx.ID_ANY,_("Review &cursor..."),_("Configure how and when the review cursor moves"))
250 self.Bind(wx.EVT_MENU, frame.onReviewCursorCommand, item)
251 item = menu_preferences.Append(wx.ID_ANY,_("&Object presentation..."),_("Change reporting of objects"))
252 self.Bind(wx.EVT_MENU, frame.onObjectPresentationCommand, item)
253 item = menu_preferences.Append(wx.ID_ANY,_("&Browse mode..."),_("Change virtual buffers specific settings"))
254 self.Bind(wx.EVT_MENU, frame.onBrowseModeCommand, item)
255 item = menu_preferences.Append(wx.ID_ANY,_("Document &formatting..."),_("Change Settings of document properties"))
256 self.Bind(wx.EVT_MENU, frame.onDocumentFormattingCommand, item)
257 subMenu_speechDicts = wx.Menu()
258 if not globalVars.appArgs.secure:
259 item = subMenu_speechDicts.Append(wx.ID_ANY,_("&Default dictionary..."),_("dialog where you can set default dictionary by adding dictionary entries to the list"))
260 self.Bind(wx.EVT_MENU, frame.onDefaultDictionaryCommand, item)
261 item = subMenu_speechDicts.Append(wx.ID_ANY,_("&Voice dictionary..."),_("dialog where you can set voice-specific dictionary by adding dictionary entries to the list"))
262 self.Bind(wx.EVT_MENU, frame.onVoiceDictionaryCommand, item)
263 item = subMenu_speechDicts.Append(wx.ID_ANY,_("&Temporary dictionary..."),_("dialog where you can set temporary dictionary by adding dictionary entries to the edit box"))
264 self.Bind(wx.EVT_MENU, frame.onTemporaryDictionaryCommand, item)
265 menu_preferences.AppendMenu(wx.ID_ANY,_("Speech &dictionaries"),subMenu_speechDicts)
266 if not globalVars.appArgs.secure:
267 item = menu_preferences.Append(wx.ID_ANY, _("&Punctuation/symbol pronunciation..."))
268 self.Bind(wx.EVT_MENU, frame.onSpeechSymbolsCommand, item)
269 self.menu.AppendMenu(wx.ID_ANY,_("&Preferences"),menu_preferences)
270
271 menu_tools = wx.Menu()
272 if not globalVars.appArgs.secure:
273 item = menu_tools.Append(wx.ID_ANY, _("View log"))
274 self.Bind(wx.EVT_MENU, frame.onViewLogCommand, item)
275 item=self.menu_tools_toggleSpeechViewer = menu_tools.AppendCheckItem(wx.ID_ANY, _("Speech viewer"))
276 self.Bind(wx.EVT_MENU, frame.onToggleSpeechViewerCommand, item)
277 if not globalVars.appArgs.secure:
278 item = menu_tools.Append(wx.ID_ANY, _("Python console"))
279 self.Bind(wx.EVT_MENU, frame.onPythonConsoleCommand, item)
280 item = menu_tools.Append(wx.ID_ANY, _("Reload plugins"))
281 self.Bind(wx.EVT_MENU, frame.onReloadPluginsCommand, item)
282 self.menu.AppendMenu(wx.ID_ANY, _("Tools"), menu_tools)
283
284 menu_help = wx.Menu()
285 if not globalVars.appArgs.secure:
286 item = menu_help.Append(wx.ID_ANY, _("User guide"))
287 self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("userGuide.html")), item)
288 item = menu_help.Append(wx.ID_ANY, _("Keyboard Command Quick Reference"))
289 self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("keyCommands.html")), item)
290 item = menu_help.Append(wx.ID_ANY, _("What's &new"))
291 self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("changes.html")), item)
292 item = menu_help.Append(wx.ID_ANY, _("Web site"))
293 self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://www.nvda-project.org/"), item)
294 item = menu_help.Append(wx.ID_ANY, _("License"))
295 self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("copying.txt", False)), item)
296 item = menu_help.Append(wx.ID_ANY, _("Contributors"))
297 self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("contributors.txt", False)), item)
298 item = menu_help.Append(wx.ID_ANY, _("We&lcome dialog"))
299 self.Bind(wx.EVT_MENU, lambda evt: WelcomeDialog.run(), item)
300 menu_help.AppendSeparator()
301 item = menu_help.Append(wx.ID_ABOUT, _("About..."), _("About NVDA"))
302 self.Bind(wx.EVT_MENU, frame.onAboutCommand, item)
303 self.menu.AppendMenu(wx.ID_ANY,_("&Help"),menu_help)
304 self.menu.AppendSeparator()
305 item = self.menu.Append(wx.ID_ANY, _("&Revert to saved configuration"),_("Reset all settings to saved state"))
306 self.Bind(wx.EVT_MENU, frame.onRevertToSavedConfigurationCommand, item)
307 if not globalVars.appArgs.secure:
308 item = self.menu.Append(wx.ID_SAVE, _("&Save configuration"), _("Write the current configuration to nvda.ini"))
309 self.Bind(wx.EVT_MENU, frame.onSaveConfigurationCommand, item)
310 if not globalVars.appArgs.secure:
311 self.menu.AppendSeparator()
312 item = self.menu.Append(wx.ID_ANY, _("Donate"))
313 self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://www.nvaccess.org/wiki/Donate"), item)
314 self.menu.AppendSeparator()
315 item = self.menu.Append(wx.ID_EXIT, _("E&xit"),_("Exit NVDA"))
316 self.Bind(wx.EVT_MENU, frame.onExitCommand, item)
317
318 self.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.onActivate)
319
323
328
333
337
340
343
344 -def messageBox(message, caption=wx.MessageBoxCaptionStr, style=wx.OK | wx.CENTER, parent=None):
345 """Display a message dialog.
346 This should be used for all message dialogs
347 rather than using C{wx.MessageDialog} and C{wx.MessageBox} directly.
348 @param message: The message text.
349 @type message: str
350 @param caption: The caption (title) of the dialog.
351 @type caption: str
352 @param style: Same as for wx.MessageBox.
353 @type style: int
354 @param parent: The parent window (optional).
355 @type parent: C{wx.Window}
356 @return: Same as for wx.MessageBox.
357 @rtype: int
358 """
359 global isInMessageBox
360 wasAlready = isInMessageBox
361 isInMessageBox = True
362 if not parent:
363 mainFrame.prePopup()
364 res = wx.MessageBox(message, caption, style, parent or mainFrame)
365 if not parent:
366 mainFrame.postPopup()
367 if not wasAlready:
368 isInMessageBox = False
369 return res
370
372 """Run a modal dialog from a script.
373 This will not block the caller,
374 but will instead call C{callback} (if provided) with the result from the dialog.
375 The dialog will be destroyed once the callback has returned.
376 @param dialog: The dialog to show.
377 @type dialog: C{wx.Dialog}
378 @param callback: The optional callable to call with the result from the dialog.
379 @type callback: callable
380 """
381 def run():
382 mainFrame.prePopup()
383 res = dialog.ShowModal()
384 mainFrame.postPopup()
385 if callback:
386 callback(res)
387 dialog.Destroy()
388 wx.CallAfter(run)
389
445
447 """A configuration file error dialog.
448 This dialog tells the user that their configuration file is broken.
449 """
450
451 MESSAGE=_("""Your configuration file contains errors.
452 Press 'Ok' to fix these errors, or press 'Cancel' if you wish to manually edit your config file at a later stage to make corrections. More details about the errors can be found in the log file.
453 """)
454
456 super(ConfigFileErrorDialog, self).__init__(parent, wx.ID_ANY, _("Configuration File Error"))
457 mainSizer=wx.BoxSizer(wx.VERTICAL)
458 messageText = wx.StaticText(self, wx.ID_ANY, self.MESSAGE)
459 mainSizer.Add(messageText,border=20,flag=wx.LEFT|wx.RIGHT|wx.TOP)
460 mainSizer.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL),flag=wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER_HORIZONTAL,border=20)
461 self.Bind(wx.EVT_BUTTON, self.onOk, id=wx.ID_OK)
462 self.SetSizer(mainSizer)
463 mainSizer.Fit(self)
464
465 - def onOk(self, evt):
469
470 @classmethod
480