30
28
NVDA_PATH = os.getcwdu()
31
ICON_PATH=os.path.join(NVDA_PATH, "images", "nvda.ico")
33
ExternalCommandEvent, evt_externalCommand = newevent.NewCommandEvent()
34
id_showGuiCommand=wx.NewId()
35
evtid_externalExecute = wx.NewEventType()
36
evt_externalExecute = wx.PyEventBinder(evtid_externalExecute, 1)
29
ICON_PATH=os.path.join(NVDA_PATH, "images", "nvdajp.ico")
41
#: A list of top level windows excluding L{mainFrame} which are currently instantiated and which should be destroyed on exit.
43
class ExternalExecuteEvent(wx.PyCommandEvent):
44
def __init__(self, func, args, kwargs, callback):
45
super(ExternalExecuteEvent, self).__init__(evtid_externalExecute, wx.ID_ANY)
49
self._callback = callback
52
ret = self._func(*self._args, **self._kwargs)
54
queueHandler.registerGeneratorObject(self._callback_gen(ret))
56
def _callback_gen(self, ret):
33
isInMessageBox = False
61
35
def getDocFilePath(fileName, localized=True):
62
36
if not getDocFilePath.rootPath:
101
75
def __init__(self):
102
76
style = wx.DEFAULT_FRAME_STYLE ^ wx.MAXIMIZE_BOX ^ wx.MINIMIZE_BOX | wx.FRAME_NO_TASKBAR
103
super(MainFrame, self).__init__(None, wx.ID_ANY, appTitle, size=(1,1), style=style)
77
super(MainFrame, self).__init__(None, wx.ID_ANY, versionInfo.name, size=(1,1), style=style)
104
78
self.Bind(wx.EVT_CLOSE, self.onExitCommand)
105
self.Bind(evt_externalCommand, self.onExitCommand, id=wx.ID_EXIT)
106
self.Bind(evt_externalCommand, self.onShowGuiCommand, id=id_showGuiCommand)
107
self.Bind(evt_externalExecute,lambda evt: evt.run())
108
79
self.sysTrayIcon = SysTrayIcon(self)
109
80
# This makes Windows return to the previous foreground window and also seems to allow NVDA to be brought to the foreground.
83
if winUser.isWindowVisible(self.Handle):
84
# HACK: Work around a wx bug where Hide() doesn't actually hide the window,
85
# but IsShown() returns False and Hide() again doesn't fix it.
86
# This seems to happen if the call takes too long.
113
90
def Destroy(self):
114
91
self.sysTrayIcon.Destroy()
148
125
queueHandler.queueFunction(queueHandler.eventQueue,ui.message,_("configuration applied"))
150
127
def onSaveConfigurationCommand(self,evt):
128
if globalVars.appArgs.secure:
129
queueHandler.queueFunction(queueHandler.eventQueue,ui.message,_("Cannot save configuration - NVDA in secure mode"))
153
133
queueHandler.queueFunction(queueHandler.eventQueue,ui.message,_("configuration saved"))
156
d = wx.MessageDialog(self,_("Could not save configuration - probably read only file system"),_("Error"),style=wx.OK | wx.ICON_ERROR)
135
messageBox(_("Could not save configuration - probably read only file system"),_("Error"),wx.OK | wx.ICON_ERROR)
161
137
def _popupSettingsDialog(self, dialog, *args, **kwargs):
163
dialog(self, *args, **kwargs).Show()
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)
166
147
def onDefaultDictionaryCommand(self,evt):
173
154
self._popupSettingsDialog(DictionaryDialog,_("Temporary dictionary"),speechDictHandler.dictionaries["temp"])
175
156
def onExitCommand(self, evt):
178
158
if config.conf["general"]["askToExit"]:
181
d = wx.MessageDialog(self, _("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES|wx.NO|wx.ICON_WARNING)
182
if d.ShowModal() == wx.ID_YES:
161
if messageBox(_("Are you sure you want to quit NVDA?"), _("Exit NVDA"), wx.YES_NO|wx.ICON_WARNING) == wx.YES:
213
189
def onObjectPresentationCommand(self,evt):
214
190
self._popupSettingsDialog(ObjectPresentationDialog)
216
def onVirtualBuffersCommand(self,evt):
217
self._popupSettingsDialog(VirtualBuffersDialog)
192
def onBrowseModeCommand(self,evt):
193
self._popupSettingsDialog(BrowseModeDialog)
219
195
def onDocumentFormattingCommand(self,evt):
220
196
self._popupSettingsDialog(DocumentFormattingDialog)
198
def onSpeechSymbolsCommand(self, evt):
199
self._popupSettingsDialog(SpeechSymbolsDialog)
222
201
def onAboutCommand(self,evt):
227
%s: %s"""%(versionInfo.longName,_("version"),versionInfo.version,_("url"),versionInfo.url,_("copyright"),versionInfo.copyrightInfo)
229
d = wx.MessageDialog(self, aboutInfo, _("About NVDA"), wx.OK)
234
log.error("gui.mainFrame.onAbout", exc_info=True)
202
messageBox(versionInfo.aboutMessage, _("About NVDA"), wx.OK)
236
204
def onViewLogCommand(self, evt):
237
205
logViewer.activate()
250
218
pythonConsole.initialize()
251
219
pythonConsole.activate()
221
def onReloadPluginsCommand(self, evt):
222
import appModuleHandler, globalPluginHandler
223
from NVDAObjects import NVDAObject
224
appModuleHandler.reloadAppModules()
225
globalPluginHandler.reloadGlobalPlugins()
226
NVDAObject.clearDynamicClassCache()
253
228
class SysTrayIcon(wx.TaskBarIcon):
255
230
def __init__(self, frame):
256
231
super(SysTrayIcon, self).__init__()
257
232
icon=wx.Icon(ICON_PATH,wx.BITMAP_TYPE_ICO)
258
self.SetIcon(icon, appTitle)
233
self.SetIcon(icon, versionInfo.name)
260
235
self.menu=wx.Menu()
261
236
menu_preferences=wx.Menu()
271
246
self.Bind(wx.EVT_MENU, frame.onKeyboardSettingsCommand, item)
272
247
item = menu_preferences.Append(wx.ID_ANY, _("&Mouse settings..."),_("Change reporting of mouse shape and object under mouse"))
273
248
self.Bind(wx.EVT_MENU, frame.onMouseSettingsCommand, item)
274
item = menu_preferences.Append(wx.ID_ANY,_("&Review cursor..."),_("Configure how and when the review cursor moves"))
249
item = menu_preferences.Append(wx.ID_ANY,_("Review &cursor..."),_("Configure how and when the review cursor moves"))
275
250
self.Bind(wx.EVT_MENU, frame.onReviewCursorCommand, item)
276
item = menu_preferences.Append(wx.ID_ANY,_("&Object presentation..."),_("Change reporting of objects"))
251
item = menu_preferences.Append(wx.ID_ANY,_("&Object presentation..."),_("Change reporting of objects"))
277
252
self.Bind(wx.EVT_MENU, frame.onObjectPresentationCommand, item)
278
item = menu_preferences.Append(wx.ID_ANY,_("Virtual &buffers..."),_("Change virtual buffers specific settings"))
279
self.Bind(wx.EVT_MENU, frame.onVirtualBuffersCommand, item)
280
item = menu_preferences.Append(wx.ID_ANY,_("Document &formatting..."),_("Change Settings of document properties"))
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"))
281
256
self.Bind(wx.EVT_MENU, frame.onDocumentFormattingCommand, item)
282
257
subMenu_speechDicts = wx.Menu()
283
item = subMenu_speechDicts.Append(wx.ID_ANY,_("&Default dictionary..."),_("dialog where you can set default dictionary by adding dictionary entries to the list"))
284
self.Bind(wx.EVT_MENU, frame.onDefaultDictionaryCommand, item)
285
item = subMenu_speechDicts.Append(wx.ID_ANY,_("&Voice dictionary..."),_("dialog where you can set voice-specific dictionary by adding dictionary entries to the list"))
286
self.Bind(wx.EVT_MENU, frame.onVoiceDictionaryCommand, item)
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)
287
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"))
288
264
self.Bind(wx.EVT_MENU, frame.onTemporaryDictionaryCommand, item)
289
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)
290
269
self.menu.AppendMenu(wx.ID_ANY,_("&Preferences"),menu_preferences)
292
271
menu_tools = wx.Menu()
298
277
if not globalVars.appArgs.secure:
299
278
item = menu_tools.Append(wx.ID_ANY, _("Python console"))
300
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)
301
282
self.menu.AppendMenu(wx.ID_ANY, _("Tools"), menu_tools)
303
284
menu_help = wx.Menu()
304
285
if not globalVars.appArgs.secure:
305
286
item = menu_help.Append(wx.ID_ANY, _("User guide"))
306
287
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("userGuide.html")), item)
307
item = menu_help.Append(wx.ID_ANY, _("Key Command Quick Reference"))
308
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("key commands.txt")), 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)
309
290
item = menu_help.Append(wx.ID_ANY, _("What's &new"))
310
291
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("changes.html")), item)
311
292
item = menu_help.Append(wx.ID_ANY, _("Web site"))
312
self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://www.nvda-project.org/"), item)
313
item = menu_help.Append(wx.ID_ANY, _("Readme"))
314
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("readme.txt")), item)
293
# self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://www.nvda-project.org/"), item)
294
self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://sourceforge.jp/projects/nvdajp/"), item) #nvdajp
295
item = menu_help.Append(wx.ID_ANY, _("Readme")) #nvdajp
296
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("readme.txt")), item) #nvdajp
315
297
item = menu_help.Append(wx.ID_ANY, _("License"))
316
298
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("copying.txt", False)), item)
317
299
item = menu_help.Append(wx.ID_ANY, _("Contributors"))
318
self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("contributors.txt", False)), item)
300
# self.Bind(wx.EVT_MENU, lambda evt: os.startfile(getDocFilePath("contributors.txt", False)), item)
301
self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://sourceforge.jp/projects/nvdajp/wiki/contributors_ja"), item) #nvdajp
319
302
item = menu_help.Append(wx.ID_ANY, _("We&lcome dialog"))
320
303
self.Bind(wx.EVT_MENU, lambda evt: WelcomeDialog.run(), item)
321
304
menu_help.AppendSeparator()
325
308
self.menu.AppendSeparator()
326
309
item = self.menu.Append(wx.ID_ANY, _("&Revert to saved configuration"),_("Reset all settings to saved state"))
327
310
self.Bind(wx.EVT_MENU, frame.onRevertToSavedConfigurationCommand, item)
328
item = self.menu.Append(wx.ID_SAVE, _("&Save configuration"), _("Write the current configuration to nvda.ini"))
329
self.Bind(wx.EVT_MENU, frame.onSaveConfigurationCommand, item)
311
if not globalVars.appArgs.secure:
312
item = self.menu.Append(wx.ID_SAVE, _("&Save configuration"), _("Write the current configuration to nvda.ini"))
313
self.Bind(wx.EVT_MENU, frame.onSaveConfigurationCommand, item)
314
if not globalVars.appArgs.secure:
315
self.menu.AppendSeparator()
316
item = self.menu.Append(wx.ID_ANY, _("Donate"))
317
self.Bind(wx.EVT_MENU, lambda evt: os.startfile("http://www.nvaccess.org/wiki/Donate"), item)
330
318
self.menu.AppendSeparator()
331
319
item = self.menu.Append(wx.ID_EXIT, _("E&xit"),_("Exit NVDA"))
332
320
self.Bind(wx.EVT_MENU, frame.onExitCommand, item)
352
340
mainFrame.Destroy()
355
wx.PostEvent(mainFrame, ExternalCommandEvent(id_showGuiCommand))
343
wx.CallAfter(mainFrame.showGui)
360
wx.PostEvent(mainFrame, ExternalCommandEvent(wx.ID_EXIT))
362
def execute(func, callback=None, *args, **kwargs):
363
"""Execute a function in the GUI thread.
364
This should be used when scripts need to interact with the user via the GUI.
365
For example, a frame or dialog can be created and this function can then be used to execute its Show method.
366
@param func: The function to execute.
368
@param callback: A function to call in the main thread when C{func} returns. The function will be passed the return value as its only argument.
346
wx.CallAfter(mainFrame.onExitCommand, None)
348
def messageBox(message, caption=wx.MessageBoxCaptionStr, style=wx.OK | wx.CENTER, parent=None):
349
"""Display a message dialog.
350
This should be used for all message dialogs
351
rather than using C{wx.MessageDialog} and C{wx.MessageBox} directly.
352
@param message: The message text.
354
@param caption: The caption (title) of the dialog.
356
@param style: Same as for wx.MessageBox.
358
@param parent: The parent window (optional).
359
@type parent: C{wx.Window}
360
@return: Same as for wx.MessageBox.
363
global isInMessageBox
364
wasAlready = isInMessageBox
365
isInMessageBox = True
368
res = wx.MessageBox(message, caption, style, parent or mainFrame)
370
mainFrame.postPopup()
372
isInMessageBox = False
375
def runScriptModalDialog(dialog, callback=None):
376
"""Run a modal dialog from a script.
377
This will not block the caller,
378
but will instead call C{callback} (if provided) with the result from the dialog.
379
The dialog will be destroyed once the callback has returned.
380
@param dialog: The dialog to show.
381
@type dialog: C{wx.Dialog}
382
@param callback: The optional callable to call with the result from the dialog.
369
383
@type callback: callable
370
@param args: Arguments for the function.
371
@param kwargs: Keyword arguments for the function.
373
wx.PostEvent(mainFrame, ExternalExecuteEvent(func, args, kwargs, callback))
387
res = dialog.ShowModal()
388
mainFrame.postPopup()
375
394
class WelcomeDialog(wx.Dialog):
376
395
"""The NVDA welcome dialog.
400
419
self.nconvAsNVDAModifierCheckBox = wx.CheckBox(self, wx.ID_ANY, _("Use NonConvert as an NVDA modifier key")) #nvdajp
401
420
self.nconvAsNVDAModifierCheckBox.SetValue(config.conf["keyboard"]["useNonConvertAsNVDAModifierKey"])
402
421
optionsSizer.Add(self.nconvAsNVDAModifierCheckBox,flag=wx.TOP|wx.RIGHT,border=10)
403
423
self.showWelcomeDialogAtStartupCheckBox = wx.CheckBox(self, wx.ID_ANY, _("Show this dialog when NVDA starts"))
404
424
self.showWelcomeDialogAtStartupCheckBox.SetValue(config.conf["general"]["showWelcomeDialogAtStartup"])
405
425
optionsSizer.Add(self.showWelcomeDialogAtStartupCheckBox,flag=wx.TOP|wx.LEFT,border=10)