|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2002 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the main user interface. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 try: |
|
12 str = unicode # __IGNORE_EXCEPTION__ |
|
13 except NameError: |
|
14 pass |
|
15 |
|
16 import os |
|
17 import sys |
|
18 import logging |
|
19 |
|
20 from PyQt5.QtCore import pyqtSlot, QTimer, QFile, QFileInfo, pyqtSignal, \ |
|
21 PYQT_VERSION_STR, QDate, QIODevice, qVersion, QProcess, QSize, QUrl, \ |
|
22 QObject, Qt, QUuid, QThread |
|
23 from PyQt5.QtGui import QKeySequence, QDesktopServices |
|
24 from PyQt5.QtWidgets import QSizePolicy, QWidget, QWhatsThis, QToolBar, \ |
|
25 QDialog, QSplitter, QApplication, QMenu, QVBoxLayout, QDockWidget, \ |
|
26 QAction, QLabel |
|
27 from PyQt5.Qsci import QSCINTILLA_VERSION_STR |
|
28 from PyQt5.QtNetwork import QNetworkProxyFactory, QNetworkAccessManager, \ |
|
29 QNetworkRequest, QNetworkReply |
|
30 |
|
31 from .Info import Version, VersionOnly, BugAddress, Program, FeatureAddress |
|
32 from . import Config |
|
33 |
|
34 from E5Gui.E5SingleApplication import E5SingleApplicationServer |
|
35 from E5Gui.E5Action import E5Action, createActionGroup |
|
36 from E5Gui.E5ToolBarManager import E5ToolBarManager |
|
37 from E5Gui import E5MessageBox, E5FileDialog, E5ErrorMessage |
|
38 from E5Gui.E5Application import e5App |
|
39 from E5Gui.E5MainWindow import E5MainWindow |
|
40 from E5Gui.E5ZoomWidget import E5ZoomWidget |
|
41 from E5Gui.E5ProgressDialog import E5ProgressDialog |
|
42 from E5Gui.E5ClickableLabel import E5ClickableLabel |
|
43 |
|
44 import Preferences |
|
45 import Utilities |
|
46 |
|
47 import UI.PixmapCache |
|
48 |
|
49 from E5Network.E5NetworkIcon import E5NetworkIcon |
|
50 from E5Network.E5NetworkProxyFactory import E5NetworkProxyFactory, \ |
|
51 proxyAuthenticationRequired |
|
52 try: |
|
53 from E5Network.E5SslErrorHandler import E5SslErrorHandler |
|
54 SSL_AVAILABLE = True |
|
55 except ImportError: |
|
56 SSL_AVAILABLE = False |
|
57 |
|
58 from eric6config import getConfig |
|
59 |
|
60 from Globals import qVersionTuple |
|
61 |
|
62 |
|
63 class Redirector(QObject): |
|
64 """ |
|
65 Helper class used to redirect stdout and stderr to the log window. |
|
66 |
|
67 @signal appendStderr(str) emitted to write data to stderr logger |
|
68 @signal appendStdout(str) emitted to write data to stdout logger |
|
69 """ |
|
70 appendStderr = pyqtSignal(str) |
|
71 appendStdout = pyqtSignal(str) |
|
72 |
|
73 def __init__(self, stderr): |
|
74 """ |
|
75 Constructor |
|
76 |
|
77 @param stderr flag indicating stderr is being redirected |
|
78 """ |
|
79 super(Redirector, self).__init__() |
|
80 self.stderr = stderr |
|
81 self.buffer = '' |
|
82 |
|
83 def __nWrite(self, n): |
|
84 """ |
|
85 Private method used to write data. |
|
86 |
|
87 @param n max number of bytes to write |
|
88 """ |
|
89 if n: |
|
90 line = self.buffer[:n] |
|
91 if self.stderr: |
|
92 self.appendStderr.emit(line) |
|
93 else: |
|
94 self.appendStdout.emit(line) |
|
95 self.buffer = self.buffer[n:] |
|
96 |
|
97 def __bufferedWrite(self): |
|
98 """ |
|
99 Private method returning number of characters to write. |
|
100 |
|
101 @return number of characters buffered or length of buffered line |
|
102 (integer) |
|
103 """ |
|
104 return self.buffer.rfind('\n') + 1 |
|
105 |
|
106 def flush(self): |
|
107 """ |
|
108 Public method used to flush the buffered data. |
|
109 """ |
|
110 self.__nWrite(len(self.buffer)) |
|
111 |
|
112 def write(self, s): |
|
113 """ |
|
114 Public method used to write data. |
|
115 |
|
116 @param s data to be written (it must support the str-method) |
|
117 """ |
|
118 self.buffer += str(s) |
|
119 self.__nWrite(self.__bufferedWrite()) |
|
120 |
|
121 |
|
122 class UserInterface(E5MainWindow): |
|
123 """ |
|
124 Class implementing the main user interface. |
|
125 |
|
126 @signal appendStderr(str) emitted to write data to stderr logger |
|
127 @signal appendStdout(str) emitted to write data to stdout logger |
|
128 @signal preferencesChanged() emitted after the preferences were changed |
|
129 @signal reloadAPIs() emitted to reload the api information |
|
130 @signal showMenu(str, QMenu) emitted when a menu is about to be shown. The |
|
131 name of the menu and a reference to the menu are given. |
|
132 @signal masterPasswordChanged(str, str) emitted after the master |
|
133 password has been changed with the old and the new password |
|
134 @signal onlineStateChanged(online) emitted to indicate a change of the |
|
135 network state |
|
136 """ |
|
137 appendStderr = pyqtSignal(str) |
|
138 appendStdout = pyqtSignal(str) |
|
139 preferencesChanged = pyqtSignal() |
|
140 reloadAPIs = pyqtSignal() |
|
141 showMenu = pyqtSignal(str, QMenu) |
|
142 masterPasswordChanged = pyqtSignal(str, str) |
|
143 onlineStateChanged = pyqtSignal(bool) |
|
144 |
|
145 maxFilePathLen = 100 |
|
146 maxMenuFilePathLen = 75 |
|
147 |
|
148 LeftSide = 1 |
|
149 BottomSide = 2 |
|
150 RightSide = 3 |
|
151 |
|
152 ErrorLogFileName = "eric6_error.log" |
|
153 |
|
154 def __init__(self, app, locale, splash, plugin, disabledPlugins, |
|
155 noOpenAtStartup, noCrashOpenAtStartup, disableCrashSession, |
|
156 restartArguments, originalPathString): |
|
157 """ |
|
158 Constructor |
|
159 |
|
160 @param app reference to the application object |
|
161 @type E5Application |
|
162 @param locale locale to be used by the UI |
|
163 @type str |
|
164 @param splash reference to the splashscreen |
|
165 @type UI.SplashScreen.SplashScreen |
|
166 @param plugin filename of a plug-in to be loaded (used for plugin |
|
167 development) |
|
168 @type str |
|
169 @param disabledPlugins list of plug-ins that have been disabled via |
|
170 the command line parameters '--disable-plugin=' |
|
171 @type list of str |
|
172 @param noOpenAtStartup flag indicating that the open at startup option |
|
173 should not be executed |
|
174 @type bool |
|
175 @param noCrashOpenAtStartup flag indicating to ignore any crash session |
|
176 file found at statup |
|
177 @type bool |
|
178 @param disableCrashSession flag indicating to disable the crash session |
|
179 support |
|
180 @type bool |
|
181 @param restartArguments list of command line parameters to be used for |
|
182 a restart |
|
183 @type list of str |
|
184 @param originalPathString original PATH environment variable |
|
185 @type str |
|
186 """ |
|
187 super(UserInterface, self).__init__() |
|
188 |
|
189 self.__restartArgs = restartArguments[:] |
|
190 |
|
191 self.setStyle(Preferences.getUI("Style"), |
|
192 Preferences.getUI("StyleSheet")) |
|
193 |
|
194 self.maxEditorPathLen = Preferences.getUI("CaptionFilenameLength") |
|
195 self.locale = locale |
|
196 self.__noOpenAtStartup = noOpenAtStartup |
|
197 self.__noCrashOpenAtStartup = noCrashOpenAtStartup |
|
198 self.__disableCrashSession = disableCrashSession |
|
199 self.__disabledPlugins = disabledPlugins[:] |
|
200 |
|
201 self.__originalPathString = originalPathString |
|
202 |
|
203 self.__layoutType = Preferences.getUI("LayoutType") |
|
204 |
|
205 self.passiveMode = Preferences.getDebugger("PassiveDbgEnabled") |
|
206 |
|
207 g = Preferences.getGeometry("MainGeometry") |
|
208 if g.isEmpty(): |
|
209 s = QSize(1280, 1024) |
|
210 self.resize(s) |
|
211 else: |
|
212 self.restoreGeometry(g) |
|
213 self.__startup = True |
|
214 |
|
215 if Preferences.getUI("UseSystemProxy"): |
|
216 QNetworkProxyFactory.setUseSystemConfiguration(True) |
|
217 else: |
|
218 self.__proxyFactory = E5NetworkProxyFactory() |
|
219 QNetworkProxyFactory.setApplicationProxyFactory( |
|
220 self.__proxyFactory) |
|
221 QNetworkProxyFactory.setUseSystemConfiguration(False) |
|
222 |
|
223 self.capProject = "" |
|
224 self.capEditor = "" |
|
225 self.captionShowsFilename = Preferences.getUI("CaptionShowsFilename") |
|
226 |
|
227 QApplication.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) |
|
228 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) |
|
229 self.__setWindowCaption() |
|
230 |
|
231 # load the view profiles |
|
232 self.profiles = Preferences.getUI("ViewProfiles2") |
|
233 |
|
234 # Generate the conda interface |
|
235 from CondaInterface.Conda import Conda |
|
236 self.condaInterface = Conda(self) |
|
237 e5App().registerObject("Conda", self.condaInterface) |
|
238 |
|
239 # Generate the pip interface |
|
240 from PipInterface.Pip import Pip |
|
241 self.pipInterface = Pip(self) |
|
242 e5App().registerObject("Pip", self.pipInterface) |
|
243 |
|
244 # Generate the virtual environment manager |
|
245 from VirtualEnv.VirtualenvManager import VirtualenvManager |
|
246 self.virtualenvManager = VirtualenvManager(self) |
|
247 # register it early because it is needed very soon |
|
248 e5App().registerObject("VirtualEnvManager", self.virtualenvManager) |
|
249 |
|
250 # Generate the debug server object |
|
251 from Debugger.DebugServer import DebugServer |
|
252 debugServer = DebugServer(self.__originalPathString) |
|
253 |
|
254 # Create the background service object |
|
255 from Utilities.BackgroundService import BackgroundService |
|
256 self.backgroundService = BackgroundService() |
|
257 |
|
258 # Generate an empty project object and multi project object |
|
259 from Project.Project import Project |
|
260 self.project = Project(self) |
|
261 e5App().registerObject("Project", self.project) |
|
262 |
|
263 from MultiProject.MultiProject import MultiProject |
|
264 self.multiProject = MultiProject(self.project, self) |
|
265 |
|
266 splash.showMessage(self.tr("Initializing Plugin Manager...")) |
|
267 |
|
268 # Initialize the Plugin Manager (Plugins are initialized later |
|
269 from PluginManager.PluginManager import PluginManager |
|
270 self.pluginManager = PluginManager(self, self.__disabledPlugins, |
|
271 develPlugin=plugin) |
|
272 |
|
273 splash.showMessage(self.tr("Generating Main User Interface...")) |
|
274 |
|
275 self.codeDocumentationViewer = None |
|
276 self.cooperation = None |
|
277 self.irc = None |
|
278 self.symbolsViewer = None |
|
279 self.browser = None |
|
280 self.templateViewer = None |
|
281 self.numbersViewer = None |
|
282 self.pipWidget = None |
|
283 self.condaWidget = None |
|
284 |
|
285 self.__webBrowserProcess = None |
|
286 self.__webBrowserClient = None |
|
287 self.__webBrowserSAName = QUuid.createUuid().toString()[1:-1] |
|
288 |
|
289 # Create the main window now so that we can connect QActions to it. |
|
290 logging.debug("Creating Layout...") |
|
291 self.__createLayout(debugServer) |
|
292 self.__currentRightWidget = None |
|
293 self.__currentBottomWidget = None |
|
294 |
|
295 # Generate the debugger part of the ui |
|
296 logging.debug("Creating Debugger UI...") |
|
297 from Debugger.DebugUI import DebugUI |
|
298 self.debuggerUI = DebugUI(self, self.viewmanager, debugServer, |
|
299 self.debugViewer, self.project) |
|
300 self.debugViewer.setDebugger(self.debuggerUI) |
|
301 self.shell.setDebuggerUI(self.debuggerUI) |
|
302 |
|
303 # Generate the redirection helpers |
|
304 self.stdout = Redirector(False) |
|
305 self.stderr = Redirector(True) |
|
306 |
|
307 # set a few dialog members for non-modal dialogs created on demand |
|
308 self.programsDialog = None |
|
309 self.shortcutsDialog = None |
|
310 self.unittestDialog = None |
|
311 self.findFileNameDialog = None |
|
312 self.diffDlg = None |
|
313 self.compareDlg = None |
|
314 self.findFilesDialog = None |
|
315 self.replaceFilesDialog = None |
|
316 self.__notification = None |
|
317 self.__readingSession = False |
|
318 self.__versionsDialog = None |
|
319 |
|
320 # now setup the connections |
|
321 splash.showMessage(self.tr("Setting up connections...")) |
|
322 |
|
323 self.debugViewer.exceptionLogger.sourceFile.connect( |
|
324 self.viewmanager.openSourceFile) |
|
325 |
|
326 self.debugViewer.sourceFile.connect(self.viewmanager.showDebugSource) |
|
327 |
|
328 self.taskViewer.displayFile.connect(self.viewmanager.openSourceFile) |
|
329 |
|
330 self.projectBrowser.psBrowser.sourceFile[str].connect( |
|
331 self.viewmanager.openSourceFile) |
|
332 self.projectBrowser.psBrowser.sourceFile[str, int].connect( |
|
333 self.viewmanager.openSourceFile) |
|
334 self.projectBrowser.psBrowser.sourceFile[str, list].connect( |
|
335 self.viewmanager.openSourceFile) |
|
336 self.projectBrowser.psBrowser.sourceFile[str, int, str].connect( |
|
337 self.viewmanager.openSourceFile) |
|
338 self.projectBrowser.psBrowser.closeSourceWindow.connect( |
|
339 self.viewmanager.closeWindow) |
|
340 self.projectBrowser.psBrowser.unittestOpen.connect( |
|
341 self.__unittestScript) |
|
342 |
|
343 self.projectBrowser.pfBrowser.designerFile.connect(self.__designer) |
|
344 self.projectBrowser.pfBrowser.sourceFile.connect( |
|
345 self.viewmanager.openSourceFile) |
|
346 self.projectBrowser.pfBrowser.uipreview.connect(self.__UIPreviewer) |
|
347 self.projectBrowser.pfBrowser.trpreview.connect(self.__TRPreviewer) |
|
348 self.projectBrowser.pfBrowser.closeSourceWindow.connect( |
|
349 self.viewmanager.closeWindow) |
|
350 self.projectBrowser.pfBrowser.appendStderr.connect(self.appendToStderr) |
|
351 |
|
352 self.projectBrowser.prBrowser.sourceFile.connect( |
|
353 self.viewmanager.openSourceFile) |
|
354 self.projectBrowser.prBrowser.closeSourceWindow.connect( |
|
355 self.viewmanager.closeWindow) |
|
356 self.projectBrowser.prBrowser.appendStderr.connect(self.appendToStderr) |
|
357 |
|
358 self.projectBrowser.ptBrowser.linguistFile.connect(self.__linguist4) |
|
359 self.projectBrowser.ptBrowser.sourceFile.connect( |
|
360 self.viewmanager.openSourceFile) |
|
361 self.projectBrowser.ptBrowser.trpreview[list].connect( |
|
362 self.__TRPreviewer) |
|
363 self.projectBrowser.ptBrowser.trpreview[list, bool].connect( |
|
364 self.__TRPreviewer) |
|
365 self.projectBrowser.ptBrowser.closeSourceWindow.connect( |
|
366 self.viewmanager.closeWindow) |
|
367 self.projectBrowser.ptBrowser.appendStdout.connect(self.appendToStdout) |
|
368 self.projectBrowser.ptBrowser.appendStderr.connect(self.appendToStderr) |
|
369 |
|
370 self.projectBrowser.piBrowser.sourceFile[str].connect( |
|
371 self.viewmanager.openSourceFile) |
|
372 self.projectBrowser.piBrowser.sourceFile[str, int].connect( |
|
373 self.viewmanager.openSourceFile) |
|
374 self.projectBrowser.piBrowser.closeSourceWindow.connect( |
|
375 self.viewmanager.closeWindow) |
|
376 self.projectBrowser.piBrowser.appendStdout.connect(self.appendToStdout) |
|
377 self.projectBrowser.piBrowser.appendStderr.connect(self.appendToStderr) |
|
378 |
|
379 self.projectBrowser.ppBrowser.sourceFile[str].connect( |
|
380 self.viewmanager.openSourceFile) |
|
381 self.projectBrowser.ppBrowser.sourceFile[str, int].connect( |
|
382 self.viewmanager.openSourceFile) |
|
383 self.projectBrowser.ppBrowser.closeSourceWindow.connect( |
|
384 self.viewmanager.closeWindow) |
|
385 self.projectBrowser.ppBrowser.appendStdout.connect(self.appendToStdout) |
|
386 self.projectBrowser.ppBrowser.appendStderr.connect(self.appendToStderr) |
|
387 |
|
388 self.projectBrowser.poBrowser.sourceFile.connect( |
|
389 self.viewmanager.openSourceFile) |
|
390 self.projectBrowser.poBrowser.closeSourceWindow.connect( |
|
391 self.viewmanager.closeWindow) |
|
392 self.projectBrowser.poBrowser.pixmapEditFile.connect(self.__editPixmap) |
|
393 self.projectBrowser.poBrowser.pixmapFile.connect(self.__showPixmap) |
|
394 self.projectBrowser.poBrowser.svgFile.connect(self.__showSvg) |
|
395 self.projectBrowser.poBrowser.binaryFile.connect(self.__openHexEditor) |
|
396 |
|
397 self.project.sourceFile.connect(self.viewmanager.openSourceFile) |
|
398 self.project.designerFile.connect(self.__designer) |
|
399 self.project.linguistFile.connect(self.__linguist4) |
|
400 self.project.projectOpened.connect(self.viewmanager.projectOpened) |
|
401 self.project.projectClosed.connect(self.viewmanager.projectClosed) |
|
402 self.project.projectFileRenamed.connect( |
|
403 self.viewmanager.projectFileRenamed) |
|
404 self.project.lexerAssociationsChanged.connect( |
|
405 self.viewmanager.projectLexerAssociationsChanged) |
|
406 self.project.newProject.connect(self.__newProject) |
|
407 self.project.projectOpened.connect(self.__projectOpened) |
|
408 self.project.projectOpened.connect(self.__activateProjectBrowser) |
|
409 self.project.projectClosed.connect(self.__projectClosed) |
|
410 self.project.projectClosed.connect( |
|
411 self.backgroundService.preferencesOrProjectChanged) |
|
412 self.project.projectOpened.connect(self.__writeCrashSession) |
|
413 self.project.projectClosed.connect(self.__writeCrashSession) |
|
414 self.project.appendStdout.connect(self.appendToStdout) |
|
415 self.project.appendStderr.connect(self.appendToStderr) |
|
416 |
|
417 self.multiProject.multiProjectOpened.connect( |
|
418 self.__activateMultiProjectBrowser) |
|
419 self.multiProject.multiProjectOpened.connect( |
|
420 self.__writeCrashSession) |
|
421 self.multiProject.multiProjectClosed.connect( |
|
422 self.__writeCrashSession) |
|
423 |
|
424 self.debuggerUI.resetUI.connect(self.viewmanager.handleResetUI) |
|
425 self.debuggerUI.resetUI.connect(self.debugViewer.handleResetUI) |
|
426 self.debuggerUI.resetUI.connect(self.__debuggingDone) |
|
427 self.debuggerUI.debuggingStarted.connect( |
|
428 self.debugViewer.exceptionLogger.debuggingStarted) |
|
429 self.debuggerUI.debuggingStarted.connect( |
|
430 self.debugViewer.handleDebuggingStarted) |
|
431 self.debuggerUI.debuggingStarted.connect(self.__programChange) |
|
432 self.debuggerUI.debuggingStarted.connect(self.__debuggingStarted) |
|
433 self.debuggerUI.compileForms.connect( |
|
434 self.projectBrowser.pfBrowser.compileChangedForms) |
|
435 self.debuggerUI.compileResources.connect( |
|
436 self.projectBrowser.prBrowser.compileChangedResources) |
|
437 self.debuggerUI.executeMake.connect(self.project.executeMake) |
|
438 self.debuggerUI.appendStdout.connect(self.appendToStdout) |
|
439 |
|
440 debugServer.passiveDebugStarted.connect( |
|
441 self.debugViewer.exceptionLogger.debuggingStarted) |
|
442 debugServer.passiveDebugStarted.connect( |
|
443 self.debugViewer.handleDebuggingStarted) |
|
444 debugServer.clientException.connect( |
|
445 self.debugViewer.exceptionLogger.addException) |
|
446 debugServer.clientLine.connect( |
|
447 self.debugViewer.breakpointViewer.highlightBreakpoint) |
|
448 debugServer.clientProcessStdout.connect(self.appendToStdout) |
|
449 debugServer.clientProcessStderr.connect(self.appendToStderr) |
|
450 debugServer.appendStdout.connect(self.appendToStdout) |
|
451 |
|
452 self.stdout.appendStdout.connect(self.appendToStdout) |
|
453 self.stderr.appendStderr.connect(self.appendToStderr) |
|
454 |
|
455 self.preferencesChanged.connect(self.viewmanager.preferencesChanged) |
|
456 self.reloadAPIs.connect(self.viewmanager.getAPIsManager().reloadAPIs) |
|
457 self.preferencesChanged.connect(self.logViewer.preferencesChanged) |
|
458 self.appendStdout.connect(self.logViewer.appendToStdout) |
|
459 self.appendStderr.connect(self.logViewer.appendToStderr) |
|
460 self.preferencesChanged.connect(self.shell.handlePreferencesChanged) |
|
461 self.preferencesChanged.connect(self.project.handlePreferencesChanged) |
|
462 self.preferencesChanged.connect( |
|
463 self.projectBrowser.handlePreferencesChanged) |
|
464 self.preferencesChanged.connect( |
|
465 self.projectBrowser.psBrowser.handlePreferencesChanged) |
|
466 self.preferencesChanged.connect( |
|
467 self.projectBrowser.pfBrowser.handlePreferencesChanged) |
|
468 self.preferencesChanged.connect( |
|
469 self.projectBrowser.prBrowser.handlePreferencesChanged) |
|
470 self.preferencesChanged.connect( |
|
471 self.projectBrowser.ptBrowser.handlePreferencesChanged) |
|
472 self.preferencesChanged.connect( |
|
473 self.projectBrowser.piBrowser.handlePreferencesChanged) |
|
474 self.preferencesChanged.connect( |
|
475 self.projectBrowser.ppBrowser.handlePreferencesChanged) |
|
476 self.preferencesChanged.connect( |
|
477 self.projectBrowser.poBrowser.handlePreferencesChanged) |
|
478 self.preferencesChanged.connect( |
|
479 self.taskViewer.handlePreferencesChanged) |
|
480 self.preferencesChanged.connect(self.pluginManager.preferencesChanged) |
|
481 self.preferencesChanged.connect(debugServer.preferencesChanged) |
|
482 self.preferencesChanged.connect(self.debugViewer.preferencesChanged) |
|
483 self.preferencesChanged.connect( |
|
484 self.backgroundService.preferencesOrProjectChanged) |
|
485 |
|
486 if self.browser is not None: |
|
487 self.browser.sourceFile[str].connect( |
|
488 self.viewmanager.openSourceFile) |
|
489 self.browser.sourceFile[str, int].connect( |
|
490 self.viewmanager.openSourceFile) |
|
491 self.browser.sourceFile[str, list].connect( |
|
492 self.viewmanager.openSourceFile) |
|
493 self.browser.sourceFile[str, int, str].connect( |
|
494 self.viewmanager.openSourceFile) |
|
495 self.browser.designerFile.connect(self.__designer) |
|
496 self.browser.linguistFile.connect(self.__linguist4) |
|
497 self.browser.projectFile.connect(self.project.openProject) |
|
498 self.browser.multiProjectFile.connect( |
|
499 self.multiProject.openMultiProject) |
|
500 self.browser.pixmapEditFile.connect(self.__editPixmap) |
|
501 self.browser.pixmapFile.connect(self.__showPixmap) |
|
502 self.browser.svgFile.connect(self.__showSvg) |
|
503 self.browser.binaryFile.connect(self.__openHexEditor) |
|
504 self.browser.unittestOpen.connect(self.__unittestScript) |
|
505 self.browser.trpreview.connect(self.__TRPreviewer) |
|
506 |
|
507 self.debuggerUI.debuggingStarted.connect( |
|
508 self.browser.handleProgramChange) |
|
509 |
|
510 debugServer.clientInterpreterChanged.connect( |
|
511 self.browser.handleInterpreterChanged) |
|
512 |
|
513 self.preferencesChanged.connect( |
|
514 self.browser.handlePreferencesChanged) |
|
515 |
|
516 if self.codeDocumentationViewer is not None: |
|
517 self.preferencesChanged.connect( |
|
518 self.codeDocumentationViewer.preferencesChanged) |
|
519 |
|
520 self.viewmanager.editorSaved.connect(self.project.repopulateItem) |
|
521 self.viewmanager.lastEditorClosed.connect(self.__lastEditorClosed) |
|
522 self.viewmanager.editorOpened.connect(self.__editorOpened) |
|
523 self.viewmanager.changeCaption.connect(self.__setWindowCaption) |
|
524 self.viewmanager.checkActions.connect(self.__checkActions) |
|
525 self.viewmanager.editorChanged.connect( |
|
526 self.projectBrowser.handleEditorChanged) |
|
527 self.viewmanager.editorLineChanged.connect( |
|
528 self.projectBrowser.handleEditorLineChanged) |
|
529 self.viewmanager.editorOpened.connect(self.__writeCrashSession) |
|
530 self.viewmanager.editorClosed.connect(self.__writeCrashSession) |
|
531 self.viewmanager.editorRenamed.connect(self.__writeCrashSession) |
|
532 self.viewmanager.editorChanged.connect(self.__writeCrashSession) |
|
533 |
|
534 self.shell.zoomValueChanged.connect( |
|
535 lambda v: self.viewmanager.zoomValueChanged(v, self.shell)) |
|
536 |
|
537 if self.cooperation is not None: |
|
538 self.viewmanager.checkActions.connect( |
|
539 self.cooperation.checkEditorActions) |
|
540 self.preferencesChanged.connect( |
|
541 self.cooperation.preferencesChanged) |
|
542 self.cooperation.shareEditor.connect( |
|
543 self.viewmanager.shareEditor) |
|
544 self.cooperation.startEdit.connect( |
|
545 self.viewmanager.startSharedEdit) |
|
546 self.cooperation.sendEdit.connect( |
|
547 self.viewmanager.sendSharedEdit) |
|
548 self.cooperation.cancelEdit.connect( |
|
549 self.viewmanager.cancelSharedEdit) |
|
550 self.cooperation.connected.connect( |
|
551 self.viewmanager.shareConnected) |
|
552 self.cooperation.editorCommand.connect( |
|
553 self.viewmanager.receive) |
|
554 self.viewmanager.setCooperationClient( |
|
555 self.cooperation.getClient()) |
|
556 |
|
557 if self.symbolsViewer is not None: |
|
558 self.symbolsViewer.insertSymbol.connect( |
|
559 self.viewmanager.insertSymbol) |
|
560 |
|
561 if self.numbersViewer is not None: |
|
562 self.numbersViewer.insertNumber.connect( |
|
563 self.viewmanager.insertNumber) |
|
564 |
|
565 if self.irc is not None: |
|
566 self.irc.autoConnected.connect(self.__ircAutoConnected) |
|
567 |
|
568 # create the toolbar manager object |
|
569 self.toolbarManager = E5ToolBarManager(self, self) |
|
570 self.toolbarManager.setMainWindow(self) |
|
571 |
|
572 # Initialize the tool groups and list of started tools |
|
573 splash.showMessage(self.tr("Initializing Tools...")) |
|
574 self.toolGroups, self.currentToolGroup = Preferences.readToolGroups() |
|
575 self.toolProcs = [] |
|
576 self.__initExternalToolsActions() |
|
577 |
|
578 # redirect handling of http and https URLs to ourselves |
|
579 QDesktopServices.setUrlHandler("http", self.handleUrl) |
|
580 QDesktopServices.setUrlHandler("https", self.handleUrl) |
|
581 |
|
582 # register all relevant objects |
|
583 splash.showMessage(self.tr("Registering Objects...")) |
|
584 e5App().registerObject("UserInterface", self) |
|
585 e5App().registerObject("DebugUI", self.debuggerUI) |
|
586 e5App().registerObject("DebugServer", debugServer) |
|
587 e5App().registerObject("BackgroundService", self.backgroundService) |
|
588 e5App().registerObject("ViewManager", self.viewmanager) |
|
589 e5App().registerObject("ProjectBrowser", self.projectBrowser) |
|
590 e5App().registerObject("MultiProject", self.multiProject) |
|
591 e5App().registerObject("TaskViewer", self.taskViewer) |
|
592 if self.templateViewer is not None: |
|
593 e5App().registerObject("TemplateViewer", self.templateViewer) |
|
594 e5App().registerObject("Shell", self.shell) |
|
595 e5App().registerObject("PluginManager", self.pluginManager) |
|
596 e5App().registerObject("ToolbarManager", self.toolbarManager) |
|
597 if self.cooperation is not None: |
|
598 e5App().registerObject("Cooperation", self.cooperation) |
|
599 if self.irc is not None: |
|
600 e5App().registerObject("IRC", self.irc) |
|
601 if self.symbolsViewer is not None: |
|
602 e5App().registerObject("Symbols", self.symbolsViewer) |
|
603 if self.numbersViewer is not None: |
|
604 e5App().registerObject("Numbers", self.numbersViewer) |
|
605 if self.codeDocumentationViewer is not None: |
|
606 e5App().registerObject("DocuViewer", self.codeDocumentationViewer) |
|
607 |
|
608 # list of web addresses serving the versions file |
|
609 self.__httpAlternatives = Preferences.getUI("VersionsUrls6") |
|
610 self.__inVersionCheck = False |
|
611 self.__versionCheckProgress = None |
|
612 |
|
613 # Initialize the actions, menus, toolbars and statusbar |
|
614 splash.showMessage(self.tr("Initializing Actions...")) |
|
615 self.__initActions() |
|
616 splash.showMessage(self.tr("Initializing Menus...")) |
|
617 self.__initMenus() |
|
618 splash.showMessage(self.tr("Initializing Toolbars...")) |
|
619 self.__initToolbars() |
|
620 splash.showMessage(self.tr("Initializing Statusbar...")) |
|
621 self.__initStatusbar() |
|
622 |
|
623 # connect the appFocusChanged signal after all actions are ready |
|
624 app.focusChanged.connect(self.viewmanager.appFocusChanged) |
|
625 |
|
626 # Initialize the instance variables. |
|
627 self.currentProg = None |
|
628 self.isProg = False |
|
629 self.utEditorOpen = False |
|
630 self.utProjectOpen = False |
|
631 |
|
632 self.inDragDrop = False |
|
633 self.setAcceptDrops(True) |
|
634 |
|
635 self.currentProfile = None |
|
636 |
|
637 self.shutdownCalled = False |
|
638 self.inCloseEvent = False |
|
639 |
|
640 # now redirect stdout and stderr |
|
641 # TODO: release - reenable redirection |
|
642 ## sys.stdout = self.stdout |
|
643 ## sys.stderr = self.stderr |
|
644 |
|
645 # now fire up the single application server |
|
646 if Preferences.getUI("SingleApplicationMode"): |
|
647 splash.showMessage( |
|
648 self.tr("Initializing Single Application Server...")) |
|
649 self.SAServer = E5SingleApplicationServer() |
|
650 else: |
|
651 self.SAServer = None |
|
652 |
|
653 # now finalize the plugin manager setup |
|
654 splash.showMessage(self.tr("Initializing Plugins...")) |
|
655 self.pluginManager.finalizeSetup() |
|
656 # now activate plugins having autoload set to True |
|
657 splash.showMessage(self.tr("Activating Plugins...")) |
|
658 self.pluginManager.activatePlugins() |
|
659 splash.showMessage(self.tr("Generating Plugins Toolbars...")) |
|
660 self.pluginManager.initPluginToolbars(self.toolbarManager) |
|
661 if Preferences.getPluginManager("StartupCleanup"): |
|
662 splash.showMessage(self.tr("Cleaning Plugins Download Area...")) |
|
663 from PluginManager.PluginRepositoryDialog import \ |
|
664 PluginRepositoryDownloadCleanup |
|
665 PluginRepositoryDownloadCleanup(quiet=True) |
|
666 |
|
667 # now read the keyboard shortcuts for all the actions |
|
668 from Preferences import Shortcuts |
|
669 Shortcuts.readShortcuts() |
|
670 |
|
671 # restore toolbar manager state |
|
672 splash.showMessage(self.tr("Restoring Toolbarmanager...")) |
|
673 self.toolbarManager.restoreState( |
|
674 Preferences.getUI("ToolbarManagerState")) |
|
675 |
|
676 if self.codeDocumentationViewer is not None: |
|
677 # finalize the initialization of the code documentation viewer |
|
678 self.codeDocumentationViewer.finalizeSetup() |
|
679 |
|
680 # now activate the initial view profile |
|
681 splash.showMessage(self.tr("Setting View Profile...")) |
|
682 self.__setEditProfile() |
|
683 |
|
684 # now read the saved tasks |
|
685 splash.showMessage(self.tr("Reading Tasks...")) |
|
686 self.__readTasks() |
|
687 |
|
688 if self.templateViewer is not None: |
|
689 # now read the saved templates |
|
690 splash.showMessage(self.tr("Reading Templates...")) |
|
691 self.templateViewer.readTemplates() |
|
692 |
|
693 # now start the debug client with the most recently used virtual |
|
694 # environment |
|
695 splash.showMessage(self.tr("Starting Debugger...")) |
|
696 if Preferences.getShell("StartWithMostRecentlyUsedEnvironment"): |
|
697 debugServer.startClient( |
|
698 False, venvName=Preferences.getShell("LastVirtualEnvironment") |
|
699 ) |
|
700 else: |
|
701 debugServer.startClient(False) |
|
702 |
|
703 # attributes for the network objects |
|
704 self.__networkManager = QNetworkAccessManager(self) |
|
705 self.__networkManager.proxyAuthenticationRequired.connect( |
|
706 proxyAuthenticationRequired) |
|
707 if SSL_AVAILABLE: |
|
708 self.__sslErrorHandler = E5SslErrorHandler(self) |
|
709 self.__networkManager.sslErrors.connect(self.__sslErrors) |
|
710 self.__replies = [] |
|
711 |
|
712 # set spellchecker defaults |
|
713 from QScintilla.SpellChecker import SpellChecker |
|
714 SpellChecker.setDefaultLanguage( |
|
715 Preferences.getEditor("SpellCheckingDefaultLanguage")) |
|
716 |
|
717 # attributes for the last shown configuration page and the |
|
718 # extended configuration entries |
|
719 self.__lastConfigurationPageName = "" |
|
720 self.__expandedConfigurationEntries = [] |
|
721 |
|
722 # set the keyboard input interval |
|
723 interval = Preferences.getUI("KeyboardInputInterval") |
|
724 if interval > 0: |
|
725 QApplication.setKeyboardInputInterval(interval) |
|
726 |
|
727 def __createLayout(self, debugServer): |
|
728 """ |
|
729 Private method to create the layout of the various windows. |
|
730 |
|
731 @param debugServer reference to the debug server object |
|
732 @exception ValueError raised to indicate an invalid layout type |
|
733 """ |
|
734 # Create the view manager depending on the configuration setting |
|
735 logging.debug("Creating Viewmanager...") |
|
736 import ViewManager |
|
737 self.viewmanager = \ |
|
738 ViewManager.factory(self, self, debugServer, self.pluginManager) |
|
739 leftWidget = QWidget() |
|
740 layout = QVBoxLayout() |
|
741 layout.setContentsMargins(1, 1, 1, 1) |
|
742 layout.setSpacing(1) |
|
743 layout.addWidget(self.viewmanager.mainWidget()) |
|
744 layout.addWidget(self.viewmanager.searchWidget()) |
|
745 layout.addWidget(self.viewmanager.replaceWidget()) |
|
746 self.viewmanager.mainWidget().setSizePolicy( |
|
747 QSizePolicy.Preferred, QSizePolicy.Expanding) |
|
748 leftWidget.setLayout(layout) |
|
749 self.viewmanager.searchWidget().hide() |
|
750 self.viewmanager.replaceWidget().hide() |
|
751 |
|
752 splitter = QSplitter(Qt.Horizontal) |
|
753 splitter.addWidget(leftWidget) |
|
754 self.setCentralWidget(splitter) |
|
755 |
|
756 # Create previewer |
|
757 logging.debug("Creating Previewer...") |
|
758 from .Previewer import Previewer |
|
759 self.__previewer = Previewer(self.viewmanager, splitter) |
|
760 splitter.addWidget(self.__previewer) |
|
761 |
|
762 # Create AST viewer |
|
763 logging.debug("Creating Python AST Viewer") |
|
764 from .PythonAstViewer import PythonAstViewer |
|
765 self.__astViewer = PythonAstViewer(self.viewmanager, splitter) |
|
766 splitter.addWidget(self.__astViewer) |
|
767 |
|
768 # Create layout with toolbox windows embedded in dock windows |
|
769 if self.__layoutType == "Toolboxes": |
|
770 logging.debug("Creating toolboxes...") |
|
771 self.__createToolboxesLayout(debugServer) |
|
772 |
|
773 # Create layout with sidebar windows embedded in dock windows |
|
774 elif self.__layoutType == "Sidebars": |
|
775 logging.debug("Creating sidebars...") |
|
776 self.__createSidebarsLayout(debugServer) |
|
777 |
|
778 else: |
|
779 raise ValueError("Wrong layout type given ({0})".format( |
|
780 self.__layoutType)) |
|
781 logging.debug("Created Layout") |
|
782 |
|
783 def __createToolboxesLayout(self, debugServer): |
|
784 """ |
|
785 Private method to create the Toolboxes layout. |
|
786 |
|
787 @param debugServer reference to the debug server object |
|
788 """ |
|
789 from E5Gui.E5ToolBox import E5VerticalToolBox, E5HorizontalToolBox |
|
790 |
|
791 logging.debug("Creating Toolboxes Layout...") |
|
792 |
|
793 # Create the left toolbox |
|
794 self.lToolboxDock = self.__createDockWindow("lToolboxDock") |
|
795 self.lToolbox = E5VerticalToolBox(self.lToolboxDock) |
|
796 self.__setupDockWindow(self.lToolboxDock, Qt.LeftDockWidgetArea, |
|
797 self.lToolbox, self.tr("Left Toolbox")) |
|
798 |
|
799 # Create the horizontal toolbox |
|
800 self.hToolboxDock = self.__createDockWindow("hToolboxDock") |
|
801 self.hToolbox = E5HorizontalToolBox(self.hToolboxDock) |
|
802 self.__setupDockWindow(self.hToolboxDock, Qt.BottomDockWidgetArea, |
|
803 self.hToolbox, |
|
804 self.tr("Horizontal Toolbox")) |
|
805 |
|
806 # Create the right toolbox |
|
807 self.rToolboxDock = self.__createDockWindow("rToolboxDock") |
|
808 self.rToolbox = E5VerticalToolBox(self.rToolboxDock) |
|
809 self.__setupDockWindow(self.rToolboxDock, Qt.RightDockWidgetArea, |
|
810 self.rToolbox, self.tr("Right Toolbox")) |
|
811 |
|
812 # Create the project browser |
|
813 logging.debug("Creating Project Browser...") |
|
814 from Project.ProjectBrowser import ProjectBrowser |
|
815 self.projectBrowser = ProjectBrowser(self.project) |
|
816 self.lToolbox.addItem(self.projectBrowser, |
|
817 UI.PixmapCache.getIcon("projectViewer.png"), |
|
818 self.tr("Project-Viewer")) |
|
819 |
|
820 # Create the multi project browser |
|
821 logging.debug("Creating Multiproject Browser...") |
|
822 from MultiProject.MultiProjectBrowser import MultiProjectBrowser |
|
823 self.multiProjectBrowser = MultiProjectBrowser(self.multiProject, |
|
824 self.project) |
|
825 self.lToolbox.addItem(self.multiProjectBrowser, |
|
826 UI.PixmapCache.getIcon("multiProjectViewer.png"), |
|
827 self.tr("Multiproject-Viewer")) |
|
828 |
|
829 if Preferences.getUI("ShowTemplateViewer"): |
|
830 # Create the template viewer part of the user interface |
|
831 logging.debug("Creating Template Viewer...") |
|
832 from Templates.TemplateViewer import TemplateViewer |
|
833 self.templateViewer = TemplateViewer(None, |
|
834 self.viewmanager) |
|
835 self.lToolbox.addItem(self.templateViewer, |
|
836 UI.PixmapCache.getIcon("templateViewer.png"), |
|
837 self.tr("Template-Viewer")) |
|
838 |
|
839 if Preferences.getUI("ShowCodeDocumentationViewer"): |
|
840 # Create the code documentation viewer |
|
841 logging.debug("Creating Code Documentation Viewer...") |
|
842 from .CodeDocumentationViewer import CodeDocumentationViewer |
|
843 self.codeDocumentationViewer = CodeDocumentationViewer(self) |
|
844 self.rToolbox.addItem(self.codeDocumentationViewer, |
|
845 UI.PixmapCache.getIcon("codeDocuViewer.png"), |
|
846 self.tr("Code Documentation Viewer")) |
|
847 |
|
848 # Create the debug viewer maybe without the embedded shell |
|
849 logging.debug("Creating Debug Viewer...") |
|
850 from Debugger.DebugViewer import DebugViewer |
|
851 self.debugViewer = DebugViewer(debugServer, True, self.viewmanager) |
|
852 self.rToolbox.addItem(self.debugViewer, |
|
853 UI.PixmapCache.getIcon("debugViewer.png"), |
|
854 self.tr("Debug-Viewer")) |
|
855 |
|
856 if Preferences.getUI("ShowPyPIPackageManager"): |
|
857 # Create the PyPI package manager |
|
858 logging.debug("Creating PyPI Package Manager...") |
|
859 from PipInterface.PipPackagesWidget import PipPackagesWidget |
|
860 self.pipWidget = PipPackagesWidget(self.pipInterface) |
|
861 self.rToolbox.addItem(self.pipWidget, |
|
862 UI.PixmapCache.getIcon("pypi"), |
|
863 self.tr("PyPI")) |
|
864 |
|
865 if Preferences.getUI("ShowCondaPackageManager"): |
|
866 # Create the conda package manager |
|
867 logging.debug("Creating Conda Package Manager...") |
|
868 from CondaInterface.CondaPackagesWidget import CondaPackagesWidget |
|
869 self.condaWidget = CondaPackagesWidget(self.condaInterface) |
|
870 self.rToolbox.addItem(self.condaWidget, |
|
871 UI.PixmapCache.getIcon("miniconda.png"), |
|
872 self.tr("Conda")) |
|
873 |
|
874 if Preferences.getUI("ShowCooperation"): |
|
875 # Create the chat part of the user interface |
|
876 logging.debug("Creating Chat Widget...") |
|
877 from Cooperation.ChatWidget import ChatWidget |
|
878 self.cooperation = ChatWidget(self) |
|
879 self.rToolbox.addItem(self.cooperation, |
|
880 UI.PixmapCache.getIcon("cooperation.png"), |
|
881 self.tr("Cooperation")) |
|
882 |
|
883 if Preferences.getUI("ShowIrc"): |
|
884 # Create the IRC part of the user interface |
|
885 logging.debug("Creating IRC Widget...") |
|
886 from Network.IRC.IrcWidget import IrcWidget |
|
887 self.irc = IrcWidget(self) |
|
888 self.rToolbox.addItem(self.irc, |
|
889 UI.PixmapCache.getIcon("irc.png"), |
|
890 self.tr("IRC")) |
|
891 |
|
892 # Create the task viewer part of the user interface |
|
893 logging.debug("Creating Task Viewer...") |
|
894 from Tasks.TaskViewer import TaskViewer |
|
895 self.taskViewer = TaskViewer(None, self.project) |
|
896 self.hToolbox.addItem(self.taskViewer, |
|
897 UI.PixmapCache.getIcon("task.png"), |
|
898 self.tr("Task-Viewer")) |
|
899 |
|
900 # Create the log viewer part of the user interface |
|
901 logging.debug("Creating Log Viewer...") |
|
902 from .LogView import LogViewer |
|
903 self.logViewer = LogViewer(self) |
|
904 self.hToolbox.addItem(self.logViewer, |
|
905 UI.PixmapCache.getIcon("logViewer.png"), |
|
906 self.tr("Log-Viewer")) |
|
907 |
|
908 # Create the shell |
|
909 logging.debug("Creating Shell...") |
|
910 from QScintilla.Shell import ShellAssembly |
|
911 self.shellAssembly = \ |
|
912 ShellAssembly(debugServer, self.viewmanager, self.project, True) |
|
913 self.shell = self.shellAssembly.shell() |
|
914 self.hToolbox.insertItem(0, self.shellAssembly, |
|
915 UI.PixmapCache.getIcon("shell.png"), |
|
916 self.tr("Shell")) |
|
917 |
|
918 if Preferences.getUI("ShowFileBrowser"): |
|
919 # Create the file browser |
|
920 logging.debug("Creating File Browser...") |
|
921 from .Browser import Browser |
|
922 self.browser = Browser() |
|
923 self.lToolbox.addItem(self.browser, |
|
924 UI.PixmapCache.getIcon("browser.png"), |
|
925 self.tr("File-Browser")) |
|
926 |
|
927 if Preferences.getUI("ShowSymbolsViewer"): |
|
928 # Create the symbols viewer |
|
929 logging.debug("Creating Symbols Viewer...") |
|
930 from .SymbolsWidget import SymbolsWidget |
|
931 self.symbolsViewer = SymbolsWidget() |
|
932 self.lToolbox.addItem(self.symbolsViewer, |
|
933 UI.PixmapCache.getIcon("symbols.png"), |
|
934 self.tr("Symbols")) |
|
935 |
|
936 if Preferences.getUI("ShowNumbersViewer"): |
|
937 # Create the numbers viewer |
|
938 logging.debug("Creating Numbers Viewer...") |
|
939 from .NumbersWidget import NumbersWidget |
|
940 self.numbersViewer = NumbersWidget() |
|
941 self.hToolbox.addItem(self.numbersViewer, |
|
942 UI.PixmapCache.getIcon("numbers.png"), |
|
943 self.tr("Numbers")) |
|
944 |
|
945 self.hToolbox.setCurrentIndex(0) |
|
946 |
|
947 def __createSidebarsLayout(self, debugServer): |
|
948 """ |
|
949 Private method to create the Sidebars layout. |
|
950 |
|
951 @param debugServer reference to the debug server object |
|
952 """ |
|
953 from E5Gui.E5SideBar import E5SideBar |
|
954 |
|
955 logging.debug("Creating Sidebars Layout...") |
|
956 |
|
957 delay = Preferences.getUI("SidebarDelay") |
|
958 # Create the left sidebar |
|
959 self.leftSidebar = E5SideBar(E5SideBar.West, delay) |
|
960 |
|
961 # Create the bottom sidebar |
|
962 self.bottomSidebar = E5SideBar(E5SideBar.South, delay) |
|
963 |
|
964 # Create the right sidebar |
|
965 self.rightSidebar = E5SideBar(E5SideBar.East, delay) |
|
966 |
|
967 # Create the project browser |
|
968 logging.debug("Creating Project Browser...") |
|
969 from Project.ProjectBrowser import ProjectBrowser |
|
970 self.projectBrowser = ProjectBrowser(self.project) |
|
971 self.leftSidebar.addTab( |
|
972 self.projectBrowser, |
|
973 UI.PixmapCache.getIcon("projectViewer.png"), |
|
974 self.tr("Project-Viewer")) |
|
975 |
|
976 # Create the multi project browser |
|
977 logging.debug("Creating Multiproject Browser...") |
|
978 from MultiProject.MultiProjectBrowser import MultiProjectBrowser |
|
979 self.multiProjectBrowser = MultiProjectBrowser(self.multiProject, |
|
980 self.project) |
|
981 self.leftSidebar.addTab( |
|
982 self.multiProjectBrowser, |
|
983 UI.PixmapCache.getIcon("multiProjectViewer.png"), |
|
984 self.tr("Multiproject-Viewer")) |
|
985 |
|
986 if Preferences.getUI("ShowTemplateViewer"): |
|
987 # Create the template viewer part of the user interface |
|
988 logging.debug("Creating Template Viewer...") |
|
989 from Templates.TemplateViewer import TemplateViewer |
|
990 self.templateViewer = TemplateViewer(None, |
|
991 self.viewmanager) |
|
992 self.leftSidebar.addTab( |
|
993 self.templateViewer, |
|
994 UI.PixmapCache.getIcon("templateViewer.png"), |
|
995 self.tr("Template-Viewer")) |
|
996 |
|
997 if Preferences.getUI("ShowCodeDocumentationViewer"): |
|
998 # Create the code documentation viewer |
|
999 logging.debug("Creating Code Documentation Viewer...") |
|
1000 from .CodeDocumentationViewer import CodeDocumentationViewer |
|
1001 self.codeDocumentationViewer = CodeDocumentationViewer(self) |
|
1002 self.rightSidebar.addTab( |
|
1003 self.codeDocumentationViewer, |
|
1004 UI.PixmapCache.getIcon("codeDocuViewer.png"), |
|
1005 self.tr("Code Documentation Viewer")) |
|
1006 |
|
1007 # Create the debug viewer maybe without the embedded shell |
|
1008 logging.debug("Creating Debug Viewer...") |
|
1009 from Debugger.DebugViewer import DebugViewer |
|
1010 self.debugViewer = DebugViewer(debugServer, True, self.viewmanager) |
|
1011 self.rightSidebar.addTab( |
|
1012 self.debugViewer, UI.PixmapCache.getIcon("debugViewer.png"), |
|
1013 self.tr("Debug-Viewer")) |
|
1014 |
|
1015 if Preferences.getUI("ShowPyPIPackageManager"): |
|
1016 # Create the PyPI package manager |
|
1017 logging.debug("Creating PyPI Package Manager...") |
|
1018 from PipInterface.PipPackagesWidget import PipPackagesWidget |
|
1019 self.pipWidget = PipPackagesWidget(self.pipInterface) |
|
1020 self.rightSidebar.addTab( |
|
1021 self.pipWidget, UI.PixmapCache.getIcon("pypi"), |
|
1022 self.tr("PyPI")) |
|
1023 |
|
1024 if Preferences.getUI("ShowCondaPackageManager"): |
|
1025 # Create the conda package manager |
|
1026 logging.debug("Creating Conda Package Manager...") |
|
1027 from CondaInterface.CondaPackagesWidget import CondaPackagesWidget |
|
1028 self.condaWidget = CondaPackagesWidget(self.condaInterface) |
|
1029 self.rightSidebar.addTab( |
|
1030 self.condaWidget, UI.PixmapCache.getIcon("miniconda.png"), |
|
1031 self.tr("Conda")) |
|
1032 |
|
1033 if Preferences.getUI("ShowCooperation"): |
|
1034 # Create the chat part of the user interface |
|
1035 logging.debug("Creating Chat Widget...") |
|
1036 from Cooperation.ChatWidget import ChatWidget |
|
1037 self.cooperation = ChatWidget(self) |
|
1038 self.rightSidebar.addTab( |
|
1039 self.cooperation, UI.PixmapCache.getIcon("cooperation.png"), |
|
1040 self.tr("Cooperation")) |
|
1041 |
|
1042 if Preferences.getUI("ShowIrc"): |
|
1043 # Create the IRC part of the user interface |
|
1044 logging.debug("Creating IRC Widget...") |
|
1045 from Network.IRC.IrcWidget import IrcWidget |
|
1046 self.irc = IrcWidget(self) |
|
1047 self.rightSidebar.addTab( |
|
1048 self.irc, UI.PixmapCache.getIcon("irc.png"), |
|
1049 self.tr("IRC")) |
|
1050 |
|
1051 # Create the task viewer part of the user interface |
|
1052 logging.debug("Creating Task Viewer...") |
|
1053 from Tasks.TaskViewer import TaskViewer |
|
1054 self.taskViewer = TaskViewer(None, self.project) |
|
1055 self.bottomSidebar.addTab(self.taskViewer, |
|
1056 UI.PixmapCache.getIcon("task.png"), |
|
1057 self.tr("Task-Viewer")) |
|
1058 |
|
1059 # Create the log viewer part of the user interface |
|
1060 logging.debug("Creating Log Viewer...") |
|
1061 from .LogView import LogViewer |
|
1062 self.logViewer = LogViewer(self) |
|
1063 self.bottomSidebar.addTab(self.logViewer, |
|
1064 UI.PixmapCache.getIcon("logViewer.png"), |
|
1065 self.tr("Log-Viewer")) |
|
1066 |
|
1067 # Create the shell |
|
1068 logging.debug("Creating Shell...") |
|
1069 from QScintilla.Shell import ShellAssembly |
|
1070 self.shellAssembly = \ |
|
1071 ShellAssembly(debugServer, self.viewmanager, self.project, True) |
|
1072 self.shell = self.shellAssembly.shell() |
|
1073 self.bottomSidebar.insertTab(0, self.shellAssembly, |
|
1074 UI.PixmapCache.getIcon("shell.png"), |
|
1075 self.tr("Shell")) |
|
1076 |
|
1077 if Preferences.getUI("ShowFileBrowser"): |
|
1078 # Create the file browser |
|
1079 logging.debug("Creating File Browser...") |
|
1080 from .Browser import Browser |
|
1081 self.browser = Browser() |
|
1082 self.leftSidebar.addTab(self.browser, |
|
1083 UI.PixmapCache.getIcon("browser.png"), |
|
1084 self.tr("File-Browser")) |
|
1085 |
|
1086 if Preferences.getUI("ShowSymbolsViewer"): |
|
1087 # Create the symbols viewer |
|
1088 logging.debug("Creating Symbols Viewer...") |
|
1089 from .SymbolsWidget import SymbolsWidget |
|
1090 self.symbolsViewer = SymbolsWidget() |
|
1091 self.leftSidebar.addTab(self.symbolsViewer, |
|
1092 UI.PixmapCache.getIcon("symbols.png"), |
|
1093 self.tr("Symbols")) |
|
1094 |
|
1095 if Preferences.getUI("ShowNumbersViewer"): |
|
1096 # Create the numbers viewer |
|
1097 logging.debug("Creating Numbers Viewer...") |
|
1098 from .NumbersWidget import NumbersWidget |
|
1099 self.numbersViewer = NumbersWidget() |
|
1100 self.bottomSidebar.addTab(self.numbersViewer, |
|
1101 UI.PixmapCache.getIcon("numbers.png"), |
|
1102 self.tr("Numbers")) |
|
1103 |
|
1104 self.bottomSidebar.setCurrentIndex(0) |
|
1105 |
|
1106 # create the central widget |
|
1107 logging.debug("Creating central widget...") |
|
1108 cw = self.centralWidget() # save the current central widget |
|
1109 self.leftSplitter = QSplitter(Qt.Horizontal) |
|
1110 self.rightSplitter = QSplitter(Qt.Horizontal) |
|
1111 self.verticalSplitter = QSplitter(Qt.Vertical) |
|
1112 self.verticalSplitter.addWidget(cw) |
|
1113 self.verticalSplitter.addWidget(self.bottomSidebar) |
|
1114 self.rightSplitter.addWidget(self.verticalSplitter) |
|
1115 self.rightSplitter.addWidget(self.rightSidebar) |
|
1116 self.leftSplitter.addWidget(self.leftSidebar) |
|
1117 self.leftSplitter.addWidget(self.rightSplitter) |
|
1118 self.setCentralWidget(self.leftSplitter) |
|
1119 |
|
1120 self.leftSidebar.setSplitter(self.leftSplitter) |
|
1121 self.rightSidebar.setSplitter(self.rightSplitter) |
|
1122 self.bottomSidebar.setSplitter(self.verticalSplitter) |
|
1123 |
|
1124 def __configureDockareaCornerUsage(self): |
|
1125 """ |
|
1126 Private method to configure the usage of the dockarea corners. |
|
1127 """ |
|
1128 if Preferences.getUI("TopLeftByLeft"): |
|
1129 self.setCorner(Qt.TopLeftCorner, Qt.LeftDockWidgetArea) |
|
1130 else: |
|
1131 self.setCorner(Qt.TopLeftCorner, Qt.TopDockWidgetArea) |
|
1132 if Preferences.getUI("BottomLeftByLeft"): |
|
1133 self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea) |
|
1134 else: |
|
1135 self.setCorner(Qt.BottomLeftCorner, Qt.BottomDockWidgetArea) |
|
1136 if Preferences.getUI("TopRightByRight"): |
|
1137 self.setCorner(Qt.TopRightCorner, Qt.RightDockWidgetArea) |
|
1138 else: |
|
1139 self.setCorner(Qt.TopRightCorner, Qt.TopDockWidgetArea) |
|
1140 if Preferences.getUI("BottomRightByRight"): |
|
1141 self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea) |
|
1142 else: |
|
1143 self.setCorner(Qt.BottomRightCorner, Qt.BottomDockWidgetArea) |
|
1144 |
|
1145 def addSideWidget(self, side, widget, icon, label): |
|
1146 """ |
|
1147 Public method to add a widget to the sides. |
|
1148 |
|
1149 @param side side to add the widget to (UserInterface.LeftSide, |
|
1150 UserInterface.BottomSide) |
|
1151 @param widget reference to the widget to add (QWidget) |
|
1152 @param icon icon to be used (QIcon) |
|
1153 @param label label text to be shown (string) |
|
1154 """ |
|
1155 assert side in [UserInterface.LeftSide, UserInterface.BottomSide, |
|
1156 UserInterface.RightSide] |
|
1157 |
|
1158 if self.__layoutType == "Toolboxes": |
|
1159 if side == UserInterface.LeftSide: |
|
1160 self.lToolbox.addItem(widget, icon, label) |
|
1161 elif side == UserInterface.BottomSide: |
|
1162 self.hToolbox.addItem(widget, icon, label) |
|
1163 elif side == UserInterface.RightSide: |
|
1164 self.rToolbox.addItem(widget, icon, label) |
|
1165 elif self.__layoutType == "Sidebars": |
|
1166 if side == UserInterface.LeftSide: |
|
1167 self.leftSidebar.addTab(widget, icon, label) |
|
1168 elif side == UserInterface.BottomSide: |
|
1169 self.bottomSidebar.addTab(widget, icon, label) |
|
1170 elif side == UserInterface.RightSide: |
|
1171 self.rightSidebar.addTab(widget, icon, label) |
|
1172 |
|
1173 def removeSideWidget(self, widget): |
|
1174 """ |
|
1175 Public method to remove a widget added using addSideWidget(). |
|
1176 |
|
1177 @param widget reference to the widget to remove (QWidget) |
|
1178 """ |
|
1179 if self.__layoutType == "Toolboxes": |
|
1180 for container in [self.lToolbox, self.hToolbox, self.rToolbox]: |
|
1181 index = container.indexOf(widget) |
|
1182 if index != -1: |
|
1183 container.removeItem(index) |
|
1184 elif self.__layoutType == "Sidebars": |
|
1185 for container in [self.leftSidebar, self.bottomSidebar, |
|
1186 self.rightSidebar]: |
|
1187 index = container.indexOf(widget) |
|
1188 if index != -1: |
|
1189 container.removeTab(index) |
|
1190 |
|
1191 def showLogViewer(self): |
|
1192 """ |
|
1193 Public method to show the Log-Viewer. |
|
1194 """ |
|
1195 if Preferences.getUI("LogViewerAutoRaise"): |
|
1196 if self.__layoutType == "Toolboxes": |
|
1197 self.hToolboxDock.show() |
|
1198 self.hToolbox.setCurrentWidget(self.logViewer) |
|
1199 self.hToolboxDock.raise_() |
|
1200 elif self.__layoutType == "Sidebars": |
|
1201 self.bottomSidebar.show() |
|
1202 self.bottomSidebar.setCurrentWidget(self.logViewer) |
|
1203 self.bottomSidebar.raise_() |
|
1204 if self.bottomSidebar.isAutoHiding(): |
|
1205 self.bottomSidebar.setFocus() |
|
1206 |
|
1207 def __openOnStartup(self, startupType=None): |
|
1208 """ |
|
1209 Private method to open the last file, project or multiproject. |
|
1210 |
|
1211 @param startupType type of startup requested (string, one of |
|
1212 "Nothing", "File", "Project", "MultiProject" or "Session") |
|
1213 """ |
|
1214 startupTypeMapping = { |
|
1215 "Nothing": 0, |
|
1216 "File": 1, |
|
1217 "Project": 2, |
|
1218 "MultiProject": 3, |
|
1219 "Session": 4, |
|
1220 } |
|
1221 |
|
1222 if startupType is None: |
|
1223 startup = Preferences.getUI("OpenOnStartup") |
|
1224 else: |
|
1225 try: |
|
1226 startup = startupTypeMapping[startupType] |
|
1227 except KeyError: |
|
1228 startup = Preferences.getUI("OpenOnStartup") |
|
1229 |
|
1230 if startup == 0: |
|
1231 # open nothing |
|
1232 pass |
|
1233 elif startup == 1: |
|
1234 # open last file |
|
1235 recent = self.viewmanager.getMostRecent() |
|
1236 if recent is not None: |
|
1237 self.viewmanager.openFiles(recent) |
|
1238 elif startup == 2: |
|
1239 # open last project |
|
1240 recent = self.project.getMostRecent() |
|
1241 if recent is not None: |
|
1242 self.project.openProject(recent) |
|
1243 elif startup == 3: |
|
1244 # open last multiproject |
|
1245 recent = self.multiProject.getMostRecent() |
|
1246 if recent is not None: |
|
1247 self.multiProject.openMultiProject(recent) |
|
1248 elif startup == 4: |
|
1249 # open from session file |
|
1250 self.__readSession() |
|
1251 |
|
1252 def processArgs(self, args): |
|
1253 """ |
|
1254 Public method to process the command line args passed to the UI. |
|
1255 |
|
1256 @param args list of files to open<br /> |
|
1257 The args are processed one at a time. All arguments after a |
|
1258 '--' option are considered debug arguments to the program |
|
1259 for the debugger. All files named before the '--' option |
|
1260 are opened in a text editor, unless the argument ends in |
|
1261 .e4p, then it is opened as a project file. If it ends in |
|
1262 .e4m or .e5m, it is opened as a multiproject. |
|
1263 """ |
|
1264 # check and optionally read a crash session and ignore any arguments |
|
1265 if self.__readCrashSession(): |
|
1266 return |
|
1267 |
|
1268 # no args, return |
|
1269 if args is None: |
|
1270 if not self.__noOpenAtStartup: |
|
1271 self.__openOnStartup() |
|
1272 return |
|
1273 |
|
1274 opens = 0 |
|
1275 |
|
1276 # holds space delimited list of command args, if any |
|
1277 argsStr = None |
|
1278 # flag indicating '--' options was found |
|
1279 ddseen = False |
|
1280 |
|
1281 if Utilities.isWindowsPlatform(): |
|
1282 argChars = ['-', '/'] |
|
1283 else: |
|
1284 argChars = ['-'] |
|
1285 |
|
1286 for arg in args: |
|
1287 # handle a request to start with last session |
|
1288 if arg == '--start-file': |
|
1289 self.__openOnStartup("File") |
|
1290 # ignore all further arguments |
|
1291 return |
|
1292 elif arg == '--start-multi': |
|
1293 self.__openOnStartup("MultiProject") |
|
1294 # ignore all further arguments |
|
1295 return |
|
1296 elif arg == '--start-project': |
|
1297 self.__openOnStartup("Project") |
|
1298 # ignore all further arguments |
|
1299 return |
|
1300 elif arg == '--start-session': |
|
1301 self.__openOnStartup("Session") |
|
1302 # ignore all further arguments |
|
1303 return |
|
1304 |
|
1305 if arg == '--' and not ddseen: |
|
1306 ddseen = True |
|
1307 continue |
|
1308 |
|
1309 if arg[0] in argChars or ddseen: |
|
1310 if argsStr is None: |
|
1311 argsStr = arg |
|
1312 else: |
|
1313 argsStr = "{0} {1}".format(argsStr, arg) |
|
1314 continue |
|
1315 |
|
1316 try: |
|
1317 ext = os.path.splitext(arg)[1] |
|
1318 ext = os.path.normcase(ext) |
|
1319 except IndexError: |
|
1320 ext = "" |
|
1321 |
|
1322 if ext in ['.e4p']: |
|
1323 self.project.openProject(arg) |
|
1324 opens += 1 |
|
1325 elif ext in ['.e4m', '.e5m']: |
|
1326 self.multiProject.openMultiProject(arg) |
|
1327 opens += 1 |
|
1328 else: |
|
1329 self.viewmanager.openFiles(arg) |
|
1330 opens += 1 |
|
1331 |
|
1332 # store away any args we had |
|
1333 if argsStr is not None: |
|
1334 self.debuggerUI.setArgvHistory(argsStr) |
|
1335 |
|
1336 if opens == 0: |
|
1337 # no files, project or multiproject was given |
|
1338 if not self.__noOpenAtStartup: |
|
1339 self.__openOnStartup() |
|
1340 |
|
1341 def __createDockWindow(self, name): |
|
1342 """ |
|
1343 Private method to create a dock window with common properties. |
|
1344 |
|
1345 @param name object name of the new dock window (string) |
|
1346 @return the generated dock window (QDockWindow) |
|
1347 """ |
|
1348 dock = QDockWidget() |
|
1349 dock.setObjectName(name) |
|
1350 dock.setFeatures( |
|
1351 QDockWidget.DockWidgetFeatures(QDockWidget.AllDockWidgetFeatures)) |
|
1352 return dock |
|
1353 |
|
1354 def __setupDockWindow(self, dock, where, widget, caption): |
|
1355 """ |
|
1356 Private method to configure the dock window created with |
|
1357 __createDockWindow(). |
|
1358 |
|
1359 @param dock the dock window (QDockWindow) |
|
1360 @param where dock area to be docked to (Qt.DockWidgetArea) |
|
1361 @param widget widget to be shown in the dock window (QWidget) |
|
1362 @param caption caption of the dock window (string) |
|
1363 """ |
|
1364 if caption is None: |
|
1365 caption = "" |
|
1366 self.addDockWidget(where, dock) |
|
1367 dock.setWidget(widget) |
|
1368 dock.setWindowTitle(caption) |
|
1369 dock.show() |
|
1370 |
|
1371 def __setWindowCaption(self, editor=None, project=None): |
|
1372 """ |
|
1373 Private method to set the caption of the Main Window. |
|
1374 |
|
1375 @param editor filename to be displayed (string) |
|
1376 @param project project name to be displayed (string) |
|
1377 """ |
|
1378 if editor is not None and self.captionShowsFilename: |
|
1379 self.capEditor = \ |
|
1380 Utilities.compactPath(editor, self.maxFilePathLen) |
|
1381 if project is not None: |
|
1382 self.capProject = project |
|
1383 |
|
1384 if self.passiveMode: |
|
1385 if not self.capProject and not self.capEditor: |
|
1386 self.setWindowTitle( |
|
1387 self.tr("{0} - Passive Mode").format(Program)) |
|
1388 elif self.capProject and not self.capEditor: |
|
1389 self.setWindowTitle( |
|
1390 self.tr("{0} - {1} - Passive Mode") |
|
1391 .format(self.capProject, Program)) |
|
1392 elif not self.capProject and self.capEditor: |
|
1393 self.setWindowTitle( |
|
1394 self.tr("{0} - {1} - Passive Mode") |
|
1395 .format(self.capEditor, Program)) |
|
1396 else: |
|
1397 self.setWindowTitle( |
|
1398 self.tr("{0} - {1} - {2} - Passive Mode") |
|
1399 .format(self.capProject, self.capEditor, Program)) |
|
1400 else: |
|
1401 if not self.capProject and not self.capEditor: |
|
1402 self.setWindowTitle(Program) |
|
1403 elif self.capProject and not self.capEditor: |
|
1404 self.setWindowTitle( |
|
1405 "{0} - {1}".format(self.capProject, Program)) |
|
1406 elif not self.capProject and self.capEditor: |
|
1407 self.setWindowTitle( |
|
1408 "{0} - {1}".format(self.capEditor, Program)) |
|
1409 else: |
|
1410 self.setWindowTitle("{0} - {1} - {2}".format( |
|
1411 self.capProject, self.capEditor, Program)) |
|
1412 |
|
1413 def __initActions(self): |
|
1414 """ |
|
1415 Private method to define the user interface actions. |
|
1416 """ |
|
1417 self.actions = [] |
|
1418 self.wizardsActions = [] |
|
1419 |
|
1420 self.exitAct = E5Action( |
|
1421 self.tr('Quit'), |
|
1422 UI.PixmapCache.getIcon("exit.png"), |
|
1423 self.tr('&Quit'), |
|
1424 QKeySequence(self.tr("Ctrl+Q", "File|Quit")), |
|
1425 0, self, 'quit') |
|
1426 self.exitAct.setStatusTip(self.tr('Quit the IDE')) |
|
1427 self.exitAct.setWhatsThis(self.tr( |
|
1428 """<b>Quit the IDE</b>""" |
|
1429 """<p>This quits the IDE. Any unsaved changes may be saved""" |
|
1430 """ first. Any Python program being debugged will be stopped""" |
|
1431 """ and the preferences will be written to disc.</p>""" |
|
1432 )) |
|
1433 self.exitAct.triggered.connect(self.__quit) |
|
1434 self.exitAct.setMenuRole(QAction.QuitRole) |
|
1435 self.actions.append(self.exitAct) |
|
1436 |
|
1437 self.restartAct = E5Action( |
|
1438 self.tr('Restart'), |
|
1439 UI.PixmapCache.getIcon("restart.png"), |
|
1440 self.tr('Restart'), |
|
1441 QKeySequence(self.tr("Ctrl+Shift+Q", "File|Quit")), |
|
1442 0, self, 'restart_eric') |
|
1443 self.restartAct.setStatusTip(self.tr('Restart the IDE')) |
|
1444 self.restartAct.setWhatsThis(self.tr( |
|
1445 """<b>Restart the IDE</b>""" |
|
1446 """<p>This restarts the IDE. Any unsaved changes may be saved""" |
|
1447 """ first. Any Python program being debugged will be stopped""" |
|
1448 """ and the preferences will be written to disc.</p>""" |
|
1449 )) |
|
1450 self.restartAct.triggered.connect(self.__restart) |
|
1451 self.actions.append(self.restartAct) |
|
1452 |
|
1453 self.saveSessionAct = E5Action( |
|
1454 self.tr('Save session'), |
|
1455 self.tr('Save session...'), |
|
1456 0, 0, self, 'save_session_to_file') |
|
1457 self.saveSessionAct.setStatusTip(self.tr('Save session')) |
|
1458 self.saveSessionAct.setWhatsThis(self.tr( |
|
1459 """<b>Save session...</b>""" |
|
1460 """<p>This saves the current session to disk. A dialog is""" |
|
1461 """ opened to select the file name.</p>""" |
|
1462 )) |
|
1463 self.saveSessionAct.triggered.connect(self.__saveSessionToFile) |
|
1464 self.actions.append(self.saveSessionAct) |
|
1465 |
|
1466 self.loadSessionAct = E5Action( |
|
1467 self.tr('Load session'), |
|
1468 self.tr('Load session...'), |
|
1469 0, 0, self, 'load_session_from_file') |
|
1470 self.loadSessionAct.setStatusTip(self.tr('Load session')) |
|
1471 self.loadSessionAct.setWhatsThis(self.tr( |
|
1472 """<b>Load session...</b>""" |
|
1473 """<p>This loads a session saved to disk previously. A dialog is""" |
|
1474 """ opened to select the file name.</p>""" |
|
1475 )) |
|
1476 self.loadSessionAct.triggered.connect(self.__loadSessionFromFile) |
|
1477 self.actions.append(self.loadSessionAct) |
|
1478 |
|
1479 self.newWindowAct = E5Action( |
|
1480 self.tr('New Window'), |
|
1481 UI.PixmapCache.getIcon("newWindow.png"), |
|
1482 self.tr('New &Window'), |
|
1483 QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")), |
|
1484 0, self, 'new_window') |
|
1485 self.newWindowAct.setStatusTip(self.tr( |
|
1486 'Open a new eric6 instance')) |
|
1487 self.newWindowAct.setWhatsThis(self.tr( |
|
1488 """<b>New Window</b>""" |
|
1489 """<p>This opens a new instance of the eric6 IDE.</p>""" |
|
1490 )) |
|
1491 self.newWindowAct.triggered.connect(self.__newWindow) |
|
1492 self.actions.append(self.newWindowAct) |
|
1493 self.newWindowAct.setEnabled( |
|
1494 not Preferences.getUI("SingleApplicationMode")) |
|
1495 |
|
1496 self.viewProfileActGrp = createActionGroup(self, "viewprofiles", True) |
|
1497 |
|
1498 self.setEditProfileAct = E5Action( |
|
1499 self.tr('Edit Profile'), |
|
1500 UI.PixmapCache.getIcon("viewProfileEdit.png"), |
|
1501 self.tr('Edit Profile'), |
|
1502 0, 0, |
|
1503 self.viewProfileActGrp, 'edit_profile', True) |
|
1504 self.setEditProfileAct.setStatusTip(self.tr( |
|
1505 'Activate the edit view profile')) |
|
1506 self.setEditProfileAct.setWhatsThis(self.tr( |
|
1507 """<b>Edit Profile</b>""" |
|
1508 """<p>Activate the "Edit View Profile". Windows being shown,""" |
|
1509 """ if this profile is active, may be configured with the""" |
|
1510 """ "View Profile Configuration" dialog.</p>""" |
|
1511 )) |
|
1512 self.setEditProfileAct.triggered.connect(self.__setEditProfile) |
|
1513 self.actions.append(self.setEditProfileAct) |
|
1514 |
|
1515 self.setDebugProfileAct = E5Action( |
|
1516 self.tr('Debug Profile'), |
|
1517 UI.PixmapCache.getIcon("viewProfileDebug.png"), |
|
1518 self.tr('Debug Profile'), |
|
1519 0, 0, |
|
1520 self.viewProfileActGrp, 'debug_profile', True) |
|
1521 self.setDebugProfileAct.setStatusTip( |
|
1522 self.tr('Activate the debug view profile')) |
|
1523 self.setDebugProfileAct.setWhatsThis(self.tr( |
|
1524 """<b>Debug Profile</b>""" |
|
1525 """<p>Activate the "Debug View Profile". Windows being shown,""" |
|
1526 """ if this profile is active, may be configured with the""" |
|
1527 """ "View Profile Configuration" dialog.</p>""" |
|
1528 )) |
|
1529 self.setDebugProfileAct.triggered.connect(self.setDebugProfile) |
|
1530 self.actions.append(self.setDebugProfileAct) |
|
1531 |
|
1532 self.pbActivateAct = E5Action( |
|
1533 self.tr('Project-Viewer'), |
|
1534 self.tr('&Project-Viewer'), |
|
1535 QKeySequence(self.tr("Alt+Shift+P")), |
|
1536 0, self, |
|
1537 'project_viewer_activate') |
|
1538 self.pbActivateAct.setStatusTip(self.tr( |
|
1539 "Switch the input focus to the Project-Viewer window.")) |
|
1540 self.pbActivateAct.setWhatsThis(self.tr( |
|
1541 """<b>Activate Project-Viewer</b>""" |
|
1542 """<p>This switches the input focus to the Project-Viewer""" |
|
1543 """ window.</p>""" |
|
1544 )) |
|
1545 self.pbActivateAct.triggered.connect(self.__activateProjectBrowser) |
|
1546 self.actions.append(self.pbActivateAct) |
|
1547 self.addAction(self.pbActivateAct) |
|
1548 |
|
1549 self.mpbActivateAct = E5Action( |
|
1550 self.tr('Multiproject-Viewer'), |
|
1551 self.tr('&Multiproject-Viewer'), |
|
1552 QKeySequence(self.tr("Alt+Shift+M")), |
|
1553 0, self, |
|
1554 'multi_project_viewer_activate') |
|
1555 self.mpbActivateAct.setStatusTip(self.tr( |
|
1556 "Switch the input focus to the Multiproject-Viewer window.")) |
|
1557 self.mpbActivateAct.setWhatsThis(self.tr( |
|
1558 """<b>Activate Multiproject-Viewer</b>""" |
|
1559 """<p>This switches the input focus to the Multiproject-Viewer""" |
|
1560 """ window.</p>""" |
|
1561 )) |
|
1562 self.mpbActivateAct.triggered.connect( |
|
1563 self.__activateMultiProjectBrowser) |
|
1564 self.actions.append(self.mpbActivateAct) |
|
1565 self.addAction(self.mpbActivateAct) |
|
1566 |
|
1567 self.debugViewerActivateAct = E5Action( |
|
1568 self.tr('Debug-Viewer'), |
|
1569 self.tr('&Debug-Viewer'), |
|
1570 QKeySequence(self.tr("Alt+Shift+D")), |
|
1571 0, self, |
|
1572 'debug_viewer_activate') |
|
1573 self.debugViewerActivateAct.setStatusTip(self.tr( |
|
1574 "Switch the input focus to the Debug-Viewer window.")) |
|
1575 self.debugViewerActivateAct.setWhatsThis(self.tr( |
|
1576 """<b>Activate Debug-Viewer</b>""" |
|
1577 """<p>This switches the input focus to the Debug-Viewer""" |
|
1578 """ window.</p>""" |
|
1579 )) |
|
1580 self.debugViewerActivateAct.triggered.connect( |
|
1581 self.activateDebugViewer) |
|
1582 self.actions.append(self.debugViewerActivateAct) |
|
1583 self.addAction(self.debugViewerActivateAct) |
|
1584 |
|
1585 self.shellActivateAct = E5Action( |
|
1586 self.tr('Shell'), |
|
1587 self.tr('&Shell'), |
|
1588 QKeySequence(self.tr("Alt+Shift+S")), |
|
1589 0, self, |
|
1590 'interpreter_shell_activate') |
|
1591 self.shellActivateAct.setStatusTip(self.tr( |
|
1592 "Switch the input focus to the Shell window.")) |
|
1593 self.shellActivateAct.setWhatsThis(self.tr( |
|
1594 """<b>Activate Shell</b>""" |
|
1595 """<p>This switches the input focus to the Shell window.</p>""" |
|
1596 )) |
|
1597 self.shellActivateAct.triggered.connect(self.__activateShell) |
|
1598 self.actions.append(self.shellActivateAct) |
|
1599 self.addAction(self.shellActivateAct) |
|
1600 |
|
1601 if self.browser is not None: |
|
1602 self.browserActivateAct = E5Action( |
|
1603 self.tr('File-Browser'), |
|
1604 self.tr('&File-Browser'), |
|
1605 QKeySequence(self.tr("Alt+Shift+F")), |
|
1606 0, self, |
|
1607 'file_browser_activate') |
|
1608 self.browserActivateAct.setStatusTip(self.tr( |
|
1609 "Switch the input focus to the File-Browser window.")) |
|
1610 self.browserActivateAct.setWhatsThis(self.tr( |
|
1611 """<b>Activate File-Browser</b>""" |
|
1612 """<p>This switches the input focus to the File-Browser""" |
|
1613 """ window.</p>""" |
|
1614 )) |
|
1615 self.browserActivateAct.triggered.connect(self.__activateBrowser) |
|
1616 self.actions.append(self.browserActivateAct) |
|
1617 self.addAction(self.browserActivateAct) |
|
1618 |
|
1619 self.logViewerActivateAct = E5Action( |
|
1620 self.tr('Log-Viewer'), |
|
1621 self.tr('Lo&g-Viewer'), |
|
1622 QKeySequence(self.tr("Alt+Shift+G")), |
|
1623 0, self, |
|
1624 'log_viewer_activate') |
|
1625 self.logViewerActivateAct.setStatusTip(self.tr( |
|
1626 "Switch the input focus to the Log-Viewer window.")) |
|
1627 self.logViewerActivateAct.setWhatsThis(self.tr( |
|
1628 """<b>Activate Log-Viewer</b>""" |
|
1629 """<p>This switches the input focus to the Log-Viewer""" |
|
1630 """ window.</p>""" |
|
1631 )) |
|
1632 self.logViewerActivateAct.triggered.connect( |
|
1633 self.__activateLogViewer) |
|
1634 self.actions.append(self.logViewerActivateAct) |
|
1635 self.addAction(self.logViewerActivateAct) |
|
1636 |
|
1637 self.taskViewerActivateAct = E5Action( |
|
1638 self.tr('Task-Viewer'), |
|
1639 self.tr('&Task-Viewer'), |
|
1640 QKeySequence(self.tr("Alt+Shift+T")), |
|
1641 0, self, |
|
1642 'task_viewer_activate') |
|
1643 self.taskViewerActivateAct.setStatusTip(self.tr( |
|
1644 "Switch the input focus to the Task-Viewer window.")) |
|
1645 self.taskViewerActivateAct.setWhatsThis(self.tr( |
|
1646 """<b>Activate Task-Viewer</b>""" |
|
1647 """<p>This switches the input focus to the Task-Viewer""" |
|
1648 """ window.</p>""" |
|
1649 )) |
|
1650 self.taskViewerActivateAct.triggered.connect( |
|
1651 self.__activateTaskViewer) |
|
1652 self.actions.append(self.taskViewerActivateAct) |
|
1653 self.addAction(self.taskViewerActivateAct) |
|
1654 |
|
1655 if self.templateViewer is not None: |
|
1656 self.templateViewerActivateAct = E5Action( |
|
1657 self.tr('Template-Viewer'), |
|
1658 self.tr('Templ&ate-Viewer'), |
|
1659 QKeySequence(self.tr("Alt+Shift+A")), |
|
1660 0, self, |
|
1661 'template_viewer_activate') |
|
1662 self.templateViewerActivateAct.setStatusTip(self.tr( |
|
1663 "Switch the input focus to the Template-Viewer window.")) |
|
1664 self.templateViewerActivateAct.setWhatsThis(self.tr( |
|
1665 """<b>Activate Template-Viewer</b>""" |
|
1666 """<p>This switches the input focus to the Template-Viewer""" |
|
1667 """ window.</p>""" |
|
1668 )) |
|
1669 self.templateViewerActivateAct.triggered.connect( |
|
1670 self.__activateTemplateViewer) |
|
1671 self.actions.append(self.templateViewerActivateAct) |
|
1672 self.addAction(self.templateViewerActivateAct) |
|
1673 |
|
1674 self.ltAct = E5Action( |
|
1675 self.tr('Left Toolbox'), |
|
1676 self.tr('&Left Toolbox'), 0, 0, self, 'vertical_toolbox', True) |
|
1677 self.ltAct.setStatusTip(self.tr('Toggle the Left Toolbox window')) |
|
1678 self.ltAct.setWhatsThis(self.tr( |
|
1679 """<b>Toggle the Left Toolbox window</b>""" |
|
1680 """<p>If the Left Toolbox window is hidden then display it.""" |
|
1681 """ If it is displayed then close it.</p>""" |
|
1682 )) |
|
1683 self.ltAct.triggered.connect(self.__toggleLeftToolbox) |
|
1684 self.actions.append(self.ltAct) |
|
1685 |
|
1686 self.rtAct = E5Action( |
|
1687 self.tr('Right Toolbox'), |
|
1688 self.tr('&Right Toolbox'), |
|
1689 0, 0, self, 'vertical_toolbox', True) |
|
1690 self.rtAct.setStatusTip(self.tr('Toggle the Right Toolbox window')) |
|
1691 self.rtAct.setWhatsThis(self.tr( |
|
1692 """<b>Toggle the Right Toolbox window</b>""" |
|
1693 """<p>If the Right Toolbox window is hidden then display it.""" |
|
1694 """ If it is displayed then close it.</p>""" |
|
1695 )) |
|
1696 self.rtAct.triggered.connect(self.__toggleRightToolbox) |
|
1697 self.actions.append(self.rtAct) |
|
1698 |
|
1699 self.htAct = E5Action( |
|
1700 self.tr('Horizontal Toolbox'), |
|
1701 self.tr('&Horizontal Toolbox'), 0, 0, self, |
|
1702 'horizontal_toolbox', True) |
|
1703 self.htAct.setStatusTip(self.tr( |
|
1704 'Toggle the Horizontal Toolbox window')) |
|
1705 self.htAct.setWhatsThis(self.tr( |
|
1706 """<b>Toggle the Horizontal Toolbox window</b>""" |
|
1707 """<p>If the Horizontal Toolbox window is hidden then display""" |
|
1708 """ it. If it is displayed then close it.</p>""" |
|
1709 )) |
|
1710 self.htAct.triggered.connect(self.__toggleHorizontalToolbox) |
|
1711 self.actions.append(self.htAct) |
|
1712 |
|
1713 self.lsbAct = E5Action( |
|
1714 self.tr('Left Sidebar'), |
|
1715 self.tr('&Left Sidebar'), |
|
1716 0, 0, self, 'left_sidebar', True) |
|
1717 self.lsbAct.setStatusTip(self.tr('Toggle the left sidebar window')) |
|
1718 self.lsbAct.setWhatsThis(self.tr( |
|
1719 """<b>Toggle the left sidebar window</b>""" |
|
1720 """<p>If the left sidebar window is hidden then display it.""" |
|
1721 """ If it is displayed then close it.</p>""" |
|
1722 )) |
|
1723 self.lsbAct.triggered.connect(self.__toggleLeftSidebar) |
|
1724 self.actions.append(self.lsbAct) |
|
1725 |
|
1726 self.rsbAct = E5Action( |
|
1727 self.tr('Right Sidebar'), |
|
1728 self.tr('&Right Sidebar'), |
|
1729 0, 0, self, 'right_sidebar', True) |
|
1730 self.rsbAct.setStatusTip(self.tr( |
|
1731 'Toggle the right sidebar window')) |
|
1732 self.rsbAct.setWhatsThis(self.tr( |
|
1733 """<b>Toggle the right sidebar window</b>""" |
|
1734 """<p>If the right sidebar window is hidden then display it.""" |
|
1735 """ If it is displayed then close it.</p>""" |
|
1736 )) |
|
1737 self.rsbAct.triggered.connect(self.__toggleRightSidebar) |
|
1738 self.actions.append(self.rsbAct) |
|
1739 |
|
1740 self.bsbAct = E5Action( |
|
1741 self.tr('Bottom Sidebar'), |
|
1742 self.tr('&Bottom Sidebar'), 0, 0, self, |
|
1743 'bottom_sidebar', True) |
|
1744 self.bsbAct.setStatusTip(self.tr( |
|
1745 'Toggle the bottom sidebar window')) |
|
1746 self.bsbAct.setWhatsThis(self.tr( |
|
1747 """<b>Toggle the bottom sidebar window</b>""" |
|
1748 """<p>If the bottom sidebar window is hidden then display it.""" |
|
1749 """ If it is displayed then close it.</p>""" |
|
1750 )) |
|
1751 self.bsbAct.triggered.connect(self.__toggleBottomSidebar) |
|
1752 self.actions.append(self.bsbAct) |
|
1753 |
|
1754 if self.cooperation is not None: |
|
1755 self.cooperationViewerActivateAct = E5Action( |
|
1756 self.tr('Cooperation-Viewer'), |
|
1757 self.tr('Co&operation-Viewer'), |
|
1758 QKeySequence(self.tr("Alt+Shift+O")), |
|
1759 0, self, |
|
1760 'cooperation_viewer_activate') |
|
1761 self.cooperationViewerActivateAct.setStatusTip(self.tr( |
|
1762 "Switch the input focus to the Cooperation-Viewer window.")) |
|
1763 self.cooperationViewerActivateAct.setWhatsThis(self.tr( |
|
1764 """<b>Activate Cooperation-Viewer</b>""" |
|
1765 """<p>This switches the input focus to the""" |
|
1766 """ Cooperation-Viewer window.</p>""" |
|
1767 )) |
|
1768 self.cooperationViewerActivateAct.triggered.connect( |
|
1769 self.activateCooperationViewer) |
|
1770 self.actions.append(self.cooperationViewerActivateAct) |
|
1771 self.addAction(self.cooperationViewerActivateAct) |
|
1772 |
|
1773 if self.irc is not None: |
|
1774 self.ircActivateAct = E5Action( |
|
1775 self.tr('IRC'), |
|
1776 self.tr('&IRC'), |
|
1777 QKeySequence(self.tr("Meta+Shift+I")), |
|
1778 0, self, |
|
1779 'irc_widget_activate') |
|
1780 self.ircActivateAct.setStatusTip(self.tr( |
|
1781 "Switch the input focus to the IRC window.")) |
|
1782 self.ircActivateAct.setWhatsThis(self.tr( |
|
1783 """<b>Activate IRC</b>""" |
|
1784 """<p>This switches the input focus to the IRC window.</p>""" |
|
1785 )) |
|
1786 self.ircActivateAct.triggered.connect( |
|
1787 self.__activateIRC) |
|
1788 self.actions.append(self.ircActivateAct) |
|
1789 self.addAction(self.ircActivateAct) |
|
1790 |
|
1791 if self.symbolsViewer is not None: |
|
1792 self.symbolsViewerActivateAct = E5Action( |
|
1793 self.tr('Symbols-Viewer'), |
|
1794 self.tr('S&ymbols-Viewer'), |
|
1795 QKeySequence(self.tr("Alt+Shift+Y")), |
|
1796 0, self, |
|
1797 'symbols_viewer_activate') |
|
1798 self.symbolsViewerActivateAct.setStatusTip(self.tr( |
|
1799 "Switch the input focus to the Symbols-Viewer window.")) |
|
1800 self.symbolsViewerActivateAct.setWhatsThis(self.tr( |
|
1801 """<b>Activate Symbols-Viewer</b>""" |
|
1802 """<p>This switches the input focus to the Symbols-Viewer""" |
|
1803 """ window.</p>""" |
|
1804 )) |
|
1805 self.symbolsViewerActivateAct.triggered.connect( |
|
1806 self.__activateSymbolsViewer) |
|
1807 self.actions.append(self.symbolsViewerActivateAct) |
|
1808 self.addAction(self.symbolsViewerActivateAct) |
|
1809 |
|
1810 if self.numbersViewer is not None: |
|
1811 self.numbersViewerActivateAct = E5Action( |
|
1812 self.tr('Numbers-Viewer'), |
|
1813 self.tr('Num&bers-Viewer'), |
|
1814 QKeySequence(self.tr("Alt+Shift+B")), |
|
1815 0, self, |
|
1816 'numbers_viewer_activate') |
|
1817 self.numbersViewerActivateAct.setStatusTip(self.tr( |
|
1818 "Switch the input focus to the Numbers-Viewer window.")) |
|
1819 self.numbersViewerActivateAct.setWhatsThis(self.tr( |
|
1820 """<b>Activate Numbers-Viewer</b>""" |
|
1821 """<p>This switches the input focus to the Numbers-Viewer""" |
|
1822 """ window.</p>""" |
|
1823 )) |
|
1824 self.numbersViewerActivateAct.triggered.connect( |
|
1825 self.__activateNumbersViewer) |
|
1826 self.actions.append(self.numbersViewerActivateAct) |
|
1827 self.addAction(self.numbersViewerActivateAct) |
|
1828 |
|
1829 self.whatsThisAct = E5Action( |
|
1830 self.tr('What\'s This?'), |
|
1831 UI.PixmapCache.getIcon("whatsThis.png"), |
|
1832 self.tr('&What\'s This?'), |
|
1833 QKeySequence(self.tr("Shift+F1")), |
|
1834 0, self, 'whatsThis') |
|
1835 self.whatsThisAct.setStatusTip(self.tr('Context sensitive help')) |
|
1836 self.whatsThisAct.setWhatsThis(self.tr( |
|
1837 """<b>Display context sensitive help</b>""" |
|
1838 """<p>In What's This? mode, the mouse cursor shows an arrow with""" |
|
1839 """ a question mark, and you can click on the interface elements""" |
|
1840 """ to get a short description of what they do and how to use""" |
|
1841 """ them. In dialogs, this feature can be accessed using the""" |
|
1842 """ context help button in the titlebar.</p>""" |
|
1843 )) |
|
1844 self.whatsThisAct.triggered.connect(self.__whatsThis) |
|
1845 self.actions.append(self.whatsThisAct) |
|
1846 |
|
1847 self.helpviewerAct = E5Action( |
|
1848 self.tr('Helpviewer'), |
|
1849 UI.PixmapCache.getIcon("help.png"), |
|
1850 self.tr('&Helpviewer...'), |
|
1851 QKeySequence(self.tr("F1")), |
|
1852 0, self, 'helpviewer') |
|
1853 self.helpviewerAct.setStatusTip(self.tr( |
|
1854 'Open the helpviewer window')) |
|
1855 self.helpviewerAct.setWhatsThis(self.tr( |
|
1856 """<b>Helpviewer</b>""" |
|
1857 """<p>Display the eric6 web browser. This window will show""" |
|
1858 """ HTML help files and help from Qt help collections. It""" |
|
1859 """ has the capability to navigate to links, set bookmarks,""" |
|
1860 """ print the displayed help and some more features. You may""" |
|
1861 """ use it to browse the internet as well</p><p>If called""" |
|
1862 """ with a word selected, this word is search in the Qt help""" |
|
1863 """ collection.</p>""" |
|
1864 )) |
|
1865 self.helpviewerAct.triggered.connect(self.__helpViewer) |
|
1866 self.actions.append(self.helpviewerAct) |
|
1867 ## else: |
|
1868 ## self.helpviewerAct = None |
|
1869 |
|
1870 self.__initQtDocActions() |
|
1871 self.__initPythonDocActions() |
|
1872 self.__initEricDocAction() |
|
1873 self.__initPySideDocActions() |
|
1874 |
|
1875 self.versionAct = E5Action( |
|
1876 self.tr('Show Versions'), |
|
1877 self.tr('Show &Versions'), |
|
1878 0, 0, self, 'show_versions') |
|
1879 self.versionAct.setStatusTip(self.tr( |
|
1880 'Display version information')) |
|
1881 self.versionAct.setWhatsThis(self.tr( |
|
1882 """<b>Show Versions</b>""" |
|
1883 """<p>Display version information.</p>""" |
|
1884 )) |
|
1885 self.versionAct.triggered.connect(self.__showVersions) |
|
1886 self.actions.append(self.versionAct) |
|
1887 |
|
1888 self.checkUpdateAct = E5Action( |
|
1889 self.tr('Check for Updates'), |
|
1890 self.tr('Check for &Updates...'), 0, 0, self, 'check_updates') |
|
1891 self.checkUpdateAct.setStatusTip(self.tr('Check for Updates')) |
|
1892 self.checkUpdateAct.setWhatsThis(self.tr( |
|
1893 """<b>Check for Updates...</b>""" |
|
1894 """<p>Checks the internet for updates of eric6.</p>""" |
|
1895 )) |
|
1896 self.checkUpdateAct.triggered.connect(self.performVersionCheck) |
|
1897 self.actions.append(self.checkUpdateAct) |
|
1898 |
|
1899 self.showVersionsAct = E5Action( |
|
1900 self.tr('Show downloadable versions'), |
|
1901 self.tr('Show &downloadable versions...'), |
|
1902 0, 0, self, 'show_downloadable_versions') |
|
1903 self.showVersionsAct.setStatusTip( |
|
1904 self.tr('Show the versions available for download')) |
|
1905 self.showVersionsAct.setWhatsThis(self.tr( |
|
1906 """<b>Show downloadable versions...</b>""" |
|
1907 """<p>Shows the eric6 versions available for download """ |
|
1908 """from the internet.</p>""" |
|
1909 )) |
|
1910 self.showVersionsAct.triggered.connect( |
|
1911 self.showAvailableVersionsInfo) |
|
1912 self.actions.append(self.showVersionsAct) |
|
1913 |
|
1914 self.showErrorLogAct = E5Action( |
|
1915 self.tr('Show Error Log'), |
|
1916 self.tr('Show Error &Log...'), |
|
1917 0, 0, self, 'show_error_log') |
|
1918 self.showErrorLogAct.setStatusTip(self.tr('Show Error Log')) |
|
1919 self.showErrorLogAct.setWhatsThis(self.tr( |
|
1920 """<b>Show Error Log...</b>""" |
|
1921 """<p>Opens a dialog showing the most recent error log.</p>""" |
|
1922 )) |
|
1923 self.showErrorLogAct.triggered.connect(self.__showErrorLog) |
|
1924 self.actions.append(self.showErrorLogAct) |
|
1925 |
|
1926 self.reportBugAct = E5Action( |
|
1927 self.tr('Report Bug'), |
|
1928 self.tr('Report &Bug...'), |
|
1929 0, 0, self, 'report_bug') |
|
1930 self.reportBugAct.setStatusTip(self.tr('Report a bug')) |
|
1931 self.reportBugAct.setWhatsThis(self.tr( |
|
1932 """<b>Report Bug...</b>""" |
|
1933 """<p>Opens a dialog to report a bug.</p>""" |
|
1934 )) |
|
1935 self.reportBugAct.triggered.connect(self.__reportBug) |
|
1936 self.actions.append(self.reportBugAct) |
|
1937 |
|
1938 self.requestFeatureAct = E5Action( |
|
1939 self.tr('Request Feature'), |
|
1940 self.tr('Request &Feature...'), |
|
1941 0, 0, self, 'request_feature') |
|
1942 self.requestFeatureAct.setStatusTip(self.tr( |
|
1943 'Send a feature request')) |
|
1944 self.requestFeatureAct.setWhatsThis(self.tr( |
|
1945 """<b>Request Feature...</b>""" |
|
1946 """<p>Opens a dialog to send a feature request.</p>""" |
|
1947 )) |
|
1948 self.requestFeatureAct.triggered.connect(self.__requestFeature) |
|
1949 self.actions.append(self.requestFeatureAct) |
|
1950 |
|
1951 self.utActGrp = createActionGroup(self) |
|
1952 |
|
1953 self.utDialogAct = E5Action( |
|
1954 self.tr('Unittest'), |
|
1955 UI.PixmapCache.getIcon("unittest.png"), |
|
1956 self.tr('&Unittest...'), |
|
1957 0, 0, self.utActGrp, 'unittest') |
|
1958 self.utDialogAct.setStatusTip(self.tr('Start unittest dialog')) |
|
1959 self.utDialogAct.setWhatsThis(self.tr( |
|
1960 """<b>Unittest</b>""" |
|
1961 """<p>Perform unit tests. The dialog gives you the""" |
|
1962 """ ability to select and run a unittest suite.</p>""" |
|
1963 )) |
|
1964 self.utDialogAct.triggered.connect(self.__unittest) |
|
1965 self.actions.append(self.utDialogAct) |
|
1966 |
|
1967 self.utRestartAct = E5Action( |
|
1968 self.tr('Unittest Restart'), |
|
1969 UI.PixmapCache.getIcon("unittestRestart.png"), |
|
1970 self.tr('&Restart Unittest...'), |
|
1971 0, 0, self.utActGrp, 'unittest_restart') |
|
1972 self.utRestartAct.setStatusTip(self.tr('Restart last unittest')) |
|
1973 self.utRestartAct.setWhatsThis(self.tr( |
|
1974 """<b>Restart Unittest</b>""" |
|
1975 """<p>Restart the unittest performed last.</p>""" |
|
1976 )) |
|
1977 self.utRestartAct.triggered.connect(self.__unittestRestart) |
|
1978 self.utRestartAct.setEnabled(False) |
|
1979 self.actions.append(self.utRestartAct) |
|
1980 |
|
1981 self.utRerunFailedAct = E5Action( |
|
1982 self.tr('Unittest Rerun Failed'), |
|
1983 UI.PixmapCache.getIcon("unittestRerunFailed.png"), |
|
1984 self.tr('Rerun Failed Tests...'), |
|
1985 0, 0, self.utActGrp, 'unittest_rerun_failed') |
|
1986 self.utRerunFailedAct.setStatusTip(self.tr( |
|
1987 'Rerun failed tests of the last run')) |
|
1988 self.utRerunFailedAct.setWhatsThis(self.tr( |
|
1989 """<b>Rerun Failed Tests</b>""" |
|
1990 """<p>Rerun all tests that failed during the last unittest""" |
|
1991 """ run.</p>""" |
|
1992 )) |
|
1993 self.utRerunFailedAct.triggered.connect(self.__unittestRerunFailed) |
|
1994 self.utRerunFailedAct.setEnabled(False) |
|
1995 self.actions.append(self.utRerunFailedAct) |
|
1996 |
|
1997 self.utScriptAct = E5Action( |
|
1998 self.tr('Unittest Script'), |
|
1999 UI.PixmapCache.getIcon("unittestScript.png"), |
|
2000 self.tr('Unittest &Script...'), |
|
2001 0, 0, self.utActGrp, 'unittest_script') |
|
2002 self.utScriptAct.setStatusTip(self.tr( |
|
2003 'Run unittest with current script')) |
|
2004 self.utScriptAct.setWhatsThis(self.tr( |
|
2005 """<b>Unittest Script</b>""" |
|
2006 """<p>Run unittest with current script.</p>""" |
|
2007 )) |
|
2008 self.utScriptAct.triggered.connect(self.__unittestScript) |
|
2009 self.utScriptAct.setEnabled(False) |
|
2010 self.actions.append(self.utScriptAct) |
|
2011 |
|
2012 self.utProjectAct = E5Action( |
|
2013 self.tr('Unittest Project'), |
|
2014 UI.PixmapCache.getIcon("unittestProject.png"), |
|
2015 self.tr('Unittest &Project...'), |
|
2016 0, 0, self.utActGrp, 'unittest_project') |
|
2017 self.utProjectAct.setStatusTip(self.tr( |
|
2018 'Run unittest with current project')) |
|
2019 self.utProjectAct.setWhatsThis(self.tr( |
|
2020 """<b>Unittest Project</b>""" |
|
2021 """<p>Run unittest with current project.</p>""" |
|
2022 )) |
|
2023 self.utProjectAct.triggered.connect(self.__unittestProject) |
|
2024 self.utProjectAct.setEnabled(False) |
|
2025 self.actions.append(self.utProjectAct) |
|
2026 |
|
2027 # check for Qt4/Qt5 designer and linguist |
|
2028 if Utilities.isWindowsPlatform(): |
|
2029 designerExe = os.path.join( |
|
2030 Utilities.getQtBinariesPath(), |
|
2031 "{0}.exe".format(Utilities.generateQtToolName("designer"))) |
|
2032 elif Utilities.isMacPlatform(): |
|
2033 designerExe = Utilities.getQtMacBundle("designer") |
|
2034 else: |
|
2035 designerExe = os.path.join( |
|
2036 Utilities.getQtBinariesPath(), |
|
2037 Utilities.generateQtToolName("designer")) |
|
2038 if os.path.exists(designerExe): |
|
2039 self.designer4Act = E5Action( |
|
2040 self.tr('Qt-Designer'), |
|
2041 UI.PixmapCache.getIcon("designer4.png"), |
|
2042 self.tr('Qt-&Designer...'), |
|
2043 0, 0, self, 'qt_designer4') |
|
2044 self.designer4Act.setStatusTip(self.tr('Start Qt-Designer')) |
|
2045 self.designer4Act.setWhatsThis(self.tr( |
|
2046 """<b>Qt-Designer</b>""" |
|
2047 """<p>Start Qt-Designer.</p>""" |
|
2048 )) |
|
2049 self.designer4Act.triggered.connect(self.__designer4) |
|
2050 self.actions.append(self.designer4Act) |
|
2051 else: |
|
2052 self.designer4Act = None |
|
2053 |
|
2054 if Utilities.isWindowsPlatform(): |
|
2055 linguistExe = os.path.join( |
|
2056 Utilities.getQtBinariesPath(), |
|
2057 "{0}.exe".format(Utilities.generateQtToolName("linguist"))) |
|
2058 elif Utilities.isMacPlatform(): |
|
2059 linguistExe = Utilities.getQtMacBundle("linguist") |
|
2060 else: |
|
2061 linguistExe = os.path.join( |
|
2062 Utilities.getQtBinariesPath(), |
|
2063 Utilities.generateQtToolName("linguist")) |
|
2064 if os.path.exists(linguistExe): |
|
2065 self.linguist4Act = E5Action( |
|
2066 self.tr('Qt-Linguist'), |
|
2067 UI.PixmapCache.getIcon("linguist4.png"), |
|
2068 self.tr('Qt-&Linguist...'), |
|
2069 0, 0, self, 'qt_linguist4') |
|
2070 self.linguist4Act.setStatusTip(self.tr('Start Qt-Linguist')) |
|
2071 self.linguist4Act.setWhatsThis(self.tr( |
|
2072 """<b>Qt-Linguist</b>""" |
|
2073 """<p>Start Qt-Linguist.</p>""" |
|
2074 )) |
|
2075 self.linguist4Act.triggered.connect(self.__linguist4) |
|
2076 self.actions.append(self.linguist4Act) |
|
2077 else: |
|
2078 self.linguist4Act = None |
|
2079 |
|
2080 self.uipreviewerAct = E5Action( |
|
2081 self.tr('UI Previewer'), |
|
2082 UI.PixmapCache.getIcon("uiPreviewer.png"), |
|
2083 self.tr('&UI Previewer...'), |
|
2084 0, 0, self, 'ui_previewer') |
|
2085 self.uipreviewerAct.setStatusTip(self.tr('Start the UI Previewer')) |
|
2086 self.uipreviewerAct.setWhatsThis(self.tr( |
|
2087 """<b>UI Previewer</b>""" |
|
2088 """<p>Start the UI Previewer.</p>""" |
|
2089 )) |
|
2090 self.uipreviewerAct.triggered.connect(self.__UIPreviewer) |
|
2091 self.actions.append(self.uipreviewerAct) |
|
2092 |
|
2093 self.trpreviewerAct = E5Action( |
|
2094 self.tr('Translations Previewer'), |
|
2095 UI.PixmapCache.getIcon("trPreviewer.png"), |
|
2096 self.tr('&Translations Previewer...'), |
|
2097 0, 0, self, 'tr_previewer') |
|
2098 self.trpreviewerAct.setStatusTip(self.tr( |
|
2099 'Start the Translations Previewer')) |
|
2100 self.trpreviewerAct.setWhatsThis(self.tr( |
|
2101 """<b>Translations Previewer</b>""" |
|
2102 """<p>Start the Translations Previewer.</p>""" |
|
2103 )) |
|
2104 self.trpreviewerAct.triggered.connect(self.__TRPreviewer) |
|
2105 self.actions.append(self.trpreviewerAct) |
|
2106 |
|
2107 self.diffAct = E5Action( |
|
2108 self.tr('Compare Files'), |
|
2109 UI.PixmapCache.getIcon("diffFiles.png"), |
|
2110 self.tr('&Compare Files...'), |
|
2111 0, 0, self, 'diff_files') |
|
2112 self.diffAct.setStatusTip(self.tr('Compare two files')) |
|
2113 self.diffAct.setWhatsThis(self.tr( |
|
2114 """<b>Compare Files</b>""" |
|
2115 """<p>Open a dialog to compare two files.</p>""" |
|
2116 )) |
|
2117 self.diffAct.triggered.connect(self.__compareFiles) |
|
2118 self.actions.append(self.diffAct) |
|
2119 |
|
2120 self.compareAct = E5Action( |
|
2121 self.tr('Compare Files side by side'), |
|
2122 UI.PixmapCache.getIcon("compareFiles.png"), |
|
2123 self.tr('Compare &Files side by side...'), |
|
2124 0, 0, self, 'compare_files') |
|
2125 self.compareAct.setStatusTip(self.tr('Compare two files')) |
|
2126 self.compareAct.setWhatsThis(self.tr( |
|
2127 """<b>Compare Files side by side</b>""" |
|
2128 """<p>Open a dialog to compare two files and show the result""" |
|
2129 """ side by side.</p>""" |
|
2130 )) |
|
2131 self.compareAct.triggered.connect(self.__compareFilesSbs) |
|
2132 self.actions.append(self.compareAct) |
|
2133 |
|
2134 self.sqlBrowserAct = E5Action( |
|
2135 self.tr('SQL Browser'), |
|
2136 UI.PixmapCache.getIcon("sqlBrowser.png"), |
|
2137 self.tr('SQL &Browser...'), |
|
2138 0, 0, self, 'sql_browser') |
|
2139 self.sqlBrowserAct.setStatusTip(self.tr('Browse a SQL database')) |
|
2140 self.sqlBrowserAct.setWhatsThis(self.tr( |
|
2141 """<b>SQL Browser</b>""" |
|
2142 """<p>Browse a SQL database.</p>""" |
|
2143 )) |
|
2144 self.sqlBrowserAct.triggered.connect(self.__sqlBrowser) |
|
2145 self.actions.append(self.sqlBrowserAct) |
|
2146 |
|
2147 self.miniEditorAct = E5Action( |
|
2148 self.tr('Mini Editor'), |
|
2149 UI.PixmapCache.getIcon("editor.png"), |
|
2150 self.tr('Mini &Editor...'), |
|
2151 0, 0, self, 'mini_editor') |
|
2152 self.miniEditorAct.setStatusTip(self.tr('Mini Editor')) |
|
2153 self.miniEditorAct.setWhatsThis(self.tr( |
|
2154 """<b>Mini Editor</b>""" |
|
2155 """<p>Open a dialog with a simplified editor.</p>""" |
|
2156 )) |
|
2157 self.miniEditorAct.triggered.connect(self.__openMiniEditor) |
|
2158 self.actions.append(self.miniEditorAct) |
|
2159 |
|
2160 self.hexEditorAct = E5Action( |
|
2161 self.tr('Hex Editor'), |
|
2162 UI.PixmapCache.getIcon("hexEditor.png"), |
|
2163 self.tr('&Hex Editor...'), |
|
2164 0, 0, self, 'hex_editor') |
|
2165 self.hexEditorAct.setStatusTip(self.tr( |
|
2166 'Start the eric6 Hex Editor')) |
|
2167 self.hexEditorAct.setWhatsThis(self.tr( |
|
2168 """<b>Hex Editor</b>""" |
|
2169 """<p>Starts the eric6 Hex Editor for viewing or editing""" |
|
2170 """ binary files.</p>""" |
|
2171 )) |
|
2172 self.hexEditorAct.triggered.connect(self.__openHexEditor) |
|
2173 self.actions.append(self.hexEditorAct) |
|
2174 |
|
2175 self.webBrowserAct = E5Action( |
|
2176 self.tr('eric6 Web Browser'), |
|
2177 UI.PixmapCache.getIcon("ericWeb.png"), |
|
2178 self.tr('eric6 &Web Browser...'), |
|
2179 0, 0, self, 'web_browser') |
|
2180 self.webBrowserAct.setStatusTip(self.tr( |
|
2181 'Start the eric6 Web Browser')) |
|
2182 self.webBrowserAct.setWhatsThis(self.tr( |
|
2183 """<b>eric6 Web Browser</b>""" |
|
2184 """<p>Browse the Internet with the eric6 Web Browser.</p>""" |
|
2185 )) |
|
2186 self.webBrowserAct.triggered.connect(self.__startWebBrowser) |
|
2187 self.actions.append(self.webBrowserAct) |
|
2188 ## else: |
|
2189 ## self.webBrowserAct = None |
|
2190 |
|
2191 self.iconEditorAct = E5Action( |
|
2192 self.tr('Icon Editor'), |
|
2193 UI.PixmapCache.getIcon("iconEditor.png"), |
|
2194 self.tr('&Icon Editor...'), |
|
2195 0, 0, self, 'icon_editor') |
|
2196 self.iconEditorAct.setStatusTip(self.tr( |
|
2197 'Start the eric6 Icon Editor')) |
|
2198 self.iconEditorAct.setWhatsThis(self.tr( |
|
2199 """<b>Icon Editor</b>""" |
|
2200 """<p>Starts the eric6 Icon Editor for editing simple icons.</p>""" |
|
2201 )) |
|
2202 self.iconEditorAct.triggered.connect(self.__editPixmap) |
|
2203 self.actions.append(self.iconEditorAct) |
|
2204 |
|
2205 self.snapshotAct = E5Action( |
|
2206 self.tr('Snapshot'), |
|
2207 UI.PixmapCache.getIcon("ericSnap.png"), |
|
2208 self.tr('&Snapshot...'), |
|
2209 0, 0, self, 'snapshot') |
|
2210 self.snapshotAct.setStatusTip(self.tr( |
|
2211 'Take snapshots of a screen region')) |
|
2212 self.snapshotAct.setWhatsThis(self.tr( |
|
2213 """<b>Snapshot</b>""" |
|
2214 """<p>This opens a dialog to take snapshots of a screen""" |
|
2215 """ region.</p>""" |
|
2216 )) |
|
2217 self.snapshotAct.triggered.connect(self.__snapshot) |
|
2218 self.actions.append(self.snapshotAct) |
|
2219 |
|
2220 self.prefAct = E5Action( |
|
2221 self.tr('Preferences'), |
|
2222 UI.PixmapCache.getIcon("configure.png"), |
|
2223 self.tr('&Preferences...'), |
|
2224 0, 0, self, 'preferences') |
|
2225 self.prefAct.setStatusTip(self.tr( |
|
2226 'Set the prefered configuration')) |
|
2227 self.prefAct.setWhatsThis(self.tr( |
|
2228 """<b>Preferences</b>""" |
|
2229 """<p>Set the configuration items of the application""" |
|
2230 """ with your prefered values.</p>""" |
|
2231 )) |
|
2232 self.prefAct.triggered.connect(self.showPreferences) |
|
2233 self.prefAct.setMenuRole(QAction.PreferencesRole) |
|
2234 self.actions.append(self.prefAct) |
|
2235 |
|
2236 self.prefExportAct = E5Action( |
|
2237 self.tr('Export Preferences'), |
|
2238 UI.PixmapCache.getIcon("configureExport.png"), |
|
2239 self.tr('E&xport Preferences...'), |
|
2240 0, 0, self, 'export_preferences') |
|
2241 self.prefExportAct.setStatusTip(self.tr( |
|
2242 'Export the current configuration')) |
|
2243 self.prefExportAct.setWhatsThis(self.tr( |
|
2244 """<b>Export Preferences</b>""" |
|
2245 """<p>Export the current configuration to a file.</p>""" |
|
2246 )) |
|
2247 self.prefExportAct.triggered.connect(self.__exportPreferences) |
|
2248 self.actions.append(self.prefExportAct) |
|
2249 |
|
2250 self.prefImportAct = E5Action( |
|
2251 self.tr('Import Preferences'), |
|
2252 UI.PixmapCache.getIcon("configureImport.png"), |
|
2253 self.tr('I&mport Preferences...'), |
|
2254 0, 0, self, 'import_preferences') |
|
2255 self.prefImportAct.setStatusTip(self.tr( |
|
2256 'Import a previously exported configuration')) |
|
2257 self.prefImportAct.setWhatsThis(self.tr( |
|
2258 """<b>Import Preferences</b>""" |
|
2259 """<p>Import a previously exported configuration.</p>""" |
|
2260 )) |
|
2261 self.prefImportAct.triggered.connect(self.__importPreferences) |
|
2262 self.actions.append(self.prefImportAct) |
|
2263 |
|
2264 self.reloadAPIsAct = E5Action( |
|
2265 self.tr('Reload APIs'), |
|
2266 self.tr('Reload &APIs'), |
|
2267 0, 0, self, 'reload_apis') |
|
2268 self.reloadAPIsAct.setStatusTip(self.tr( |
|
2269 'Reload the API information')) |
|
2270 self.reloadAPIsAct.setWhatsThis(self.tr( |
|
2271 """<b>Reload APIs</b>""" |
|
2272 """<p>Reload the API information.</p>""" |
|
2273 )) |
|
2274 self.reloadAPIsAct.triggered.connect(self.__reloadAPIs) |
|
2275 self.actions.append(self.reloadAPIsAct) |
|
2276 |
|
2277 self.showExternalToolsAct = E5Action( |
|
2278 self.tr('Show external tools'), |
|
2279 UI.PixmapCache.getIcon("showPrograms.png"), |
|
2280 self.tr('Show external &tools'), |
|
2281 0, 0, self, 'show_external_tools') |
|
2282 self.showExternalToolsAct.setStatusTip(self.tr( |
|
2283 'Show external tools')) |
|
2284 self.showExternalToolsAct.setWhatsThis(self.tr( |
|
2285 """<b>Show external tools</b>""" |
|
2286 """<p>Opens a dialog to show the path and versions of all""" |
|
2287 """ extenal tools used by eric6.</p>""" |
|
2288 )) |
|
2289 self.showExternalToolsAct.triggered.connect( |
|
2290 self.__showExternalTools) |
|
2291 self.actions.append(self.showExternalToolsAct) |
|
2292 |
|
2293 self.configViewProfilesAct = E5Action( |
|
2294 self.tr('View Profiles'), |
|
2295 UI.PixmapCache.getIcon("configureViewProfiles.png"), |
|
2296 self.tr('&View Profiles...'), |
|
2297 0, 0, self, 'view_profiles') |
|
2298 self.configViewProfilesAct.setStatusTip(self.tr( |
|
2299 'Configure view profiles')) |
|
2300 self.configViewProfilesAct.setWhatsThis(self.tr( |
|
2301 """<b>View Profiles</b>""" |
|
2302 """<p>Configure the view profiles. With this dialog you may""" |
|
2303 """ set the visibility of the various windows for the""" |
|
2304 """ predetermined view profiles.</p>""" |
|
2305 )) |
|
2306 self.configViewProfilesAct.triggered.connect( |
|
2307 self.__configViewProfiles) |
|
2308 self.actions.append(self.configViewProfilesAct) |
|
2309 |
|
2310 self.configToolBarsAct = E5Action( |
|
2311 self.tr('Toolbars'), |
|
2312 UI.PixmapCache.getIcon("toolbarsConfigure.png"), |
|
2313 self.tr('Tool&bars...'), |
|
2314 0, 0, self, 'configure_toolbars') |
|
2315 self.configToolBarsAct.setStatusTip(self.tr('Configure toolbars')) |
|
2316 self.configToolBarsAct.setWhatsThis(self.tr( |
|
2317 """<b>Toolbars</b>""" |
|
2318 """<p>Configure the toolbars. With this dialog you may""" |
|
2319 """ change the actions shown on the various toolbars and""" |
|
2320 """ define your own toolbars.</p>""" |
|
2321 )) |
|
2322 self.configToolBarsAct.triggered.connect(self.__configToolBars) |
|
2323 self.actions.append(self.configToolBarsAct) |
|
2324 |
|
2325 self.shortcutsAct = E5Action( |
|
2326 self.tr('Keyboard Shortcuts'), |
|
2327 UI.PixmapCache.getIcon("configureShortcuts.png"), |
|
2328 self.tr('Keyboard &Shortcuts...'), |
|
2329 0, 0, self, 'keyboard_shortcuts') |
|
2330 self.shortcutsAct.setStatusTip(self.tr( |
|
2331 'Set the keyboard shortcuts')) |
|
2332 self.shortcutsAct.setWhatsThis(self.tr( |
|
2333 """<b>Keyboard Shortcuts</b>""" |
|
2334 """<p>Set the keyboard shortcuts of the application""" |
|
2335 """ with your prefered values.</p>""" |
|
2336 )) |
|
2337 self.shortcutsAct.triggered.connect(self.__configShortcuts) |
|
2338 self.actions.append(self.shortcutsAct) |
|
2339 |
|
2340 self.exportShortcutsAct = E5Action( |
|
2341 self.tr('Export Keyboard Shortcuts'), |
|
2342 UI.PixmapCache.getIcon("exportShortcuts.png"), |
|
2343 self.tr('&Export Keyboard Shortcuts...'), |
|
2344 0, 0, self, 'export_keyboard_shortcuts') |
|
2345 self.exportShortcutsAct.setStatusTip(self.tr( |
|
2346 'Export the keyboard shortcuts')) |
|
2347 self.exportShortcutsAct.setWhatsThis(self.tr( |
|
2348 """<b>Export Keyboard Shortcuts</b>""" |
|
2349 """<p>Export the keyboard shortcuts of the application.</p>""" |
|
2350 )) |
|
2351 self.exportShortcutsAct.triggered.connect(self.__exportShortcuts) |
|
2352 self.actions.append(self.exportShortcutsAct) |
|
2353 |
|
2354 self.importShortcutsAct = E5Action( |
|
2355 self.tr('Import Keyboard Shortcuts'), |
|
2356 UI.PixmapCache.getIcon("importShortcuts.png"), |
|
2357 self.tr('&Import Keyboard Shortcuts...'), |
|
2358 0, 0, self, 'import_keyboard_shortcuts') |
|
2359 self.importShortcutsAct.setStatusTip(self.tr( |
|
2360 'Import the keyboard shortcuts')) |
|
2361 self.importShortcutsAct.setWhatsThis(self.tr( |
|
2362 """<b>Import Keyboard Shortcuts</b>""" |
|
2363 """<p>Import the keyboard shortcuts of the application.</p>""" |
|
2364 )) |
|
2365 self.importShortcutsAct.triggered.connect(self.__importShortcuts) |
|
2366 self.actions.append(self.importShortcutsAct) |
|
2367 |
|
2368 if SSL_AVAILABLE: |
|
2369 self.certificatesAct = E5Action( |
|
2370 self.tr('Manage SSL Certificates'), |
|
2371 UI.PixmapCache.getIcon("certificates.png"), |
|
2372 self.tr('Manage SSL Certificates...'), |
|
2373 0, 0, self, 'manage_ssl_certificates') |
|
2374 self.certificatesAct.setStatusTip(self.tr( |
|
2375 'Manage the saved SSL certificates')) |
|
2376 self.certificatesAct.setWhatsThis(self.tr( |
|
2377 """<b>Manage SSL Certificates...</b>""" |
|
2378 """<p>Opens a dialog to manage the saved SSL certificates.""" |
|
2379 """</p>""" |
|
2380 )) |
|
2381 self.certificatesAct.triggered.connect( |
|
2382 self.__showCertificatesDialog) |
|
2383 self.actions.append(self.certificatesAct) |
|
2384 |
|
2385 self.editMessageFilterAct = E5Action( |
|
2386 self.tr('Edit Message Filters'), |
|
2387 UI.PixmapCache.getIcon("warning.png"), |
|
2388 self.tr('Edit Message Filters...'), |
|
2389 0, 0, self, 'manage_message_filters') |
|
2390 self.editMessageFilterAct.setStatusTip(self.tr( |
|
2391 'Edit the message filters used to suppress unwanted messages')) |
|
2392 self.editMessageFilterAct.setWhatsThis(self.tr( |
|
2393 """<b>Edit Message Filters</b>""" |
|
2394 """<p>Opens a dialog to edit the message filters used to""" |
|
2395 """ suppress unwanted messages been shown in an error""" |
|
2396 """ window.</p>""" |
|
2397 )) |
|
2398 self.editMessageFilterAct.triggered.connect( |
|
2399 E5ErrorMessage.editMessageFilters) |
|
2400 self.actions.append(self.editMessageFilterAct) |
|
2401 |
|
2402 self.clearPrivateDataAct = E5Action( |
|
2403 self.tr('Clear private data'), |
|
2404 UI.PixmapCache.getIcon("clearPrivateData.png"), |
|
2405 self.tr('Clear private data'), |
|
2406 0, 0, |
|
2407 self, 'clear_private_data') |
|
2408 self.clearPrivateDataAct.setStatusTip(self.tr( |
|
2409 'Clear private data')) |
|
2410 self.clearPrivateDataAct.setWhatsThis(self.tr( |
|
2411 """<b>Clear private data</b>""" |
|
2412 """<p>Clears the private data like the various list of""" |
|
2413 """ recently opened files, projects or multi projects.</p>""" |
|
2414 )) |
|
2415 self.clearPrivateDataAct.triggered.connect( |
|
2416 self.__clearPrivateData) |
|
2417 self.actions.append(self.clearPrivateDataAct) |
|
2418 |
|
2419 self.viewmanagerActivateAct = E5Action( |
|
2420 self.tr('Activate current editor'), |
|
2421 self.tr('Activate current editor'), |
|
2422 QKeySequence(self.tr("Alt+Shift+E")), |
|
2423 0, self, 'viewmanager_activate', 1) |
|
2424 self.viewmanagerActivateAct.triggered.connect( |
|
2425 self.__activateViewmanager) |
|
2426 self.actions.append(self.viewmanagerActivateAct) |
|
2427 self.addAction(self.viewmanagerActivateAct) |
|
2428 |
|
2429 self.nextTabAct = E5Action( |
|
2430 self.tr('Show next'), |
|
2431 self.tr('Show next'), |
|
2432 QKeySequence(self.tr('Ctrl+Alt+Tab')), 0, |
|
2433 self, 'view_next_tab') |
|
2434 self.nextTabAct.triggered.connect(self.__showNext) |
|
2435 self.actions.append(self.nextTabAct) |
|
2436 self.addAction(self.nextTabAct) |
|
2437 |
|
2438 self.prevTabAct = E5Action( |
|
2439 self.tr('Show previous'), |
|
2440 self.tr('Show previous'), |
|
2441 QKeySequence(self.tr('Shift+Ctrl+Alt+Tab')), 0, |
|
2442 self, 'view_previous_tab') |
|
2443 self.prevTabAct.triggered.connect(self.__showPrevious) |
|
2444 self.actions.append(self.prevTabAct) |
|
2445 self.addAction(self.prevTabAct) |
|
2446 |
|
2447 self.switchTabAct = E5Action( |
|
2448 self.tr('Switch between tabs'), |
|
2449 self.tr('Switch between tabs'), |
|
2450 QKeySequence(self.tr('Ctrl+1')), 0, |
|
2451 self, 'switch_tabs') |
|
2452 self.switchTabAct.triggered.connect(self.__switchTab) |
|
2453 self.actions.append(self.switchTabAct) |
|
2454 self.addAction(self.switchTabAct) |
|
2455 |
|
2456 self.pluginInfoAct = E5Action( |
|
2457 self.tr('Plugin Infos'), |
|
2458 UI.PixmapCache.getIcon("plugin.png"), |
|
2459 self.tr('&Plugin Infos...'), 0, 0, self, 'plugin_infos') |
|
2460 self.pluginInfoAct.setStatusTip(self.tr('Show Plugin Infos')) |
|
2461 self.pluginInfoAct.setWhatsThis(self.tr( |
|
2462 """<b>Plugin Infos...</b>""" |
|
2463 """<p>This opens a dialog, that show some information about""" |
|
2464 """ loaded plugins.</p>""" |
|
2465 )) |
|
2466 self.pluginInfoAct.triggered.connect(self.__showPluginInfo) |
|
2467 self.actions.append(self.pluginInfoAct) |
|
2468 |
|
2469 self.pluginInstallAct = E5Action( |
|
2470 self.tr('Install Plugins'), |
|
2471 UI.PixmapCache.getIcon("pluginInstall.png"), |
|
2472 self.tr('&Install Plugins...'), |
|
2473 0, 0, self, 'plugin_install') |
|
2474 self.pluginInstallAct.setStatusTip(self.tr('Install Plugins')) |
|
2475 self.pluginInstallAct.setWhatsThis(self.tr( |
|
2476 """<b>Install Plugins...</b>""" |
|
2477 """<p>This opens a dialog to install or update plugins.</p>""" |
|
2478 )) |
|
2479 self.pluginInstallAct.triggered.connect(self.__installPlugins) |
|
2480 self.actions.append(self.pluginInstallAct) |
|
2481 |
|
2482 self.pluginDeinstallAct = E5Action( |
|
2483 self.tr('Uninstall Plugin'), |
|
2484 UI.PixmapCache.getIcon("pluginUninstall.png"), |
|
2485 self.tr('&Uninstall Plugin...'), |
|
2486 0, 0, self, 'plugin_deinstall') |
|
2487 self.pluginDeinstallAct.setStatusTip(self.tr('Uninstall Plugin')) |
|
2488 self.pluginDeinstallAct.setWhatsThis(self.tr( |
|
2489 """<b>Uninstall Plugin...</b>""" |
|
2490 """<p>This opens a dialog to uninstall a plugin.</p>""" |
|
2491 )) |
|
2492 self.pluginDeinstallAct.triggered.connect(self.__deinstallPlugin) |
|
2493 self.actions.append(self.pluginDeinstallAct) |
|
2494 |
|
2495 self.pluginRepoAct = E5Action( |
|
2496 self.tr('Plugin Repository'), |
|
2497 UI.PixmapCache.getIcon("pluginRepository.png"), |
|
2498 self.tr('Plugin &Repository...'), |
|
2499 0, 0, self, 'plugin_repository') |
|
2500 self.pluginRepoAct.setStatusTip(self.tr( |
|
2501 'Show Plugins available for download')) |
|
2502 self.pluginRepoAct.setWhatsThis(self.tr( |
|
2503 """<b>Plugin Repository...</b>""" |
|
2504 """<p>This opens a dialog, that shows a list of plugins """ |
|
2505 """available on the Internet.</p>""" |
|
2506 )) |
|
2507 self.pluginRepoAct.triggered.connect(self.showPluginsAvailable) |
|
2508 self.actions.append(self.pluginRepoAct) |
|
2509 |
|
2510 self.virtualenvManagerAct = E5Action( |
|
2511 self.tr('Virtualenv Manager'), |
|
2512 UI.PixmapCache.getIcon("virtualenv.png"), |
|
2513 self.tr('&Virtualenv Manager...'), |
|
2514 0, 0, self, |
|
2515 'virtualenv_manager') |
|
2516 self.virtualenvManagerAct.setStatusTip(self.tr( |
|
2517 'Virtualenv Manager')) |
|
2518 self.virtualenvManagerAct.setWhatsThis(self.tr( |
|
2519 """<b>Virtualenv Manager</b>""" |
|
2520 """<p>This opens a dialog to manage the defined Python virtual""" |
|
2521 """ environments.</p>""" |
|
2522 )) |
|
2523 self.virtualenvManagerAct.triggered.connect( |
|
2524 self.virtualenvManager.showVirtualenvManagerDialog) |
|
2525 self.actions.append(self.virtualenvManagerAct) |
|
2526 |
|
2527 self.virtualenvConfigAct = E5Action( |
|
2528 self.tr('Virtualenv Configurator'), |
|
2529 UI.PixmapCache.getIcon("virtualenvConfig.png"), |
|
2530 self.tr('Virtualenv &Configurator...'), |
|
2531 0, 0, self, |
|
2532 'virtualenv_configurator') |
|
2533 self.virtualenvConfigAct.setStatusTip(self.tr( |
|
2534 'Virtualenv Configurator')) |
|
2535 self.virtualenvConfigAct.setWhatsThis(self.tr( |
|
2536 """<b>Virtualenv Configurator</b>""" |
|
2537 """<p>This opens a dialog for entering all the parameters""" |
|
2538 """ needed to create a Python virtual environment using""" |
|
2539 """ virtualenv or pyvenv.</p>""" |
|
2540 )) |
|
2541 self.virtualenvConfigAct.triggered.connect( |
|
2542 self.virtualenvManager.createVirtualEnv) |
|
2543 self.actions.append(self.virtualenvConfigAct) |
|
2544 |
|
2545 # initialize viewmanager actions |
|
2546 self.viewmanager.initActions() |
|
2547 |
|
2548 # initialize debugger actions |
|
2549 self.debuggerUI.initActions() |
|
2550 |
|
2551 # initialize project actions |
|
2552 self.project.initActions() |
|
2553 |
|
2554 # initialize multi project actions |
|
2555 self.multiProject.initActions() |
|
2556 |
|
2557 def __initQtDocActions(self): |
|
2558 """ |
|
2559 Private slot to initialize the action to show the Qt documentation. |
|
2560 """ |
|
2561 self.qt4DocAct = E5Action( |
|
2562 self.tr('Qt4 Documentation'), |
|
2563 self.tr('Qt&4 Documentation'), |
|
2564 0, 0, self, 'qt4_documentation') |
|
2565 self.qt4DocAct.setStatusTip(self.tr('Open Qt4 Documentation')) |
|
2566 self.qt4DocAct.setWhatsThis(self.tr( |
|
2567 """<b>Qt4 Documentation</b>""" |
|
2568 """<p>Display the Qt4 Documentation. Dependent upon your""" |
|
2569 """ settings, this will either show the help in Eric's internal""" |
|
2570 """ help viewer/web browser, or execute a web browser or Qt""" |
|
2571 """ Assistant. </p>""" |
|
2572 )) |
|
2573 self.qt4DocAct.triggered.connect(self.__showQt4Doc) |
|
2574 self.actions.append(self.qt4DocAct) |
|
2575 |
|
2576 self.qt5DocAct = E5Action( |
|
2577 self.tr('Qt5 Documentation'), |
|
2578 self.tr('Qt&5 Documentation'), |
|
2579 0, 0, self, 'qt5_documentation') |
|
2580 self.qt5DocAct.setStatusTip(self.tr('Open Qt5 Documentation')) |
|
2581 self.qt5DocAct.setWhatsThis(self.tr( |
|
2582 """<b>Qt5 Documentation</b>""" |
|
2583 """<p>Display the Qt5 Documentation. Dependent upon your""" |
|
2584 """ settings, this will either show the help in Eric's internal""" |
|
2585 """ help viewer/web browser, or execute a web browser or Qt""" |
|
2586 """ Assistant. </p>""" |
|
2587 )) |
|
2588 self.qt5DocAct.triggered.connect(self.__showQt5Doc) |
|
2589 self.actions.append(self.qt5DocAct) |
|
2590 |
|
2591 try: |
|
2592 import PyQt4 # __IGNORE_WARNING__ |
|
2593 self.pyqt4DocAct = E5Action( |
|
2594 self.tr('PyQt4 Documentation'), |
|
2595 self.tr('PyQt&4 Documentation'), |
|
2596 0, 0, self, 'pyqt4_documentation') |
|
2597 self.pyqt4DocAct.setStatusTip(self.tr('Open PyQt4 Documentation')) |
|
2598 self.pyqt4DocAct.setWhatsThis(self.tr( |
|
2599 """<b>PyQt4 Documentation</b>""" |
|
2600 """<p>Display the PyQt4 Documentation. Dependent upon your""" |
|
2601 """ settings, this will either show the help in Eric's""" |
|
2602 """ internal help viewer/web browser, or execute a web""" |
|
2603 """ browser or Qt Assistant. </p>""" |
|
2604 )) |
|
2605 self.pyqt4DocAct.triggered.connect(self.__showPyQt4Doc) |
|
2606 self.actions.append(self.pyqt4DocAct) |
|
2607 except ImportError: |
|
2608 self.pyqt4DocAct = None |
|
2609 |
|
2610 try: |
|
2611 import PyQt5 # __IGNORE_WARNING__ |
|
2612 self.pyqt5DocAct = E5Action( |
|
2613 self.tr('PyQt5 Documentation'), |
|
2614 self.tr('PyQt&5 Documentation'), |
|
2615 0, 0, self, 'pyqt5_documentation') |
|
2616 self.pyqt5DocAct.setStatusTip(self.tr( |
|
2617 'Open PyQt5 Documentation')) |
|
2618 self.pyqt5DocAct.setWhatsThis(self.tr( |
|
2619 """<b>PyQt5 Documentation</b>""" |
|
2620 """<p>Display the PyQt5 Documentation. Dependent upon your""" |
|
2621 """ settings, this will either show the help in Eric's""" |
|
2622 """ internal help viewer/web browser, or execute a web""" |
|
2623 """ browser or Qt Assistant. </p>""" |
|
2624 )) |
|
2625 self.pyqt5DocAct.triggered.connect(self.__showPyQt5Doc) |
|
2626 self.actions.append(self.pyqt5DocAct) |
|
2627 except ImportError: |
|
2628 self.pyqt5DocAct = None |
|
2629 |
|
2630 def __initPythonDocActions(self): |
|
2631 """ |
|
2632 Private slot to initialize the actions to show the Python |
|
2633 documentation. |
|
2634 """ |
|
2635 self.pythonDocAct = E5Action( |
|
2636 self.tr('Python 3 Documentation'), |
|
2637 self.tr('Python &3 Documentation'), |
|
2638 0, 0, self, 'python3_documentation') |
|
2639 self.pythonDocAct.setStatusTip(self.tr( |
|
2640 'Open Python 3 Documentation')) |
|
2641 self.pythonDocAct.setWhatsThis(self.tr( |
|
2642 """<b>Python 3 Documentation</b>""" |
|
2643 """<p>Display the Python 3 documentation. If no documentation""" |
|
2644 """ directory is configured, the location of the Python 3""" |
|
2645 """ documentation is assumed to be the doc directory underneath""" |
|
2646 """ the location of the Python 3 executable on Windows and""" |
|
2647 """ <i>/usr/share/doc/packages/python/html</i> on Unix. Set""" |
|
2648 """ PYTHON3DOCDIR in your environment to override this.</p>""" |
|
2649 )) |
|
2650 self.pythonDocAct.triggered.connect(self.__showPythonDoc) |
|
2651 self.actions.append(self.pythonDocAct) |
|
2652 |
|
2653 self.python2DocAct = E5Action( |
|
2654 self.tr('Python 2 Documentation'), |
|
2655 self.tr('Python &2 Documentation'), |
|
2656 0, 0, self, 'python2_documentation') |
|
2657 self.python2DocAct.setStatusTip(self.tr( |
|
2658 'Open Python 2 Documentation')) |
|
2659 self.python2DocAct.setWhatsThis(self.tr( |
|
2660 """<b>Python 2 Documentation</b>""" |
|
2661 """<p>Display the Python 2 documentation. If no documentation""" |
|
2662 """ directory is configured, the location of the Python 2""" |
|
2663 """ documentation is assumed to be the doc directory underneath""" |
|
2664 """ the location of the configured Python 2 executable on""" |
|
2665 """ Windows and""" |
|
2666 """ <i>/usr/share/doc/packages/python/html/python-docs-html</i>""" |
|
2667 """ on Unix. Set PYTHON2DOCDIR in your environment to override""" |
|
2668 """ this. </p>""" |
|
2669 )) |
|
2670 self.python2DocAct.triggered.connect(self.__showPython2Doc) |
|
2671 self.actions.append(self.python2DocAct) |
|
2672 |
|
2673 def __initEricDocAction(self): |
|
2674 """ |
|
2675 Private slot to initialize the action to show the eric6 documentation. |
|
2676 """ |
|
2677 self.ericDocAct = E5Action( |
|
2678 self.tr("Eric API Documentation"), |
|
2679 self.tr('&Eric API Documentation'), |
|
2680 0, 0, self, 'eric_documentation') |
|
2681 self.ericDocAct.setStatusTip(self.tr( |
|
2682 "Open Eric API Documentation")) |
|
2683 self.ericDocAct.setWhatsThis(self.tr( |
|
2684 """<b>Eric API Documentation</b>""" |
|
2685 """<p>Display the Eric API documentation. The location for the""" |
|
2686 """ documentation is the Documentation/Source subdirectory of""" |
|
2687 """ the eric6 installation directory.</p>""" |
|
2688 )) |
|
2689 self.ericDocAct.triggered.connect(self.__showEricDoc) |
|
2690 self.actions.append(self.ericDocAct) |
|
2691 |
|
2692 def __initPySideDocActions(self): |
|
2693 """ |
|
2694 Private slot to initialize the actions to show the PySide |
|
2695 documentation. |
|
2696 """ |
|
2697 pyside_py2, pyside_py3 = Utilities.checkPyside("1") |
|
2698 if pyside_py2 or pyside_py3: |
|
2699 self.pysideDocAct = E5Action( |
|
2700 self.tr('PySide Documentation'), |
|
2701 self.tr('Py&Side Documentation'), |
|
2702 0, 0, self, 'pyside_documentation') |
|
2703 self.pysideDocAct.setStatusTip(self.tr( |
|
2704 'Open PySide Documentation')) |
|
2705 self.pysideDocAct.setWhatsThis(self.tr( |
|
2706 """<b>PySide Documentation</b>""" |
|
2707 """<p>Display the PySide Documentation. Dependent upon your""" |
|
2708 """ settings, this will either show the help in Eric's""" |
|
2709 """ internal help viewer/web browser, or execute a web""" |
|
2710 """ browser or Qt Assistant. </p>""" |
|
2711 )) |
|
2712 self.pysideDocAct.triggered.connect( |
|
2713 lambda: self.__showPySideDoc("1")) |
|
2714 self.actions.append(self.pysideDocAct) |
|
2715 else: |
|
2716 self.pysideDocAct = None |
|
2717 |
|
2718 pyside2_py2, pyside2_py3 = Utilities.checkPyside("2") |
|
2719 if pyside2_py2 or pyside2_py3: |
|
2720 self.pyside2DocAct = E5Action( |
|
2721 self.tr('PySide2 Documentation'), |
|
2722 self.tr('PySide&2 Documentation'), |
|
2723 0, 0, self, 'pyside2_documentation') |
|
2724 self.pyside2DocAct.setStatusTip(self.tr( |
|
2725 'Open PySide2 Documentation')) |
|
2726 self.pyside2DocAct.setWhatsThis(self.tr( |
|
2727 """<b>PySide2 Documentation</b>""" |
|
2728 """<p>Display the PySide2 Documentation. Dependent upon your""" |
|
2729 """ settings, this will either show the help in Eric's""" |
|
2730 """ internal help viewer/web browser, or execute a web""" |
|
2731 """ browser or Qt Assistant. </p>""" |
|
2732 )) |
|
2733 self.pyside2DocAct.triggered.connect( |
|
2734 lambda: self.__showPySideDoc("2")) |
|
2735 self.actions.append(self.pyside2DocAct) |
|
2736 else: |
|
2737 self.pyside2DocAct = None |
|
2738 |
|
2739 def __initMenus(self): |
|
2740 """ |
|
2741 Private slot to create the menus. |
|
2742 """ |
|
2743 self.__menus = {} |
|
2744 mb = self.menuBar() |
|
2745 if Utilities.isLinuxPlatform() and \ |
|
2746 not Preferences.getUI("UseNativeMenuBar"): |
|
2747 mb.setNativeMenuBar(False) |
|
2748 |
|
2749 self.__menus["file"] = self.viewmanager.initFileMenu() |
|
2750 mb.addMenu(self.__menus["file"]) |
|
2751 self.__menus["file"].addSeparator() |
|
2752 self.__menus["file"].addAction(self.saveSessionAct) |
|
2753 self.__menus["file"].addAction(self.loadSessionAct) |
|
2754 self.__menus["file"].addSeparator() |
|
2755 self.__menus["file"].addAction(self.restartAct) |
|
2756 self.__menus["file"].addAction(self.exitAct) |
|
2757 act = self.__menus["file"].actions()[0] |
|
2758 sep = self.__menus["file"].insertSeparator(act) |
|
2759 self.__menus["file"].insertAction(sep, self.newWindowAct) |
|
2760 self.__menus["file"].aboutToShow.connect(self.__showFileMenu) |
|
2761 |
|
2762 self.__menus["edit"] = self.viewmanager.initEditMenu() |
|
2763 mb.addMenu(self.__menus["edit"]) |
|
2764 |
|
2765 self.__menus["view"] = self.viewmanager.initViewMenu() |
|
2766 mb.addMenu(self.__menus["view"]) |
|
2767 |
|
2768 self.__menus["start"], self.__menus["debug"] = \ |
|
2769 self.debuggerUI.initMenus() |
|
2770 mb.addMenu(self.__menus["start"]) |
|
2771 mb.addMenu(self.__menus["debug"]) |
|
2772 |
|
2773 self.__menus["unittest"] = QMenu(self.tr('&Unittest'), self) |
|
2774 self.__menus["unittest"].setTearOffEnabled(True) |
|
2775 mb.addMenu(self.__menus["unittest"]) |
|
2776 self.__menus["unittest"].addAction(self.utDialogAct) |
|
2777 self.__menus["unittest"].addSeparator() |
|
2778 self.__menus["unittest"].addAction(self.utRestartAct) |
|
2779 self.__menus["unittest"].addAction(self.utRerunFailedAct) |
|
2780 self.__menus["unittest"].addSeparator() |
|
2781 self.__menus["unittest"].addAction(self.utScriptAct) |
|
2782 self.__menus["unittest"].addAction(self.utProjectAct) |
|
2783 |
|
2784 self.__menus["multiproject"] = self.multiProject.initMenu() |
|
2785 mb.addMenu(self.__menus["multiproject"]) |
|
2786 |
|
2787 self.__menus["project"] = self.project.initMenu() |
|
2788 mb.addMenu(self.__menus["project"]) |
|
2789 |
|
2790 self.__menus["extras"] = QMenu(self.tr('E&xtras'), self) |
|
2791 self.__menus["extras"].setTearOffEnabled(True) |
|
2792 self.__menus["extras"].aboutToShow.connect(self.__showExtrasMenu) |
|
2793 mb.addMenu(self.__menus["extras"]) |
|
2794 self.viewmanager.addToExtrasMenu(self.__menus["extras"]) |
|
2795 self.__menus["wizards"] = QMenu(self.tr('Wi&zards'), self) |
|
2796 self.__menus["wizards"].setTearOffEnabled(True) |
|
2797 self.__menus["wizards"].aboutToShow.connect(self.__showWizardsMenu) |
|
2798 self.wizardsMenuAct = self.__menus["extras"].addMenu( |
|
2799 self.__menus["wizards"]) |
|
2800 self.wizardsMenuAct.setEnabled(False) |
|
2801 self.__menus["macros"] = self.viewmanager.initMacroMenu() |
|
2802 self.__menus["extras"].addMenu(self.__menus["macros"]) |
|
2803 self.__menus["extras"].addSeparator() |
|
2804 self.__menus["extras"].addAction(self.virtualenvManagerAct) |
|
2805 self.__menus["extras"].addAction(self.virtualenvConfigAct) |
|
2806 self.toolGroupsMenu = QMenu(self.tr("Select Tool Group"), self) |
|
2807 self.toolGroupsMenu.aboutToShow.connect(self.__showToolGroupsMenu) |
|
2808 self.toolGroupsMenu.triggered.connect(self.__toolGroupSelected) |
|
2809 self.toolGroupsMenuTriggered = False |
|
2810 self.__menus["extras"].addSeparator() |
|
2811 self.__initToolsMenus(self.__menus["extras"]) |
|
2812 self.__menus["extras"].addSeparator() |
|
2813 |
|
2814 self.__menus["settings"] = QMenu(self.tr('Se&ttings'), self) |
|
2815 mb.addMenu(self.__menus["settings"]) |
|
2816 self.__menus["settings"].setTearOffEnabled(True) |
|
2817 self.__menus["settings"].addAction(self.prefAct) |
|
2818 self.__menus["settings"].addAction(self.prefExportAct) |
|
2819 self.__menus["settings"].addAction(self.prefImportAct) |
|
2820 self.__menus["settings"].addSeparator() |
|
2821 self.__menus["settings"].addAction(self.reloadAPIsAct) |
|
2822 self.__menus["settings"].addSeparator() |
|
2823 self.__menus["settings"].addAction(self.configViewProfilesAct) |
|
2824 self.__menus["settings"].addAction(self.configToolBarsAct) |
|
2825 self.__menus["settings"].addSeparator() |
|
2826 self.__menus["settings"].addAction(self.shortcutsAct) |
|
2827 self.__menus["settings"].addAction(self.exportShortcutsAct) |
|
2828 self.__menus["settings"].addAction(self.importShortcutsAct) |
|
2829 self.__menus["settings"].addSeparator() |
|
2830 self.__menus["settings"].addAction(self.showExternalToolsAct) |
|
2831 if SSL_AVAILABLE: |
|
2832 self.__menus["settings"].addSeparator() |
|
2833 self.__menus["settings"].addAction(self.certificatesAct) |
|
2834 self.__menus["settings"].addSeparator() |
|
2835 self.__menus["settings"].addAction(self.editMessageFilterAct) |
|
2836 self.__menus["settings"].addSeparator() |
|
2837 self.__menus["settings"].addAction(self.clearPrivateDataAct) |
|
2838 |
|
2839 self.__menus["window"] = QMenu(self.tr('&Window'), self) |
|
2840 mb.addMenu(self.__menus["window"]) |
|
2841 self.__menus["window"].setTearOffEnabled(True) |
|
2842 self.__menus["window"].aboutToShow.connect(self.__showWindowMenu) |
|
2843 |
|
2844 self.__menus["subwindow"] = QMenu(self.tr("&Windows"), |
|
2845 self.__menus["window"]) |
|
2846 self.__menus["subwindow"].setTearOffEnabled(True) |
|
2847 # left side |
|
2848 try: |
|
2849 self.__menus["subwindow"].addSection(self.tr("Left Side")) |
|
2850 except AttributeError: |
|
2851 # Qt4 |
|
2852 pass |
|
2853 self.__menus["subwindow"].addAction(self.pbActivateAct) |
|
2854 self.__menus["subwindow"].addAction(self.mpbActivateAct) |
|
2855 if self.templateViewer is not None: |
|
2856 self.__menus["subwindow"].addAction(self.templateViewerActivateAct) |
|
2857 if self.browser is not None: |
|
2858 self.__menus["subwindow"].addAction(self.browserActivateAct) |
|
2859 if self.symbolsViewer is not None: |
|
2860 self.__menus["subwindow"].addAction(self.symbolsViewerActivateAct) |
|
2861 # bottom side |
|
2862 try: |
|
2863 self.__menus["subwindow"].addSection(self.tr("Bottom Side")) |
|
2864 except AttributeError: |
|
2865 # Qt4 |
|
2866 self.__menus["subwindow"].addSeparator() |
|
2867 self.__menus["subwindow"].addAction(self.shellActivateAct) |
|
2868 self.__menus["subwindow"].addAction(self.taskViewerActivateAct) |
|
2869 self.__menus["subwindow"].addAction(self.logViewerActivateAct) |
|
2870 if self.numbersViewer is not None: |
|
2871 self.__menus["subwindow"].addAction(self.numbersViewerActivateAct) |
|
2872 try: |
|
2873 self.__menus["subwindow"].addSection(self.tr("Right Side")) |
|
2874 except AttributeError: |
|
2875 # Qt4 |
|
2876 self.__menus["subwindow"].addSeparator() |
|
2877 # right side |
|
2878 if self.codeDocumentationViewer is not None: |
|
2879 self.__menus["subwindow"].addAction( |
|
2880 self.tr("Code Documentation Viewer"), |
|
2881 self.activateCodeDocumentationViewer) |
|
2882 self.__menus["subwindow"].addAction(self.debugViewerActivateAct) |
|
2883 if self.pipWidget is not None: |
|
2884 self.__menus["subwindow"].addAction( |
|
2885 self.tr("PyPI"), |
|
2886 self.__activatePipWidget) |
|
2887 if self.condaWidget is not None: |
|
2888 self.__menus["subwindow"].addAction( |
|
2889 self.tr("Conda"), |
|
2890 self.__activateCondaWidget) |
|
2891 if self.cooperation is not None: |
|
2892 self.__menus["subwindow"].addAction( |
|
2893 self.cooperationViewerActivateAct) |
|
2894 if self.irc is not None: |
|
2895 self.__menus["subwindow"].addAction(self.ircActivateAct) |
|
2896 try: |
|
2897 self.__menus["subwindow"].addSection(self.tr("Plug-ins")) |
|
2898 except AttributeError: |
|
2899 # Qt4 |
|
2900 self.__menus["subwindow"].addSeparator() |
|
2901 |
|
2902 self.__menus["toolbars"] = \ |
|
2903 QMenu(self.tr("&Toolbars"), self.__menus["window"]) |
|
2904 self.__menus["toolbars"].setTearOffEnabled(True) |
|
2905 self.__menus["toolbars"].aboutToShow.connect(self.__showToolbarsMenu) |
|
2906 self.__menus["toolbars"].triggered.connect(self.__TBMenuTriggered) |
|
2907 |
|
2908 self.__showWindowMenu() # to initialize these actions |
|
2909 |
|
2910 self.__menus["bookmarks"] = self.viewmanager.initBookmarkMenu() |
|
2911 mb.addMenu(self.__menus["bookmarks"]) |
|
2912 self.__menus["bookmarks"].setTearOffEnabled(True) |
|
2913 |
|
2914 self.__menus["plugins"] = QMenu(self.tr('P&lugins'), self) |
|
2915 mb.addMenu(self.__menus["plugins"]) |
|
2916 self.__menus["plugins"].setTearOffEnabled(True) |
|
2917 self.__menus["plugins"].addAction(self.pluginInfoAct) |
|
2918 self.__menus["plugins"].addAction(self.pluginInstallAct) |
|
2919 self.__menus["plugins"].addAction(self.pluginDeinstallAct) |
|
2920 self.__menus["plugins"].addSeparator() |
|
2921 self.__menus["plugins"].addAction(self.pluginRepoAct) |
|
2922 self.__menus["plugins"].addSeparator() |
|
2923 self.__menus["plugins"].addAction( |
|
2924 self.tr("Configure..."), self.__pluginsConfigure) |
|
2925 |
|
2926 mb.addSeparator() |
|
2927 |
|
2928 self.__menus["help"] = QMenu(self.tr('&Help'), self) |
|
2929 mb.addMenu(self.__menus["help"]) |
|
2930 self.__menus["help"].setTearOffEnabled(True) |
|
2931 if self.helpviewerAct: |
|
2932 self.__menus["help"].addAction(self.helpviewerAct) |
|
2933 self.__menus["help"].addSeparator() |
|
2934 self.__menus["help"].addAction(self.ericDocAct) |
|
2935 self.__menus["help"].addAction(self.pythonDocAct) |
|
2936 self.__menus["help"].addAction(self.python2DocAct) |
|
2937 self.__menus["help"].addAction(self.qt4DocAct) |
|
2938 self.__menus["help"].addAction(self.qt5DocAct) |
|
2939 if self.pyqt4DocAct is not None: |
|
2940 self.__menus["help"].addAction(self.pyqt4DocAct) |
|
2941 if self.pyqt5DocAct is not None: |
|
2942 self.__menus["help"].addAction(self.pyqt5DocAct) |
|
2943 if self.pysideDocAct is not None: |
|
2944 self.__menus["help"].addAction(self.pysideDocAct) |
|
2945 if self.pyside2DocAct is not None: |
|
2946 self.__menus["help"].addAction(self.pyside2DocAct) |
|
2947 self.__menus["help"].addSeparator() |
|
2948 self.__menus["help"].addAction(self.versionAct) |
|
2949 self.__menus["help"].addSeparator() |
|
2950 self.__menus["help"].addAction(self.checkUpdateAct) |
|
2951 self.__menus["help"].addAction(self.showVersionsAct) |
|
2952 self.__menus["help"].addSeparator() |
|
2953 self.__menus["help"].addAction(self.showErrorLogAct) |
|
2954 self.__menus["help"].addAction(self.reportBugAct) |
|
2955 self.__menus["help"].addAction(self.requestFeatureAct) |
|
2956 self.__menus["help"].addSeparator() |
|
2957 self.__menus["help"].addAction(self.whatsThisAct) |
|
2958 self.__menus["help"].aboutToShow.connect(self.__showHelpMenu) |
|
2959 |
|
2960 def getToolBarIconSize(self): |
|
2961 """ |
|
2962 Public method to get the toolbar icon size. |
|
2963 |
|
2964 @return toolbar icon size (QSize) |
|
2965 """ |
|
2966 return Config.ToolBarIconSize |
|
2967 |
|
2968 def __initToolbars(self): |
|
2969 """ |
|
2970 Private slot to create the toolbars. |
|
2971 """ |
|
2972 filetb = self.viewmanager.initFileToolbar(self.toolbarManager) |
|
2973 edittb = self.viewmanager.initEditToolbar(self.toolbarManager) |
|
2974 searchtb, quicksearchtb = self.viewmanager.initSearchToolbars( |
|
2975 self.toolbarManager) |
|
2976 viewtb = self.viewmanager.initViewToolbar(self.toolbarManager) |
|
2977 starttb, debugtb = self.debuggerUI.initToolbars(self.toolbarManager) |
|
2978 multiprojecttb = self.multiProject.initToolbar(self.toolbarManager) |
|
2979 projecttb, vcstb = self.project.initToolbars(self.toolbarManager) |
|
2980 toolstb = QToolBar(self.tr("Tools"), self) |
|
2981 unittesttb = QToolBar(self.tr("Unittest"), self) |
|
2982 bookmarktb = self.viewmanager.initBookmarkToolbar(self.toolbarManager) |
|
2983 spellingtb = self.viewmanager.initSpellingToolbar(self.toolbarManager) |
|
2984 settingstb = QToolBar(self.tr("Settings"), self) |
|
2985 helptb = QToolBar(self.tr("Help"), self) |
|
2986 profilestb = QToolBar(self.tr("Profiles"), self) |
|
2987 pluginstb = QToolBar(self.tr("Plugins"), self) |
|
2988 |
|
2989 toolstb.setIconSize(Config.ToolBarIconSize) |
|
2990 unittesttb.setIconSize(Config.ToolBarIconSize) |
|
2991 settingstb.setIconSize(Config.ToolBarIconSize) |
|
2992 helptb.setIconSize(Config.ToolBarIconSize) |
|
2993 profilestb.setIconSize(Config.ToolBarIconSize) |
|
2994 pluginstb.setIconSize(Config.ToolBarIconSize) |
|
2995 |
|
2996 toolstb.setObjectName("ToolsToolbar") |
|
2997 unittesttb.setObjectName("UnittestToolbar") |
|
2998 settingstb.setObjectName("SettingsToolbar") |
|
2999 helptb.setObjectName("HelpToolbar") |
|
3000 profilestb.setObjectName("ProfilesToolbar") |
|
3001 pluginstb.setObjectName("PluginsToolbar") |
|
3002 |
|
3003 toolstb.setToolTip(self.tr("Tools")) |
|
3004 unittesttb.setToolTip(self.tr("Unittest")) |
|
3005 settingstb.setToolTip(self.tr("Settings")) |
|
3006 helptb.setToolTip(self.tr("Help")) |
|
3007 profilestb.setToolTip(self.tr("Profiles")) |
|
3008 pluginstb.setToolTip(self.tr("Plugins")) |
|
3009 |
|
3010 filetb.addSeparator() |
|
3011 filetb.addAction(self.restartAct) |
|
3012 filetb.addAction(self.exitAct) |
|
3013 act = filetb.actions()[0] |
|
3014 sep = filetb.insertSeparator(act) |
|
3015 filetb.insertAction(sep, self.newWindowAct) |
|
3016 self.toolbarManager.addToolBar(filetb, filetb.windowTitle()) |
|
3017 |
|
3018 # setup the unittest toolbar |
|
3019 unittesttb.addAction(self.utDialogAct) |
|
3020 unittesttb.addSeparator() |
|
3021 unittesttb.addAction(self.utRestartAct) |
|
3022 unittesttb.addAction(self.utRerunFailedAct) |
|
3023 unittesttb.addSeparator() |
|
3024 unittesttb.addAction(self.utScriptAct) |
|
3025 unittesttb.addAction(self.utProjectAct) |
|
3026 self.toolbarManager.addToolBar(unittesttb, unittesttb.windowTitle()) |
|
3027 |
|
3028 # setup the tools toolbar |
|
3029 if self.designer4Act is not None: |
|
3030 toolstb.addAction(self.designer4Act) |
|
3031 if self.linguist4Act is not None: |
|
3032 toolstb.addAction(self.linguist4Act) |
|
3033 toolstb.addAction(self.uipreviewerAct) |
|
3034 toolstb.addAction(self.trpreviewerAct) |
|
3035 toolstb.addSeparator() |
|
3036 toolstb.addAction(self.diffAct) |
|
3037 toolstb.addAction(self.compareAct) |
|
3038 toolstb.addSeparator() |
|
3039 toolstb.addAction(self.sqlBrowserAct) |
|
3040 toolstb.addSeparator() |
|
3041 toolstb.addAction(self.miniEditorAct) |
|
3042 toolstb.addAction(self.hexEditorAct) |
|
3043 toolstb.addAction(self.iconEditorAct) |
|
3044 toolstb.addAction(self.snapshotAct) |
|
3045 toolstb.addSeparator() |
|
3046 toolstb.addAction(self.virtualenvManagerAct) |
|
3047 toolstb.addAction(self.virtualenvConfigAct) |
|
3048 if self.webBrowserAct: |
|
3049 toolstb.addSeparator() |
|
3050 toolstb.addAction(self.webBrowserAct) |
|
3051 self.toolbarManager.addToolBar(toolstb, toolstb.windowTitle()) |
|
3052 |
|
3053 # setup the settings toolbar |
|
3054 settingstb.addAction(self.prefAct) |
|
3055 settingstb.addAction(self.configViewProfilesAct) |
|
3056 settingstb.addAction(self.configToolBarsAct) |
|
3057 settingstb.addAction(self.shortcutsAct) |
|
3058 settingstb.addAction(self.showExternalToolsAct) |
|
3059 self.toolbarManager.addToolBar(settingstb, settingstb.windowTitle()) |
|
3060 self.toolbarManager.addActions([ |
|
3061 self.exportShortcutsAct, |
|
3062 self.importShortcutsAct, |
|
3063 self.prefExportAct, |
|
3064 self.prefImportAct, |
|
3065 self.showExternalToolsAct, |
|
3066 self.editMessageFilterAct, |
|
3067 self.clearPrivateDataAct, |
|
3068 ], settingstb.windowTitle()) |
|
3069 if SSL_AVAILABLE: |
|
3070 self.toolbarManager.addAction( |
|
3071 self.certificatesAct, settingstb.windowTitle()) |
|
3072 |
|
3073 # setup the help toolbar |
|
3074 helptb.addAction(self.whatsThisAct) |
|
3075 self.toolbarManager.addToolBar(helptb, helptb.windowTitle()) |
|
3076 if self.helpviewerAct: |
|
3077 self.toolbarManager.addAction(self.helpviewerAct, |
|
3078 helptb.windowTitle()) |
|
3079 |
|
3080 # setup the view profiles toolbar |
|
3081 profilestb.addActions(self.viewProfileActGrp.actions()) |
|
3082 self.toolbarManager.addToolBar(profilestb, profilestb.windowTitle()) |
|
3083 |
|
3084 # setup the plugins toolbar |
|
3085 pluginstb.addAction(self.pluginInfoAct) |
|
3086 pluginstb.addAction(self.pluginInstallAct) |
|
3087 pluginstb.addAction(self.pluginDeinstallAct) |
|
3088 pluginstb.addSeparator() |
|
3089 pluginstb.addAction(self.pluginRepoAct) |
|
3090 self.toolbarManager.addToolBar(pluginstb, pluginstb.windowTitle()) |
|
3091 |
|
3092 # add the various toolbars |
|
3093 self.addToolBar(filetb) |
|
3094 self.addToolBar(edittb) |
|
3095 self.addToolBar(searchtb) |
|
3096 self.addToolBar(quicksearchtb) |
|
3097 self.addToolBar(viewtb) |
|
3098 self.addToolBar(starttb) |
|
3099 self.addToolBar(debugtb) |
|
3100 self.addToolBar(multiprojecttb) |
|
3101 self.addToolBar(projecttb) |
|
3102 self.addToolBar(vcstb) |
|
3103 self.addToolBar(Qt.RightToolBarArea, settingstb) |
|
3104 self.addToolBar(Qt.RightToolBarArea, toolstb) |
|
3105 self.addToolBar(helptb) |
|
3106 self.addToolBar(bookmarktb) |
|
3107 self.addToolBar(spellingtb) |
|
3108 self.addToolBar(unittesttb) |
|
3109 self.addToolBar(profilestb) |
|
3110 self.addToolBar(pluginstb) |
|
3111 |
|
3112 # hide toolbars not wanted in the initial layout |
|
3113 searchtb.hide() |
|
3114 quicksearchtb.hide() |
|
3115 viewtb.hide() |
|
3116 debugtb.hide() |
|
3117 multiprojecttb.hide() |
|
3118 helptb.hide() |
|
3119 spellingtb.hide() |
|
3120 unittesttb.hide() |
|
3121 pluginstb.hide() |
|
3122 |
|
3123 # just add new toolbars to the end of the list |
|
3124 self.__toolbars = {} |
|
3125 self.__toolbars["file"] = [filetb.windowTitle(), filetb] |
|
3126 self.__toolbars["edit"] = [edittb.windowTitle(), edittb] |
|
3127 self.__toolbars["search"] = [searchtb.windowTitle(), searchtb] |
|
3128 self.__toolbars["view"] = [viewtb.windowTitle(), viewtb] |
|
3129 self.__toolbars["start"] = [starttb.windowTitle(), starttb] |
|
3130 self.__toolbars["debug"] = [debugtb.windowTitle(), debugtb] |
|
3131 self.__toolbars["project"] = [projecttb.windowTitle(), projecttb] |
|
3132 self.__toolbars["tools"] = [toolstb.windowTitle(), toolstb] |
|
3133 self.__toolbars["help"] = [helptb.windowTitle(), helptb] |
|
3134 self.__toolbars["settings"] = [settingstb.windowTitle(), settingstb] |
|
3135 self.__toolbars["bookmarks"] = [bookmarktb.windowTitle(), bookmarktb] |
|
3136 self.__toolbars["unittest"] = [unittesttb.windowTitle(), unittesttb] |
|
3137 self.__toolbars["view_profiles"] = [profilestb.windowTitle(), |
|
3138 profilestb] |
|
3139 self.__toolbars["plugins"] = [pluginstb.windowTitle(), pluginstb] |
|
3140 self.__toolbars["quicksearch"] = [quicksearchtb.windowTitle(), |
|
3141 quicksearchtb] |
|
3142 self.__toolbars["multiproject"] = [multiprojecttb.windowTitle(), |
|
3143 multiprojecttb] |
|
3144 self.__toolbars["spelling"] = [spellingtb.windowTitle(), spellingtb] |
|
3145 self.__toolbars["vcs"] = [vcstb.windowTitle(), vcstb] |
|
3146 |
|
3147 def __initDebugToolbarsLayout(self): |
|
3148 """ |
|
3149 Private slot to initialize the toolbars layout for the debug profile. |
|
3150 """ |
|
3151 # Step 1: set the edit profile to be sure |
|
3152 self.__setEditProfile() |
|
3153 |
|
3154 # Step 2: switch to debug profile and do the layout |
|
3155 initSize = self.size() |
|
3156 self.setDebugProfile() |
|
3157 self.__toolbars["project"][1].hide() |
|
3158 self.__toolbars["debug"][1].show() |
|
3159 self.resize(initSize) |
|
3160 |
|
3161 # Step 3: switch back to edit profile |
|
3162 self.__setEditProfile() |
|
3163 |
|
3164 def __initStatusbar(self): |
|
3165 """ |
|
3166 Private slot to set up the status bar. |
|
3167 """ |
|
3168 self.__statusBar = self.statusBar() |
|
3169 self.__statusBar.setSizeGripEnabled(True) |
|
3170 |
|
3171 self.sbLanguage = E5ClickableLabel(self.__statusBar) |
|
3172 self.__statusBar.addPermanentWidget(self.sbLanguage) |
|
3173 self.sbLanguage.setWhatsThis(self.tr( |
|
3174 """<p>This part of the status bar displays the""" |
|
3175 """ current editors language.</p>""" |
|
3176 )) |
|
3177 |
|
3178 self.sbEncoding = E5ClickableLabel(self.__statusBar) |
|
3179 self.__statusBar.addPermanentWidget(self.sbEncoding) |
|
3180 self.sbEncoding.setWhatsThis(self.tr( |
|
3181 """<p>This part of the status bar displays the""" |
|
3182 """ current editors encoding.</p>""" |
|
3183 )) |
|
3184 |
|
3185 self.sbEol = E5ClickableLabel(self.__statusBar) |
|
3186 self.__statusBar.addPermanentWidget(self.sbEol) |
|
3187 self.sbEol.setWhatsThis(self.tr( |
|
3188 """<p>This part of the status bar displays the""" |
|
3189 """ current editors eol setting.</p>""" |
|
3190 )) |
|
3191 |
|
3192 self.sbWritable = QLabel(self.__statusBar) |
|
3193 self.__statusBar.addPermanentWidget(self.sbWritable) |
|
3194 self.sbWritable.setWhatsThis(self.tr( |
|
3195 """<p>This part of the status bar displays an indication of the""" |
|
3196 """ current editors files writability.</p>""" |
|
3197 )) |
|
3198 |
|
3199 self.sbLine = QLabel(self.__statusBar) |
|
3200 self.__statusBar.addPermanentWidget(self.sbLine) |
|
3201 self.sbLine.setWhatsThis(self.tr( |
|
3202 """<p>This part of the status bar displays the line number of""" |
|
3203 """ the current editor.</p>""" |
|
3204 )) |
|
3205 |
|
3206 self.sbPos = QLabel(self.__statusBar) |
|
3207 self.__statusBar.addPermanentWidget(self.sbPos) |
|
3208 self.sbPos.setWhatsThis(self.tr( |
|
3209 """<p>This part of the status bar displays the cursor position""" |
|
3210 """ of the current editor.</p>""" |
|
3211 )) |
|
3212 |
|
3213 self.sbZoom = E5ZoomWidget( |
|
3214 UI.PixmapCache.getPixmap("zoomOut.png"), |
|
3215 UI.PixmapCache.getPixmap("zoomIn.png"), |
|
3216 UI.PixmapCache.getPixmap("zoomReset.png"), |
|
3217 self.__statusBar) |
|
3218 self.__statusBar.addPermanentWidget(self.sbZoom) |
|
3219 self.sbZoom.setWhatsThis(self.tr( |
|
3220 """<p>This part of the status bar allows zooming the current""" |
|
3221 """ editor, shell or terminal.</p>""" |
|
3222 )) |
|
3223 |
|
3224 self.viewmanager.setSbInfo( |
|
3225 self.sbLine, self.sbPos, self.sbWritable, self.sbEncoding, |
|
3226 self.sbLanguage, self.sbEol, self.sbZoom) |
|
3227 |
|
3228 from VCS.StatusMonitorLed import StatusMonitorLedWidget |
|
3229 self.sbVcsMonitorLed = StatusMonitorLedWidget( |
|
3230 self.project, self.__statusBar) |
|
3231 self.__statusBar.addPermanentWidget(self.sbVcsMonitorLed) |
|
3232 |
|
3233 self.networkIcon = E5NetworkIcon(self.__statusBar) |
|
3234 self.__statusBar.addPermanentWidget(self.networkIcon) |
|
3235 self.networkIcon.onlineStateChanged.connect(self.onlineStateChanged) |
|
3236 self.networkIcon.onlineStateChanged.connect(self.__onlineStateChanged) |
|
3237 |
|
3238 def __initExternalToolsActions(self): |
|
3239 """ |
|
3240 Private slot to create actions for the configured external tools. |
|
3241 """ |
|
3242 self.toolGroupActions = {} |
|
3243 for toolGroup in self.toolGroups: |
|
3244 category = self.tr("External Tools/{0}").format(toolGroup[0]) |
|
3245 for tool in toolGroup[1]: |
|
3246 if tool['menutext'] != '--': |
|
3247 act = QAction(UI.PixmapCache.getIcon(tool['icon']), |
|
3248 tool['menutext'], self) |
|
3249 act.setObjectName("{0}@@{1}".format(toolGroup[0], |
|
3250 tool['menutext'])) |
|
3251 act.triggered.connect( |
|
3252 lambda: self.__toolActionTriggered(act)) |
|
3253 self.toolGroupActions[act.objectName()] = act |
|
3254 |
|
3255 self.toolbarManager.addAction(act, category) |
|
3256 |
|
3257 def __updateExternalToolsActions(self): |
|
3258 """ |
|
3259 Private method to update the external tools actions for the current |
|
3260 tool group. |
|
3261 """ |
|
3262 toolGroup = self.toolGroups[self.currentToolGroup] |
|
3263 groupkey = "{0}@@".format(toolGroup[0]) |
|
3264 groupActionKeys = [] |
|
3265 # step 1: get actions for this group |
|
3266 for key in self.toolGroupActions: |
|
3267 if key.startswith(groupkey): |
|
3268 groupActionKeys.append(key) |
|
3269 |
|
3270 # step 2: build keys for all actions i.a.w. current configuration |
|
3271 ckeys = [] |
|
3272 for tool in toolGroup[1]: |
|
3273 if tool['menutext'] != '--': |
|
3274 ckeys.append("{0}@@{1}".format(toolGroup[0], tool['menutext'])) |
|
3275 |
|
3276 # step 3: remove all actions not configured any more |
|
3277 for key in groupActionKeys: |
|
3278 if key not in ckeys: |
|
3279 self.toolbarManager.removeAction(self.toolGroupActions[key]) |
|
3280 self.toolGroupActions[key].triggered.disconnect() |
|
3281 del self.toolGroupActions[key] |
|
3282 |
|
3283 # step 4: add all newly configured tools |
|
3284 category = self.tr("External Tools/{0}").format(toolGroup[0]) |
|
3285 for tool in toolGroup[1]: |
|
3286 if tool['menutext'] != '--': |
|
3287 key = "{0}@@{1}".format(toolGroup[0], tool['menutext']) |
|
3288 if key not in groupActionKeys: |
|
3289 act = QAction(UI.PixmapCache.getIcon(tool['icon']), |
|
3290 tool['menutext'], self) |
|
3291 act.setObjectName(key) |
|
3292 act.triggered.connect( |
|
3293 lambda: self.__toolActionTriggered(act)) |
|
3294 self.toolGroupActions[key] = act |
|
3295 |
|
3296 self.toolbarManager.addAction(act, category) |
|
3297 |
|
3298 def __showFileMenu(self): |
|
3299 """ |
|
3300 Private slot to display the File menu. |
|
3301 """ |
|
3302 self.showMenu.emit("File", self.__menus["file"]) |
|
3303 |
|
3304 def __showExtrasMenu(self): |
|
3305 """ |
|
3306 Private slot to display the Extras menu. |
|
3307 """ |
|
3308 self.showMenu.emit("Extras", self.__menus["extras"]) |
|
3309 |
|
3310 def __showWizardsMenu(self): |
|
3311 """ |
|
3312 Private slot to display the Wizards menu. |
|
3313 """ |
|
3314 self.showMenu.emit("Wizards", self.__menus["wizards"]) |
|
3315 |
|
3316 def __showHelpMenu(self): |
|
3317 """ |
|
3318 Private slot to display the Help menu. |
|
3319 """ |
|
3320 self.checkUpdateAct.setEnabled(not self.__inVersionCheck) |
|
3321 self.showVersionsAct.setEnabled(not self.__inVersionCheck) |
|
3322 self.showErrorLogAct.setEnabled(self.__hasErrorLog()) |
|
3323 |
|
3324 self.showMenu.emit("Help", self.__menus["help"]) |
|
3325 |
|
3326 def __showSettingsMenu(self): |
|
3327 """ |
|
3328 Private slot to show the Settings menu. |
|
3329 """ |
|
3330 self.editMessageFilterAct.setEnabled( |
|
3331 E5ErrorMessage.messageHandlerInstalled()) |
|
3332 |
|
3333 self.showMenu.emit("Settings", self.__menus["settings"]) |
|
3334 |
|
3335 def __showNext(self): |
|
3336 """ |
|
3337 Private slot used to show the next tab or file. |
|
3338 """ |
|
3339 fwidget = QApplication.focusWidget() |
|
3340 while fwidget and not hasattr(fwidget, 'nextTab'): |
|
3341 fwidget = fwidget.parent() |
|
3342 if fwidget: |
|
3343 fwidget.nextTab() |
|
3344 |
|
3345 def __showPrevious(self): |
|
3346 """ |
|
3347 Private slot used to show the previous tab or file. |
|
3348 """ |
|
3349 fwidget = QApplication.focusWidget() |
|
3350 while fwidget and not hasattr(fwidget, 'prevTab'): |
|
3351 fwidget = fwidget.parent() |
|
3352 if fwidget: |
|
3353 fwidget.prevTab() |
|
3354 |
|
3355 def __switchTab(self): |
|
3356 """ |
|
3357 Private slot used to switch between the current and the previous |
|
3358 current tab. |
|
3359 """ |
|
3360 fwidget = QApplication.focusWidget() |
|
3361 while fwidget and not hasattr(fwidget, 'switchTab'): |
|
3362 fwidget = fwidget.parent() |
|
3363 if fwidget: |
|
3364 fwidget.switchTab() |
|
3365 |
|
3366 def __whatsThis(self): |
|
3367 """ |
|
3368 Private slot called in to enter Whats This mode. |
|
3369 """ |
|
3370 QWhatsThis.enterWhatsThisMode() |
|
3371 |
|
3372 def __showVersions(self): |
|
3373 """ |
|
3374 Private slot to handle the Versions dialog. |
|
3375 """ |
|
3376 try: |
|
3377 try: |
|
3378 from PyQt5 import sip |
|
3379 except ImportError: |
|
3380 import sip |
|
3381 sip_version_str = sip.SIP_VERSION_STR |
|
3382 except (ImportError, AttributeError): |
|
3383 sip_version_str = "sip version not available" |
|
3384 |
|
3385 if sys.maxsize > 2**32: |
|
3386 sizeStr = "64-Bit" |
|
3387 else: |
|
3388 sizeStr = "32-Bit" |
|
3389 |
|
3390 versionText = self.tr( |
|
3391 """<h3>Version Numbers</h3>""" |
|
3392 """<table>""") |
|
3393 versionText += """<tr><td><b>Python</b></td><td>{0}, {1}</td></tr>"""\ |
|
3394 .format(sys.version.split()[0], sizeStr) |
|
3395 versionText += """<tr><td><b>Qt</b></td><td>{0}</td></tr>"""\ |
|
3396 .format(qVersion()) |
|
3397 versionText += """<tr><td><b>PyQt</b></td><td>{0}</td></tr>"""\ |
|
3398 .format(PYQT_VERSION_STR) |
|
3399 versionText += """<tr><td><b>sip</b></td><td>{0}</td></tr>"""\ |
|
3400 .format(sip_version_str) |
|
3401 versionText += """<tr><td><b>QScintilla</b></td><td>{0}</td></tr>"""\ |
|
3402 .format(QSCINTILLA_VERSION_STR) |
|
3403 try: |
|
3404 from WebBrowser.Tools import WebBrowserTools |
|
3405 chromeVersion = WebBrowserTools.getWebEngineVersions()[0] |
|
3406 versionText += \ |
|
3407 """<tr><td><b>WebEngine</b></td><td>{0}</td></tr>"""\ |
|
3408 .format(chromeVersion) |
|
3409 except ImportError: |
|
3410 pass |
|
3411 try: |
|
3412 from PyQt5.QtWebKit import qWebKitVersion |
|
3413 versionText += """<tr><td><b>WebKit</b></td><td>{0}</td></tr>"""\ |
|
3414 .format(qWebKitVersion()) |
|
3415 except ImportError: |
|
3416 pass |
|
3417 versionText += """<tr><td><b>{0}</b></td><td>{1}</td></tr>"""\ |
|
3418 .format(Program, Version) |
|
3419 versionText += self.tr("""</table>""") |
|
3420 |
|
3421 E5MessageBox.about(self, Program, versionText) |
|
3422 |
|
3423 def __reportBug(self): |
|
3424 """ |
|
3425 Private slot to handle the Report Bug dialog. |
|
3426 """ |
|
3427 self.showEmailDialog("bug") |
|
3428 |
|
3429 def __requestFeature(self): |
|
3430 """ |
|
3431 Private slot to handle the Feature Request dialog. |
|
3432 """ |
|
3433 self.showEmailDialog("feature") |
|
3434 |
|
3435 def showEmailDialog(self, mode, attachFile=None, deleteAttachFile=False): |
|
3436 """ |
|
3437 Public slot to show the email dialog in a given mode. |
|
3438 |
|
3439 @param mode mode of the email dialog (string, "bug" or "feature") |
|
3440 @param attachFile name of a file to attach to the email (string) |
|
3441 @param deleteAttachFile flag indicating to delete the attached file |
|
3442 after it has been sent (boolean) |
|
3443 """ |
|
3444 if Preferences.getUser("UseSystemEmailClient"): |
|
3445 self.__showSystemEmailClient(mode, attachFile, deleteAttachFile) |
|
3446 else: |
|
3447 if not Preferences.getUser("UseGoogleMailOAuth2") and ( |
|
3448 Preferences.getUser("Email") == "" or |
|
3449 Preferences.getUser("MailServer") == ""): |
|
3450 E5MessageBox.critical( |
|
3451 self, |
|
3452 self.tr("Report Bug"), |
|
3453 self.tr( |
|
3454 """Email address or mail server address is empty.""" |
|
3455 """ Please configure your Email settings in the""" |
|
3456 """ Preferences Dialog.""")) |
|
3457 self.showPreferences("emailPage") |
|
3458 return |
|
3459 |
|
3460 from .EmailDialog import EmailDialog |
|
3461 self.dlg = EmailDialog(mode=mode) |
|
3462 if attachFile is not None: |
|
3463 self.dlg.attachFile(attachFile, deleteAttachFile) |
|
3464 self.dlg.show() |
|
3465 |
|
3466 def __showSystemEmailClient(self, mode, attachFile=None, |
|
3467 deleteAttachFile=False): |
|
3468 """ |
|
3469 Private slot to show the system email dialog. |
|
3470 |
|
3471 @param mode mode of the email dialog (string, "bug" or "feature") |
|
3472 @param attachFile name of a file to put into the body of the |
|
3473 email (string) |
|
3474 @param deleteAttachFile flag indicating to delete the file after |
|
3475 it has been read (boolean) |
|
3476 """ |
|
3477 if mode == "feature": |
|
3478 address = FeatureAddress |
|
3479 else: |
|
3480 address = BugAddress |
|
3481 subject = "[eric6] " |
|
3482 if attachFile is not None: |
|
3483 f = open(attachFile, "r", encoding="utf-8") |
|
3484 body = f.read() |
|
3485 f.close() |
|
3486 if deleteAttachFile: |
|
3487 os.remove(attachFile) |
|
3488 else: |
|
3489 body = "\r\n----\r\n{0}----\r\n{1}----\r\n{2}".format( |
|
3490 Utilities.generateVersionInfo("\r\n"), |
|
3491 Utilities.generatePluginsVersionInfo("\r\n"), |
|
3492 Utilities.generateDistroInfo("\r\n")) |
|
3493 |
|
3494 url = QUrl("mailto:{0}".format(address)) |
|
3495 if qVersionTuple() >= (5, 0, 0): |
|
3496 from PyQt5.QtCore import QUrlQuery |
|
3497 urlQuery = QUrlQuery(url) |
|
3498 urlQuery.addQueryItem("subject", subject) |
|
3499 urlQuery.addQueryItem("body", body) |
|
3500 url.setQuery(urlQuery) |
|
3501 else: |
|
3502 url.addQueryItem("subject", subject) |
|
3503 url.addQueryItem("body", body) |
|
3504 QDesktopServices.openUrl(url) |
|
3505 |
|
3506 def checkForErrorLog(self): |
|
3507 """ |
|
3508 Public method to check for the presence of an error log and ask the |
|
3509 user, what to do with it. |
|
3510 """ |
|
3511 if Preferences.getUI("CheckErrorLog"): |
|
3512 logFile = os.path.join(Utilities.getConfigDir(), |
|
3513 self.ErrorLogFileName) |
|
3514 if os.path.exists(logFile): |
|
3515 from .ErrorLogDialog import ErrorLogDialog |
|
3516 dlg = ErrorLogDialog(logFile, False, self) |
|
3517 dlg.exec_() |
|
3518 |
|
3519 def __hasErrorLog(self): |
|
3520 """ |
|
3521 Private method to check, if an error log file exists. |
|
3522 |
|
3523 @return flag indicating the existence of an error log file (boolean) |
|
3524 """ |
|
3525 logFile = os.path.join(Utilities.getConfigDir(), |
|
3526 self.ErrorLogFileName) |
|
3527 return os.path.exists(logFile) |
|
3528 |
|
3529 def __showErrorLog(self): |
|
3530 """ |
|
3531 Private slot to show the most recent error log message. |
|
3532 """ |
|
3533 logFile = os.path.join(Utilities.getConfigDir(), |
|
3534 self.ErrorLogFileName) |
|
3535 if os.path.exists(logFile): |
|
3536 from .ErrorLogDialog import ErrorLogDialog |
|
3537 dlg = ErrorLogDialog(logFile, True, self) |
|
3538 dlg.show() |
|
3539 |
|
3540 def __compareFiles(self): |
|
3541 """ |
|
3542 Private slot to handle the Compare Files dialog. |
|
3543 """ |
|
3544 aw = self.viewmanager.activeWindow() |
|
3545 fn = aw and aw.getFileName() or None |
|
3546 if self.diffDlg is None: |
|
3547 from .DiffDialog import DiffDialog |
|
3548 self.diffDlg = DiffDialog() |
|
3549 self.diffDlg.show(fn) |
|
3550 |
|
3551 def __compareFilesSbs(self): |
|
3552 """ |
|
3553 Private slot to handle the Compare Files dialog. |
|
3554 """ |
|
3555 aw = self.viewmanager.activeWindow() |
|
3556 fn = aw and aw.getFileName() or None |
|
3557 if self.compareDlg is None: |
|
3558 from .CompareDialog import CompareDialog |
|
3559 self.compareDlg = CompareDialog() |
|
3560 self.compareDlg.show(fn) |
|
3561 |
|
3562 def __openMiniEditor(self): |
|
3563 """ |
|
3564 Private slot to show a mini editor window. |
|
3565 """ |
|
3566 from QScintilla.MiniEditor import MiniEditor |
|
3567 editor = MiniEditor(parent=self) |
|
3568 editor.show() |
|
3569 |
|
3570 def addE5Actions(self, actions, actionType): |
|
3571 """ |
|
3572 Public method to add actions to the list of actions. |
|
3573 |
|
3574 @param actions list of actions to be added (list of E5Action) |
|
3575 @param actionType string denoting the action set to add to. |
|
3576 It must be one of "ui" or "wizards". |
|
3577 """ |
|
3578 if actionType == 'ui': |
|
3579 self.actions.extend(actions) |
|
3580 elif actionType == 'wizards': |
|
3581 self.wizardsActions.extend(actions) |
|
3582 |
|
3583 def removeE5Actions(self, actions, actionType='ui'): |
|
3584 """ |
|
3585 Public method to remove actions from the list of actions. |
|
3586 |
|
3587 @param actions list of actions (list of E5Action) |
|
3588 @param actionType string denoting the action set to remove from. |
|
3589 It must be one of "ui" or "wizards". |
|
3590 """ |
|
3591 for act in actions: |
|
3592 try: |
|
3593 if actionType == 'ui': |
|
3594 self.actions.remove(act) |
|
3595 elif actionType == 'wizards': |
|
3596 self.wizardsActions.remove(act) |
|
3597 except ValueError: |
|
3598 pass |
|
3599 |
|
3600 def getActions(self, actionType): |
|
3601 """ |
|
3602 Public method to get a list of all actions. |
|
3603 |
|
3604 @param actionType string denoting the action set to get. |
|
3605 It must be one of "ui" or "wizards". |
|
3606 @return list of all actions (list of E5Action) |
|
3607 """ |
|
3608 if actionType == 'ui': |
|
3609 return self.actions[:] |
|
3610 elif actionType == 'wizards': |
|
3611 return self.wizardsActions[:] |
|
3612 else: |
|
3613 return [] |
|
3614 |
|
3615 def getMenuAction(self, menuName, actionName): |
|
3616 """ |
|
3617 Public method to get a reference to an action of a menu. |
|
3618 |
|
3619 @param menuName name of the menu to search in (string) |
|
3620 @param actionName object name of the action to search for |
|
3621 (string) |
|
3622 @return reference to the menu action (QAction) |
|
3623 """ |
|
3624 try: |
|
3625 menu = self.__menus[menuName] |
|
3626 except KeyError: |
|
3627 return None |
|
3628 |
|
3629 for act in menu.actions(): |
|
3630 if act.objectName() == actionName: |
|
3631 return act |
|
3632 |
|
3633 return None |
|
3634 |
|
3635 def getMenuBarAction(self, menuName): |
|
3636 """ |
|
3637 Public method to get a reference to an action of the main menu. |
|
3638 |
|
3639 @param menuName name of the menu to search in (string) |
|
3640 @return reference to the menu bar action (QAction) |
|
3641 """ |
|
3642 try: |
|
3643 menu = self.__menus[menuName] |
|
3644 except KeyError: |
|
3645 return None |
|
3646 |
|
3647 return menu.menuAction() |
|
3648 |
|
3649 def getMenu(self, name): |
|
3650 """ |
|
3651 Public method to get a reference to a specific menu. |
|
3652 |
|
3653 @param name name of the menu (string) |
|
3654 @return reference to the menu (QMenu) |
|
3655 """ |
|
3656 try: |
|
3657 return self.__menus[name] |
|
3658 except KeyError: |
|
3659 return None |
|
3660 |
|
3661 def registerToolbar(self, name, text, toolbar): |
|
3662 """ |
|
3663 Public method to register a toolbar. |
|
3664 |
|
3665 This method must be called in order to make a toolbar manageable by the |
|
3666 UserInterface object. |
|
3667 |
|
3668 @param name name of the toolbar (string). This is used as the key into |
|
3669 the dictionary of toolbar references. |
|
3670 @param text user visible text for the toolbar entry (string) |
|
3671 @param toolbar reference to the toolbar to be registered (QToolBar) |
|
3672 @exception KeyError raised, if a toolbar with the given name was |
|
3673 already registered |
|
3674 """ |
|
3675 if name in self.__toolbars: |
|
3676 raise KeyError("Toolbar '{0}' already registered.".format(name)) |
|
3677 |
|
3678 self.__toolbars[name] = [text, toolbar] |
|
3679 |
|
3680 def reregisterToolbar(self, name, text): |
|
3681 """ |
|
3682 Public method to change the visible text for the named toolbar. |
|
3683 |
|
3684 @param name name of the toolbar to be changed (string) |
|
3685 @param text new user visible text for the toolbar entry (string) |
|
3686 """ |
|
3687 if name in self.__toolbars: |
|
3688 self.__toolbars[name][0] = text |
|
3689 |
|
3690 def unregisterToolbar(self, name): |
|
3691 """ |
|
3692 Public method to unregister a toolbar. |
|
3693 |
|
3694 @param name name of the toolbar (string). |
|
3695 """ |
|
3696 if name in self.__toolbars: |
|
3697 del self.__toolbars[name] |
|
3698 |
|
3699 def getToolbar(self, name): |
|
3700 """ |
|
3701 Public method to get a reference to a specific toolbar. |
|
3702 |
|
3703 @param name name of the toolbar (string) |
|
3704 @return reference to the toolbar entry (tuple of string and QToolBar) |
|
3705 """ |
|
3706 try: |
|
3707 return self.__toolbars[name] |
|
3708 except KeyError: |
|
3709 return None |
|
3710 |
|
3711 def getLocale(self): |
|
3712 """ |
|
3713 Public method to get the locale of the IDE. |
|
3714 |
|
3715 @return locale of the IDE (string or None) |
|
3716 """ |
|
3717 return self.locale |
|
3718 |
|
3719 def __quit(self): |
|
3720 """ |
|
3721 Private method to quit the application. |
|
3722 """ |
|
3723 if self.__shutdown(): |
|
3724 e5App().closeAllWindows() |
|
3725 |
|
3726 @pyqtSlot() |
|
3727 def __restart(self, ask=False): |
|
3728 """ |
|
3729 Private method to restart the application. |
|
3730 |
|
3731 @param ask flag indicating to ask the user for permission |
|
3732 @type bool |
|
3733 """ |
|
3734 if ask: |
|
3735 res = E5MessageBox.yesNo( |
|
3736 self, |
|
3737 self.tr("Restart application"), |
|
3738 self.tr( |
|
3739 """The application needs to be restarted. Do it now?"""), |
|
3740 yesDefault=True) |
|
3741 else: |
|
3742 res = True |
|
3743 |
|
3744 if res and self.__shutdown(): |
|
3745 e5App().closeAllWindows() |
|
3746 program = sys.executable |
|
3747 eric6 = os.path.join(getConfig("ericDir"), "eric6.py") |
|
3748 args = [eric6] |
|
3749 args.append("--start-session") |
|
3750 args.extend(self.__restartArgs) |
|
3751 QProcess.startDetached(program, args) |
|
3752 |
|
3753 def __newWindow(self): |
|
3754 """ |
|
3755 Private slot to start a new instance of eric6. |
|
3756 """ |
|
3757 if not Preferences.getUI("SingleApplicationMode"): |
|
3758 # start eric6 without any arguments |
|
3759 program = sys.executable |
|
3760 eric6 = os.path.join(getConfig("ericDir"), "eric6.py") |
|
3761 args = [eric6] |
|
3762 QProcess.startDetached(program, args) |
|
3763 |
|
3764 def __initToolsMenus(self, menu): |
|
3765 """ |
|
3766 Private slot to initialize the various tool menus. |
|
3767 |
|
3768 @param menu reference to the parent menu |
|
3769 @type QMenu |
|
3770 """ |
|
3771 btMenu = QMenu(self.tr("&Builtin Tools"), self) |
|
3772 if self.designer4Act is not None: |
|
3773 btMenu.addAction(self.designer4Act) |
|
3774 if self.linguist4Act is not None: |
|
3775 btMenu.addAction(self.linguist4Act) |
|
3776 btMenu.addAction(self.uipreviewerAct) |
|
3777 btMenu.addAction(self.trpreviewerAct) |
|
3778 btMenu.addAction(self.diffAct) |
|
3779 btMenu.addAction(self.compareAct) |
|
3780 btMenu.addAction(self.sqlBrowserAct) |
|
3781 btMenu.addAction(self.miniEditorAct) |
|
3782 btMenu.addAction(self.hexEditorAct) |
|
3783 btMenu.addAction(self.iconEditorAct) |
|
3784 btMenu.addAction(self.snapshotAct) |
|
3785 if self.webBrowserAct: |
|
3786 btMenu.addAction(self.webBrowserAct) |
|
3787 |
|
3788 ptMenu = QMenu(self.tr("&Plugin Tools"), self) |
|
3789 ptMenu.aboutToShow.connect(self.__showPluginToolsMenu) |
|
3790 |
|
3791 utMenu = QMenu(self.tr("&User Tools"), self) |
|
3792 utMenu.triggered.connect(self.__toolExecute) |
|
3793 utMenu.aboutToShow.connect(self.__showUserToolsMenu) |
|
3794 |
|
3795 menu.addMenu(btMenu) |
|
3796 menu.addMenu(ptMenu) |
|
3797 menu.addMenu(utMenu) |
|
3798 |
|
3799 self.__menus["builtin_tools"] = btMenu |
|
3800 self.__menus["plugin_tools"] = ptMenu |
|
3801 self.__menus["user_tools"] = utMenu |
|
3802 |
|
3803 def __showPluginToolsMenu(self): |
|
3804 """ |
|
3805 Private slot to show the Plugin Tools menu. |
|
3806 """ |
|
3807 self.showMenu.emit("PluginTools", self.__menus["plugin_tools"]) |
|
3808 |
|
3809 def __showUserToolsMenu(self): |
|
3810 """ |
|
3811 Private slot to display the User Tools menu. |
|
3812 """ |
|
3813 self.__menus["user_tools"].clear() |
|
3814 |
|
3815 self.__menus["user_tools"].addMenu(self.toolGroupsMenu) |
|
3816 act = self.__menus["user_tools"].addAction( |
|
3817 self.tr("Configure Tool Groups ..."), |
|
3818 self.__toolGroupsConfiguration) |
|
3819 act.setData(-1) |
|
3820 act = self.__menus["user_tools"].addAction( |
|
3821 self.tr("Configure current Tool Group ..."), |
|
3822 self.__toolsConfiguration) |
|
3823 act.setData(-2) |
|
3824 act.setEnabled(self.currentToolGroup >= 0) |
|
3825 self.__menus["user_tools"].addSeparator() |
|
3826 |
|
3827 # add the configurable entries |
|
3828 idx = 0 |
|
3829 try: |
|
3830 for tool in self.toolGroups[self.currentToolGroup][1]: |
|
3831 if tool['menutext'] == '--': |
|
3832 self.__menus["user_tools"].addSeparator() |
|
3833 else: |
|
3834 act = self.__menus["user_tools"].addAction( |
|
3835 UI.PixmapCache.getIcon(tool['icon']), |
|
3836 tool['menutext']) |
|
3837 act.setData(idx) |
|
3838 idx += 1 |
|
3839 except IndexError: |
|
3840 # the current tool group might have been deleted |
|
3841 act = self.__menus["user_tools"].addAction( |
|
3842 self.tr("No User Tools Configured")) |
|
3843 act.setData(-3) |
|
3844 |
|
3845 def __showToolGroupsMenu(self): |
|
3846 """ |
|
3847 Private slot to display the Tool Groups menu. |
|
3848 """ |
|
3849 self.toolGroupsMenu.clear() |
|
3850 |
|
3851 # add the configurable tool groups |
|
3852 if self.toolGroups: |
|
3853 idx = 0 |
|
3854 for toolGroup in self.toolGroups: |
|
3855 act = self.toolGroupsMenu.addAction(toolGroup[0]) |
|
3856 act.setData(idx) |
|
3857 if self.currentToolGroup == idx: |
|
3858 font = act.font() |
|
3859 font.setBold(True) |
|
3860 act.setFont(font) |
|
3861 idx += 1 |
|
3862 else: |
|
3863 act = self.toolGroupsMenu.addAction( |
|
3864 self.tr("No User Tools Configured")) |
|
3865 act.setData(-3) |
|
3866 |
|
3867 def __toolGroupSelected(self, act): |
|
3868 """ |
|
3869 Private slot to set the current tool group. |
|
3870 |
|
3871 @param act reference to the action that was triggered (QAction) |
|
3872 """ |
|
3873 self.toolGroupsMenuTriggered = True |
|
3874 idx = act.data() |
|
3875 if idx is not None: |
|
3876 self.currentToolGroup = idx |
|
3877 |
|
3878 def __showWindowMenu(self): |
|
3879 """ |
|
3880 Private slot to display the Window menu. |
|
3881 """ |
|
3882 self.__menus["window"].clear() |
|
3883 |
|
3884 self.__menus["window"].addActions(self.viewProfileActGrp.actions()) |
|
3885 self.__menus["window"].addSeparator() |
|
3886 |
|
3887 if self.__layoutType == "Toolboxes": |
|
3888 self.__menus["window"].addAction(self.ltAct) |
|
3889 self.ltAct.setChecked(not self.lToolboxDock.isHidden()) |
|
3890 self.__menus["window"].addAction(self.rtAct) |
|
3891 self.rtAct.setChecked(not self.lToolboxDock.isHidden()) |
|
3892 self.__menus["window"].addAction(self.htAct) |
|
3893 self.htAct.setChecked(not self.hToolboxDock.isHidden()) |
|
3894 elif self.__layoutType == "Sidebars": |
|
3895 self.__menus["window"].addAction(self.lsbAct) |
|
3896 self.lsbAct.setChecked(not self.leftSidebar.isHidden()) |
|
3897 self.__menus["window"].addAction(self.rsbAct) |
|
3898 self.rsbAct.setChecked(not self.rightSidebar.isHidden()) |
|
3899 self.__menus["window"].addAction(self.bsbAct) |
|
3900 self.bsbAct.setChecked(not self.bottomSidebar.isHidden()) |
|
3901 |
|
3902 # Insert menu entry for sub-windows |
|
3903 self.__menus["window"].addSeparator() |
|
3904 self.__menus["window"].addMenu(self.__menus["subwindow"]) |
|
3905 |
|
3906 # Insert menu entry for toolbar settings |
|
3907 self.__menus["window"].addSeparator() |
|
3908 self.__menus["window"].addMenu(self.__menus["toolbars"]) |
|
3909 |
|
3910 # Now do any Source Viewer related stuff. |
|
3911 self.viewmanager.showWindowMenu(self.__menus["window"]) |
|
3912 |
|
3913 self.showMenu.emit("Window", self.__menus["window"]) |
|
3914 |
|
3915 def __showSubWindowMenu(self): |
|
3916 """ |
|
3917 Private slot to display the Window menu of the Window menu. |
|
3918 """ |
|
3919 self.showMenu.emit("Subwindows", self.__menus["subwindow"]) |
|
3920 |
|
3921 def __populateToolbarsMenu(self, menu): |
|
3922 """ |
|
3923 Private method to populate a toolbars menu. |
|
3924 |
|
3925 @param menu reference to the menu to be populated (QMenu) |
|
3926 """ |
|
3927 menu.clear() |
|
3928 |
|
3929 for name, (text, tb) in sorted(self.__toolbars.items(), |
|
3930 key=lambda t: t[1][0]): |
|
3931 act = menu.addAction(text) |
|
3932 act.setCheckable(True) |
|
3933 act.setChecked(not tb.isHidden()) |
|
3934 act.setData(name) |
|
3935 menu.addSeparator() |
|
3936 act = menu.addAction(self.tr("&Show all")) |
|
3937 act.setData("__SHOW__") |
|
3938 act = menu.addAction(self.tr("&Hide all")) |
|
3939 act.setData("__HIDE__") |
|
3940 |
|
3941 def createPopupMenu(self): |
|
3942 """ |
|
3943 Public method to create the toolbars menu for Qt. |
|
3944 |
|
3945 @return toolbars menu (QMenu) |
|
3946 """ |
|
3947 menu = QMenu(self) |
|
3948 menu.triggered.connect(self.__TBPopupMenuTriggered) |
|
3949 |
|
3950 self.__populateToolbarsMenu(menu) |
|
3951 |
|
3952 return menu |
|
3953 |
|
3954 def __showToolbarsMenu(self): |
|
3955 """ |
|
3956 Private slot to display the Toolbars menu. |
|
3957 """ |
|
3958 self.__populateToolbarsMenu(self.__menus["toolbars"]) |
|
3959 |
|
3960 def __TBMenuTriggered(self, act): |
|
3961 """ |
|
3962 Private method to handle the toggle of a toolbar via the Window-> |
|
3963 Toolbars submenu. |
|
3964 |
|
3965 @param act reference to the action that was triggered (QAction) |
|
3966 """ |
|
3967 name = act.data() |
|
3968 if name: |
|
3969 if name == "__SHOW__": |
|
3970 for _text, tb in self.__toolbars.values(): |
|
3971 tb.show() |
|
3972 if self.__menus["toolbars"].isTearOffMenuVisible(): |
|
3973 self.__menus["toolbars"].hideTearOffMenu() |
|
3974 elif name == "__HIDE__": |
|
3975 for _text, tb in self.__toolbars.values(): |
|
3976 tb.hide() |
|
3977 if self.__menus["toolbars"].isTearOffMenuVisible(): |
|
3978 self.__menus["toolbars"].hideTearOffMenu() |
|
3979 else: |
|
3980 tb = self.__toolbars[name][1] |
|
3981 if act.isChecked(): |
|
3982 tb.show() |
|
3983 else: |
|
3984 tb.hide() |
|
3985 |
|
3986 def __TBPopupMenuTriggered(self, act): |
|
3987 """ |
|
3988 Private method to handle the toggle of a toolbar via the QMainWindow |
|
3989 Toolbars popup menu. |
|
3990 |
|
3991 @param act reference to the action that was triggered (QAction) |
|
3992 """ |
|
3993 name = act.data() |
|
3994 if name: |
|
3995 if name == "__SHOW__": |
|
3996 for _text, tb in self.__toolbars.values(): |
|
3997 tb.show() |
|
3998 elif name == "__HIDE__": |
|
3999 for _text, tb in self.__toolbars.values(): |
|
4000 tb.hide() |
|
4001 else: |
|
4002 tb = self.__toolbars[name][1] |
|
4003 if act.isChecked(): |
|
4004 tb.show() |
|
4005 else: |
|
4006 tb.hide() |
|
4007 if self.__menus["toolbars"].isTearOffMenuVisible(): |
|
4008 self.__menus["toolbars"].hideTearOffMenu() |
|
4009 |
|
4010 def __saveCurrentViewProfile(self, save): |
|
4011 """ |
|
4012 Private slot to save the window geometries of the active profile. |
|
4013 |
|
4014 @param save flag indicating that the current profile should |
|
4015 be saved (boolean) |
|
4016 """ |
|
4017 if self.currentProfile and save: |
|
4018 # step 1: save the window geometries of the active profile |
|
4019 if self.__layoutType in ["Toolboxes", "Sidebars"]: |
|
4020 state = self.saveState() |
|
4021 self.profiles[self.currentProfile][0] = state |
|
4022 if self.__layoutType == "Sidebars": |
|
4023 state = self.leftSplitter.saveState() |
|
4024 self.profiles[self.currentProfile][2][0] = state |
|
4025 state = self.verticalSplitter.saveState() |
|
4026 self.profiles[self.currentProfile][2][1] = state |
|
4027 state = self.leftSidebar.saveState() |
|
4028 self.profiles[self.currentProfile][2][2] = state |
|
4029 state = self.bottomSidebar.saveState() |
|
4030 self.profiles[self.currentProfile][2][3] = state |
|
4031 state = self.rightSplitter.saveState() |
|
4032 self.profiles[self.currentProfile][2][4] = state |
|
4033 state = self.rightSidebar.saveState() |
|
4034 self.profiles[self.currentProfile][2][5] = state |
|
4035 # step 2: save the visibility of the windows of the active profile |
|
4036 if self.__layoutType == "Toolboxes": |
|
4037 self.profiles[self.currentProfile][1][0] = \ |
|
4038 self.lToolboxDock.isVisible() |
|
4039 self.profiles[self.currentProfile][1][1] = \ |
|
4040 self.hToolboxDock.isVisible() |
|
4041 self.profiles[self.currentProfile][1][2] = \ |
|
4042 self.rToolboxDock.isVisible() |
|
4043 elif self.__layoutType == "Sidebars": |
|
4044 self.profiles[self.currentProfile][1][0] = \ |
|
4045 self.leftSidebar.isVisible() |
|
4046 self.profiles[self.currentProfile][1][1] = \ |
|
4047 self.bottomSidebar.isVisible() |
|
4048 self.profiles[self.currentProfile][1][2] = \ |
|
4049 self.rightSidebar.isVisible() |
|
4050 Preferences.setUI("ViewProfiles2", self.profiles) |
|
4051 |
|
4052 def __activateViewProfile(self, name, save=True): |
|
4053 """ |
|
4054 Private slot to activate a view profile. |
|
4055 |
|
4056 @param name name of the profile to be activated (string) |
|
4057 @param save flag indicating that the current profile should |
|
4058 be saved (boolean) |
|
4059 """ |
|
4060 if self.currentProfile != name or not save: |
|
4061 # step 1: save the active profile |
|
4062 self.__saveCurrentViewProfile(save) |
|
4063 |
|
4064 # step 2: set the window geometries of the new profile |
|
4065 if self.__layoutType in ["Toolboxes", "Sidebars"]: |
|
4066 state = self.profiles[name][0] |
|
4067 if not state.isEmpty(): |
|
4068 self.restoreState(state) |
|
4069 if self.__layoutType == "Sidebars": |
|
4070 state = self.profiles[name][2][0] |
|
4071 if not state.isEmpty(): |
|
4072 self.leftSplitter.restoreState(state) |
|
4073 state = self.profiles[name][2][1] |
|
4074 if not state.isEmpty(): |
|
4075 self.verticalSplitter.restoreState(state) |
|
4076 state = self.profiles[name][2][2] |
|
4077 if not state.isEmpty(): |
|
4078 self.leftSidebar.restoreState(state) |
|
4079 state = self.profiles[name][2][3] |
|
4080 if not state.isEmpty(): |
|
4081 self.bottomSidebar.restoreState(state) |
|
4082 state = self.profiles[name][2][4] |
|
4083 if not state.isEmpty(): |
|
4084 self.rightSplitter.restoreState(state) |
|
4085 state = self.profiles[name][2][5] |
|
4086 if not state.isEmpty(): |
|
4087 self.rightSidebar.restoreState(state) |
|
4088 self.__configureDockareaCornerUsage() |
|
4089 |
|
4090 # step 3: activate the windows of the new profile |
|
4091 if self.__layoutType == "Toolboxes": |
|
4092 self.lToolboxDock.setVisible(self.profiles[name][1][0]) |
|
4093 self.hToolboxDock.setVisible(self.profiles[name][1][1]) |
|
4094 self.rToolboxDock.setVisible(self.profiles[name][1][2]) |
|
4095 elif self.__layoutType == "Sidebars": |
|
4096 self.leftSidebar.setVisible(self.profiles[name][1][0]) |
|
4097 self.bottomSidebar.setVisible(self.profiles[name][1][1]) |
|
4098 self.rightSidebar.setVisible(self.profiles[name][1][2]) |
|
4099 |
|
4100 # step 4: remember the new profile |
|
4101 self.currentProfile = name |
|
4102 |
|
4103 # step 5: make sure that cursor of the shell is visible |
|
4104 self.shell.ensureCursorVisible() |
|
4105 |
|
4106 # step 6: make sure, that the toolbars and window menu are |
|
4107 # shown correctly |
|
4108 if self.__menus["toolbars"].isTearOffMenuVisible(): |
|
4109 self.__showToolbarsMenu() |
|
4110 if self.__menus["window"].isTearOffMenuVisible(): |
|
4111 self.__showWindowMenu() |
|
4112 |
|
4113 def __debuggingStarted(self): |
|
4114 """ |
|
4115 Private slot to handle the start of a debugging session. |
|
4116 """ |
|
4117 self.setDebugProfile() |
|
4118 if self.__layoutType == "Toolboxes": |
|
4119 self.__currentRightWidget = self.rToolbox.currentWidget() |
|
4120 self.rToolbox.setCurrentWidget(self.debugViewer) |
|
4121 self.__currentBottomWidget = self.hToolbox.currentWidget() |
|
4122 self.hToolbox.setCurrentWidget(self.shellAssembly) |
|
4123 elif self.__layoutType == "Sidebars": |
|
4124 self.__currentRightWidget = self.rightSidebar.currentWidget() |
|
4125 self.rightSidebar.setCurrentWidget(self.debugViewer) |
|
4126 self.__currentBottomWidget = self.bottomSidebar.currentWidget() |
|
4127 self.bottomSidebar.setCurrentWidget(self.shellAssembly) |
|
4128 |
|
4129 def __debuggingDone(self): |
|
4130 """ |
|
4131 Private slot to handle the end of a debugging session. |
|
4132 """ |
|
4133 self.__setEditProfile() |
|
4134 if self.__layoutType == "Toolboxes": |
|
4135 if self.__currentRightWidget: |
|
4136 self.rToolbox.setCurrentWidget(self.__currentRightWidget) |
|
4137 if self.__currentBottomWidget: |
|
4138 self.hToolbox.setCurrentWidget(self.__currentBottomWidget) |
|
4139 elif self.__layoutType == "Sidebars": |
|
4140 if self.__currentRightWidget: |
|
4141 self.rightSidebar.setCurrentWidget(self.__currentRightWidget) |
|
4142 if self.__currentBottomWidget: |
|
4143 self.bottomSidebar.setCurrentWidget(self.__currentBottomWidget) |
|
4144 self.__currentRightWidget = None |
|
4145 self.__currentBottomWidget = None |
|
4146 self.__activateViewmanager() |
|
4147 |
|
4148 @pyqtSlot() |
|
4149 def __setEditProfile(self, save=True): |
|
4150 """ |
|
4151 Private slot to activate the edit view profile. |
|
4152 |
|
4153 @param save flag indicating that the current profile should |
|
4154 be saved (boolean) |
|
4155 """ |
|
4156 self.__activateViewProfile("edit", save) |
|
4157 self.setEditProfileAct.setChecked(True) |
|
4158 |
|
4159 @pyqtSlot() |
|
4160 def setDebugProfile(self, save=True): |
|
4161 """ |
|
4162 Public slot to activate the debug view profile. |
|
4163 |
|
4164 @param save flag indicating that the current profile should |
|
4165 be saved (boolean) |
|
4166 """ |
|
4167 self.viewmanager.searchWidget().hide() |
|
4168 self.viewmanager.replaceWidget().hide() |
|
4169 self.__activateViewProfile("debug", save) |
|
4170 self.setDebugProfileAct.setChecked(True) |
|
4171 |
|
4172 def getViewProfile(self): |
|
4173 """ |
|
4174 Public method to get the current view profile. |
|
4175 |
|
4176 @return the name of the current view profile (string) |
|
4177 """ |
|
4178 return self.currentProfile |
|
4179 |
|
4180 def getLayoutType(self): |
|
4181 """ |
|
4182 Public method to get the current layout type. |
|
4183 |
|
4184 @return current layout type |
|
4185 @rtype str |
|
4186 """ |
|
4187 return self.__layoutType |
|
4188 |
|
4189 def __activateProjectBrowser(self): |
|
4190 """ |
|
4191 Private slot to handle the activation of the project browser. |
|
4192 """ |
|
4193 if self.__layoutType == "Toolboxes": |
|
4194 self.lToolboxDock.show() |
|
4195 self.lToolbox.setCurrentWidget(self.projectBrowser) |
|
4196 elif self.__layoutType == "Sidebars": |
|
4197 self.leftSidebar.show() |
|
4198 self.leftSidebar.setCurrentWidget(self.projectBrowser) |
|
4199 else: |
|
4200 self.projectBrowser.show() |
|
4201 self.projectBrowser.currentWidget().setFocus( |
|
4202 Qt.ActiveWindowFocusReason) |
|
4203 |
|
4204 def __activateMultiProjectBrowser(self): |
|
4205 """ |
|
4206 Private slot to handle the activation of the project browser. |
|
4207 """ |
|
4208 if self.__layoutType == "Toolboxes": |
|
4209 self.lToolboxDock.show() |
|
4210 self.lToolbox.setCurrentWidget(self.multiProjectBrowser) |
|
4211 elif self.__layoutType == "Sidebars": |
|
4212 self.leftSidebar.show() |
|
4213 self.leftSidebar.setCurrentWidget(self.multiProjectBrowser) |
|
4214 else: |
|
4215 self.multiProjectBrowser.show() |
|
4216 self.multiProjectBrowser.setFocus(Qt.ActiveWindowFocusReason) |
|
4217 |
|
4218 def activateDebugViewer(self): |
|
4219 """ |
|
4220 Public slot to handle the activation of the debug viewer. |
|
4221 """ |
|
4222 if self.__layoutType == "Toolboxes": |
|
4223 self.rToolboxDock.show() |
|
4224 self.rToolbox.setCurrentWidget(self.debugViewer) |
|
4225 elif self.__layoutType == "Sidebars": |
|
4226 self.rightSidebar.show() |
|
4227 self.rightSidebar.setCurrentWidget(self.debugViewer) |
|
4228 else: |
|
4229 self.debugViewer.show() |
|
4230 self.debugViewer.currentWidget().setFocus(Qt.ActiveWindowFocusReason) |
|
4231 |
|
4232 def __activateShell(self): |
|
4233 """ |
|
4234 Private slot to handle the activation of the Shell window. |
|
4235 """ |
|
4236 if self.__layoutType == "Toolboxes": |
|
4237 self.hToolboxDock.show() |
|
4238 self.hToolbox.setCurrentWidget(self.shellAssembly) |
|
4239 elif self.__layoutType == "Sidebars": |
|
4240 self.bottomSidebar.show() |
|
4241 self.bottomSidebar.setCurrentWidget(self.shellAssembly) |
|
4242 else: |
|
4243 self.shell.show() |
|
4244 self.shell.setFocus(Qt.ActiveWindowFocusReason) |
|
4245 |
|
4246 def __activateLogViewer(self): |
|
4247 """ |
|
4248 Private slot to handle the activation of the Log Viewer. |
|
4249 """ |
|
4250 if self.__layoutType == "Toolboxes": |
|
4251 self.hToolboxDock.show() |
|
4252 self.hToolbox.setCurrentWidget(self.logViewer) |
|
4253 elif self.__layoutType == "Sidebars": |
|
4254 self.bottomSidebar.show() |
|
4255 self.bottomSidebar.setCurrentWidget(self.logViewer) |
|
4256 else: |
|
4257 self.logViewer.show() |
|
4258 self.logViewer.setFocus(Qt.ActiveWindowFocusReason) |
|
4259 |
|
4260 def __activateTaskViewer(self): |
|
4261 """ |
|
4262 Private slot to handle the activation of the Task Viewer. |
|
4263 """ |
|
4264 if self.__layoutType == "Toolboxes": |
|
4265 self.hToolboxDock.show() |
|
4266 self.hToolbox.setCurrentWidget(self.taskViewer) |
|
4267 elif self.__layoutType == "Sidebars": |
|
4268 self.bottomSidebar.show() |
|
4269 self.bottomSidebar.setCurrentWidget(self.taskViewer) |
|
4270 else: |
|
4271 self.taskViewer.show() |
|
4272 self.taskViewer.setFocus(Qt.ActiveWindowFocusReason) |
|
4273 |
|
4274 def __activateTemplateViewer(self): |
|
4275 """ |
|
4276 Private slot to handle the activation of the Template Viewer. |
|
4277 """ |
|
4278 if self.templateViewer is not None: |
|
4279 if self.__layoutType == "Toolboxes": |
|
4280 self.lToolboxDock.show() |
|
4281 self.lToolbox.setCurrentWidget(self.templateViewer) |
|
4282 elif self.__layoutType == "Sidebars": |
|
4283 self.leftSidebar.show() |
|
4284 self.leftSidebar.setCurrentWidget(self.templateViewer) |
|
4285 else: |
|
4286 self.templateViewer.show() |
|
4287 self.templateViewer.setFocus(Qt.ActiveWindowFocusReason) |
|
4288 |
|
4289 def __activateBrowser(self): |
|
4290 """ |
|
4291 Private slot to handle the activation of the file browser. |
|
4292 """ |
|
4293 if self.browser is not None: |
|
4294 if self.__layoutType == "Toolboxes": |
|
4295 self.lToolboxDock.show() |
|
4296 self.lToolbox.setCurrentWidget(self.browser) |
|
4297 elif self.__layoutType == "Sidebars": |
|
4298 self.leftSidebar.show() |
|
4299 self.leftSidebar.setCurrentWidget(self.browser) |
|
4300 else: |
|
4301 self.browser.show() |
|
4302 self.browser.setFocus(Qt.ActiveWindowFocusReason) |
|
4303 |
|
4304 def __toggleLeftToolbox(self): |
|
4305 """ |
|
4306 Private slot to handle the toggle of the Left Toolbox window. |
|
4307 """ |
|
4308 hasFocus = self.lToolbox.currentWidget().hasFocus() |
|
4309 shown = self.__toggleWindow(self.lToolboxDock) |
|
4310 if shown: |
|
4311 self.lToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) |
|
4312 else: |
|
4313 if hasFocus: |
|
4314 self.__activateViewmanager() |
|
4315 |
|
4316 def __toggleRightToolbox(self): |
|
4317 """ |
|
4318 Private slot to handle the toggle of the Right Toolbox window. |
|
4319 """ |
|
4320 hasFocus = self.rToolbox.currentWidget().hasFocus() |
|
4321 shown = self.__toggleWindow(self.rToolboxDock) |
|
4322 if shown: |
|
4323 self.rToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) |
|
4324 else: |
|
4325 if hasFocus: |
|
4326 self.__activateViewmanager() |
|
4327 |
|
4328 def __toggleHorizontalToolbox(self): |
|
4329 """ |
|
4330 Private slot to handle the toggle of the Horizontal Toolbox window. |
|
4331 """ |
|
4332 hasFocus = self.hToolbox.currentWidget().hasFocus() |
|
4333 shown = self.__toggleWindow(self.hToolboxDock) |
|
4334 if shown: |
|
4335 self.hToolbox.currentWidget().setFocus(Qt.ActiveWindowFocusReason) |
|
4336 else: |
|
4337 if hasFocus: |
|
4338 self.__activateViewmanager() |
|
4339 |
|
4340 def __toggleLeftSidebar(self): |
|
4341 """ |
|
4342 Private slot to handle the toggle of the left sidebar window. |
|
4343 """ |
|
4344 hasFocus = self.leftSidebar.currentWidget().hasFocus() |
|
4345 shown = self.__toggleWindow(self.leftSidebar) |
|
4346 if shown: |
|
4347 self.leftSidebar.currentWidget().setFocus( |
|
4348 Qt.ActiveWindowFocusReason) |
|
4349 else: |
|
4350 if hasFocus: |
|
4351 self.__activateViewmanager() |
|
4352 |
|
4353 def __toggleRightSidebar(self): |
|
4354 """ |
|
4355 Private slot to handle the toggle of the right sidebar window. |
|
4356 """ |
|
4357 hasFocus = self.rightSidebar.currentWidget().hasFocus() |
|
4358 shown = self.__toggleWindow(self.rightSidebar) |
|
4359 if shown: |
|
4360 self.rightSidebar.currentWidget().setFocus( |
|
4361 Qt.ActiveWindowFocusReason) |
|
4362 else: |
|
4363 if hasFocus: |
|
4364 self.__activateViewmanager() |
|
4365 |
|
4366 def __toggleBottomSidebar(self): |
|
4367 """ |
|
4368 Private slot to handle the toggle of the bottom sidebar window. |
|
4369 """ |
|
4370 hasFocus = self.bottomSidebar.currentWidget().hasFocus() |
|
4371 shown = self.__toggleWindow(self.bottomSidebar) |
|
4372 if shown: |
|
4373 self.bottomSidebar.currentWidget().setFocus( |
|
4374 Qt.ActiveWindowFocusReason) |
|
4375 else: |
|
4376 if hasFocus: |
|
4377 self.__activateViewmanager() |
|
4378 |
|
4379 def activateCooperationViewer(self): |
|
4380 """ |
|
4381 Public slot to handle the activation of the cooperation window. |
|
4382 """ |
|
4383 if self.cooperation is not None: |
|
4384 if self.__layoutType == "Toolboxes": |
|
4385 self.rToolboxDock.show() |
|
4386 self.rToolbox.setCurrentWidget(self.cooperation) |
|
4387 elif self.__layoutType == "Sidebars": |
|
4388 self.rightSidebar.show() |
|
4389 self.rightSidebar.setCurrentWidget(self.cooperation) |
|
4390 else: |
|
4391 self.cooperation.show() |
|
4392 self.cooperation.setFocus(Qt.ActiveWindowFocusReason) |
|
4393 |
|
4394 def __activateIRC(self): |
|
4395 """ |
|
4396 Private slot to handle the activation of the IRC window. |
|
4397 """ |
|
4398 if self.irc is not None: |
|
4399 if self.__layoutType == "Toolboxes": |
|
4400 self.rToolboxDock.show() |
|
4401 self.rToolbox.setCurrentWidget(self.irc) |
|
4402 elif self.__layoutType == "Sidebars": |
|
4403 self.rightSidebar.show() |
|
4404 self.rightSidebar.setCurrentWidget(self.irc) |
|
4405 else: |
|
4406 self.irc.show() |
|
4407 self.irc.setFocus(Qt.ActiveWindowFocusReason) |
|
4408 |
|
4409 def __activateSymbolsViewer(self): |
|
4410 """ |
|
4411 Private slot to handle the activation of the Symbols Viewer. |
|
4412 """ |
|
4413 if self.symbolsViewer is not None: |
|
4414 if self.__layoutType == "Toolboxes": |
|
4415 self.lToolboxDock.show() |
|
4416 self.lToolbox.setCurrentWidget(self.symbolsViewer) |
|
4417 elif self.__layoutType == "Sidebars": |
|
4418 self.leftSidebar.show() |
|
4419 self.leftSidebar.setCurrentWidget(self.symbolsViewer) |
|
4420 else: |
|
4421 self.symbolsViewer.show() |
|
4422 self.symbolsViewer.setFocus(Qt.ActiveWindowFocusReason) |
|
4423 |
|
4424 def __activateNumbersViewer(self): |
|
4425 """ |
|
4426 Private slot to handle the activation of the Numbers Viewer. |
|
4427 """ |
|
4428 if self.numbersViewer is not None: |
|
4429 if self.__layoutType == "Toolboxes": |
|
4430 self.hToolboxDock.show() |
|
4431 self.hToolbox.setCurrentWidget(self.numbersViewer) |
|
4432 elif self.__layoutType == "Sidebars": |
|
4433 self.bottomSidebar.show() |
|
4434 self.bottomSidebar.setCurrentWidget(self.numbersViewer) |
|
4435 else: |
|
4436 self.numbersViewer.show() |
|
4437 self.numbersViewer.setFocus(Qt.ActiveWindowFocusReason) |
|
4438 |
|
4439 def __activateViewmanager(self): |
|
4440 """ |
|
4441 Private slot to handle the activation of the current editor. |
|
4442 """ |
|
4443 aw = self.viewmanager.activeWindow() |
|
4444 if aw is not None: |
|
4445 aw.setFocus(Qt.ActiveWindowFocusReason) |
|
4446 |
|
4447 def activateCodeDocumentationViewer(self, switchFocus=True): |
|
4448 """ |
|
4449 Public slot to handle the activation of the Code Documentation Viewer. |
|
4450 |
|
4451 @param switchFocus flag indicating to transfer the input focus |
|
4452 @type bool |
|
4453 """ |
|
4454 if self.codeDocumentationViewer is not None: |
|
4455 if self.__layoutType == "Toolboxes": |
|
4456 self.rToolboxDock.show() |
|
4457 self.rToolbox.setCurrentWidget(self.codeDocumentationViewer) |
|
4458 elif self.__layoutType == "Sidebars": |
|
4459 self.rightSidebar.show() |
|
4460 self.rightSidebar.setCurrentWidget( |
|
4461 self.codeDocumentationViewer) |
|
4462 else: |
|
4463 self.codeDocumentationViewer.show() |
|
4464 if switchFocus: |
|
4465 self.codeDocumentationViewer.setFocus( |
|
4466 Qt.ActiveWindowFocusReason) |
|
4467 |
|
4468 def __activatePipWidget(self): |
|
4469 """ |
|
4470 Private slot to handle the activation of the PyPI manager widget. |
|
4471 """ |
|
4472 if self.pipWidget is not None: |
|
4473 if self.__layoutType == "Toolboxes": |
|
4474 self.rToolboxDock.show() |
|
4475 self.rToolbox.setCurrentWidget(self.pipWidget) |
|
4476 elif self.__layoutType == "Sidebars": |
|
4477 self.rightSidebar.show() |
|
4478 self.rightSidebar.setCurrentWidget(self.pipWidget) |
|
4479 else: |
|
4480 self.pipWidget.show() |
|
4481 self.pipWidget.setFocus(Qt.ActiveWindowFocusReason) |
|
4482 |
|
4483 def __activateCondaWidget(self): |
|
4484 """ |
|
4485 Private slot to handle the activation of the Conda manager widget. |
|
4486 """ |
|
4487 if self.condaWidget is not None: |
|
4488 if self.__layoutType == "Toolboxes": |
|
4489 self.rToolboxDock.show() |
|
4490 self.rToolbox.setCurrentWidget(self.condaWidget) |
|
4491 elif self.__layoutType == "Sidebars": |
|
4492 self.rightSidebar.show() |
|
4493 self.rightSidebar.setCurrentWidget(self.condaWidget) |
|
4494 else: |
|
4495 self.condaWidget.show() |
|
4496 self.condaWidget.setFocus(Qt.ActiveWindowFocusReason) |
|
4497 |
|
4498 def __toggleWindow(self, w): |
|
4499 """ |
|
4500 Private method to toggle a workspace editor window. |
|
4501 |
|
4502 @param w reference to the workspace editor window |
|
4503 @return flag indicating, if the window was shown (boolean) |
|
4504 """ |
|
4505 if w.isHidden(): |
|
4506 w.show() |
|
4507 return True |
|
4508 else: |
|
4509 w.hide() |
|
4510 return False |
|
4511 |
|
4512 def __toolsConfiguration(self): |
|
4513 """ |
|
4514 Private slot to handle the tools configuration menu entry. |
|
4515 """ |
|
4516 from Preferences.ToolConfigurationDialog import ToolConfigurationDialog |
|
4517 dlg = ToolConfigurationDialog( |
|
4518 self.toolGroups[self.currentToolGroup][1], self) |
|
4519 if dlg.exec_() == QDialog.Accepted: |
|
4520 self.toolGroups[self.currentToolGroup][1] = dlg.getToollist() |
|
4521 self.__updateExternalToolsActions() |
|
4522 |
|
4523 def __toolGroupsConfiguration(self): |
|
4524 """ |
|
4525 Private slot to handle the tool groups configuration menu entry. |
|
4526 """ |
|
4527 from Preferences.ToolGroupConfigurationDialog import \ |
|
4528 ToolGroupConfigurationDialog |
|
4529 dlg = ToolGroupConfigurationDialog( |
|
4530 self.toolGroups, self.currentToolGroup, self) |
|
4531 if dlg.exec_() == QDialog.Accepted: |
|
4532 self.toolGroups, self.currentToolGroup = dlg.getToolGroups() |
|
4533 |
|
4534 def __createUnitTestDialog(self): |
|
4535 """ |
|
4536 Private slot to generate the unit test dialog on demand. |
|
4537 """ |
|
4538 if self.unittestDialog is None: |
|
4539 from PyUnit.UnittestDialog import UnittestDialog |
|
4540 self.unittestDialog = UnittestDialog( |
|
4541 None, self.debuggerUI.debugServer, self) |
|
4542 self.unittestDialog.unittestFile.connect( |
|
4543 self.viewmanager.setFileLine) |
|
4544 self.unittestDialog.unittestStopped.connect(self.__unittestStopped) |
|
4545 |
|
4546 def __unittestStopped(self): |
|
4547 """ |
|
4548 Private slot to handle the end of a unit test run. |
|
4549 """ |
|
4550 self.utRerunFailedAct.setEnabled(self.unittestDialog.hasFailedTests()) |
|
4551 self.utRestartAct.setEnabled(True) |
|
4552 |
|
4553 def __unittest(self): |
|
4554 """ |
|
4555 Private slot for displaying the unittest dialog. |
|
4556 """ |
|
4557 self.__createUnitTestDialog() |
|
4558 self.unittestDialog.show() |
|
4559 self.unittestDialog.raise_() |
|
4560 |
|
4561 @pyqtSlot() |
|
4562 @pyqtSlot(str) |
|
4563 def __unittestScript(self, prog=None): |
|
4564 """ |
|
4565 Private slot for displaying the unittest dialog and run the current |
|
4566 script. |
|
4567 |
|
4568 @param prog the python program to be opened |
|
4569 """ |
|
4570 if prog is None: |
|
4571 aw = self.viewmanager.activeWindow() |
|
4572 fn = aw.getFileName() |
|
4573 tfn = Utilities.getTestFileName(fn) |
|
4574 if os.path.exists(tfn): |
|
4575 prog = tfn |
|
4576 else: |
|
4577 prog = fn |
|
4578 |
|
4579 self.__unittest() |
|
4580 self.unittestDialog.setProjectMode(False) |
|
4581 self.unittestDialog.insertProg(prog) |
|
4582 self.utRestartAct.setEnabled(False) |
|
4583 self.utRerunFailedAct.setEnabled(False) |
|
4584 |
|
4585 def __unittestProject(self): |
|
4586 """ |
|
4587 Private slot for displaying the unittest dialog and run the current |
|
4588 project. |
|
4589 """ |
|
4590 fn = self.project.getMainScript(True) |
|
4591 if fn: |
|
4592 tfn = Utilities.getTestFileName(fn) |
|
4593 if os.path.exists(tfn): |
|
4594 prog = tfn |
|
4595 else: |
|
4596 prog = fn |
|
4597 else: |
|
4598 E5MessageBox.critical( |
|
4599 self, |
|
4600 self.tr("Unittest Project"), |
|
4601 self.tr( |
|
4602 "There is no main script defined for the" |
|
4603 " current project. Aborting")) |
|
4604 return |
|
4605 |
|
4606 self.__unittest() |
|
4607 self.unittestDialog.setProjectMode(True) |
|
4608 self.unittestDialog.insertProg(prog) |
|
4609 self.utRestartAct.setEnabled(False) |
|
4610 self.utRerunFailedAct.setEnabled(False) |
|
4611 |
|
4612 def __unittestRestart(self): |
|
4613 """ |
|
4614 Private slot to display the unittest dialog and rerun the last |
|
4615 unit test. |
|
4616 """ |
|
4617 self.__unittest() |
|
4618 self.unittestDialog.startTests() |
|
4619 |
|
4620 def __unittestRerunFailed(self): |
|
4621 """ |
|
4622 Private slot to display the unittest dialog and rerun all failed tests |
|
4623 of the last run. |
|
4624 """ |
|
4625 self.__unittest() |
|
4626 self.unittestDialog.startTests(failedOnly=True) |
|
4627 |
|
4628 def __designer(self, fn=None, version=0): |
|
4629 """ |
|
4630 Private slot to start the Qt-Designer executable. |
|
4631 |
|
4632 @param fn filename of the form to be opened |
|
4633 @type str |
|
4634 @param version indication for the requested version (4 = Qt 4/5) |
|
4635 @type int |
|
4636 """ |
|
4637 if fn is not None and version == 0: |
|
4638 # determine version from file, if not specified |
|
4639 try: |
|
4640 f = open(fn, "r", encoding="utf-8") |
|
4641 found = False |
|
4642 while not found: |
|
4643 uiLine = f.readline() |
|
4644 found = uiLine.lower().startswith("<ui ") |
|
4645 f.close() |
|
4646 if uiLine.lower().find("version") == -1: |
|
4647 # it is an old version 3 UI file |
|
4648 version = 3 |
|
4649 else: |
|
4650 if uiLine.split('"')[1].startswith("4."): |
|
4651 version = 4 |
|
4652 else: |
|
4653 version = 3 |
|
4654 except IOError: |
|
4655 pass |
|
4656 |
|
4657 if version == 3: |
|
4658 E5MessageBox.information( |
|
4659 self, |
|
4660 self.tr("Qt 3 support"), |
|
4661 self.tr("""Qt v.3 is not supported by eric6.""")) |
|
4662 return |
|
4663 |
|
4664 args = [] |
|
4665 if fn is not None: |
|
4666 try: |
|
4667 if os.path.isfile(fn) and os.path.getsize(fn): |
|
4668 args.append(fn) |
|
4669 else: |
|
4670 E5MessageBox.critical( |
|
4671 self, |
|
4672 self.tr('Problem'), |
|
4673 self.tr( |
|
4674 '<p>The file <b>{0}</b> does not exist or' |
|
4675 ' is zero length.</p>') |
|
4676 .format(fn)) |
|
4677 return |
|
4678 except EnvironmentError: |
|
4679 E5MessageBox.critical( |
|
4680 self, |
|
4681 self.tr('Problem'), |
|
4682 self.tr( |
|
4683 '<p>The file <b>{0}</b> does not exist or' |
|
4684 ' is zero length.</p>') |
|
4685 .format(fn)) |
|
4686 return |
|
4687 |
|
4688 if Utilities.isMacPlatform(): |
|
4689 designer, args = Utilities.prepareQtMacBundle( |
|
4690 "designer", version, args) |
|
4691 else: |
|
4692 if version == 4: |
|
4693 designer = os.path.join( |
|
4694 Utilities.getQtBinariesPath(), |
|
4695 Utilities.generateQtToolName("designer")) |
|
4696 if Utilities.isWindowsPlatform(): |
|
4697 designer += '.exe' |
|
4698 |
|
4699 proc = QProcess() |
|
4700 if not proc.startDetached(designer, args): |
|
4701 E5MessageBox.critical( |
|
4702 self, |
|
4703 self.tr('Process Generation Error'), |
|
4704 self.tr( |
|
4705 '<p>Could not start Qt-Designer.<br>' |
|
4706 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4707 ).format(designer)) |
|
4708 |
|
4709 def __designer4(self): |
|
4710 """ |
|
4711 Private slot to start the Qt-Designer 4/5 executable. |
|
4712 """ |
|
4713 self.__designer(version=4) |
|
4714 |
|
4715 def __linguist(self, fn=None, version=0): |
|
4716 """ |
|
4717 Private slot to start the Qt-Linguist executable. |
|
4718 |
|
4719 @param fn filename of the translation file to be opened |
|
4720 @type str |
|
4721 @param version indication for the requested version (4 = Qt 4/5) |
|
4722 @type int |
|
4723 """ |
|
4724 if version < 4: |
|
4725 E5MessageBox.information( |
|
4726 self, |
|
4727 self.tr("Qt 3 support"), |
|
4728 self.tr("""Qt v.3 is not supported by eric6.""")) |
|
4729 return |
|
4730 |
|
4731 args = [] |
|
4732 if fn is not None: |
|
4733 fn = fn.replace('.qm', '.ts') |
|
4734 try: |
|
4735 if os.path.isfile(fn) and os.path.getsize(fn) and \ |
|
4736 fn not in args: |
|
4737 args.append(fn) |
|
4738 else: |
|
4739 E5MessageBox.critical( |
|
4740 self, |
|
4741 self.tr('Problem'), |
|
4742 self.tr( |
|
4743 '<p>The file <b>{0}</b> does not exist or' |
|
4744 ' is zero length.</p>') |
|
4745 .format(fn)) |
|
4746 return |
|
4747 except EnvironmentError: |
|
4748 E5MessageBox.critical( |
|
4749 self, |
|
4750 self.tr('Problem'), |
|
4751 self.tr( |
|
4752 '<p>The file <b>{0}</b> does not exist or' |
|
4753 ' is zero length.</p>') |
|
4754 .format(fn)) |
|
4755 return |
|
4756 |
|
4757 if Utilities.isMacPlatform(): |
|
4758 linguist, args = Utilities.prepareQtMacBundle( |
|
4759 "linguist", version, args) |
|
4760 else: |
|
4761 if version == 4: |
|
4762 linguist = os.path.join( |
|
4763 Utilities.getQtBinariesPath(), |
|
4764 Utilities.generateQtToolName("linguist")) |
|
4765 if Utilities.isWindowsPlatform(): |
|
4766 linguist += '.exe' |
|
4767 |
|
4768 proc = QProcess() |
|
4769 if not proc.startDetached(linguist, args): |
|
4770 E5MessageBox.critical( |
|
4771 self, |
|
4772 self.tr('Process Generation Error'), |
|
4773 self.tr( |
|
4774 '<p>Could not start Qt-Linguist.<br>' |
|
4775 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4776 ).format(linguist)) |
|
4777 |
|
4778 @pyqtSlot() |
|
4779 @pyqtSlot(str) |
|
4780 def __linguist4(self, fn=None): |
|
4781 """ |
|
4782 Private slot to start the Qt-Linguist 4/5 executable. |
|
4783 |
|
4784 @param fn filename of the translation file to be opened |
|
4785 """ |
|
4786 self.__linguist(fn, version=4) |
|
4787 |
|
4788 def __assistant(self, home=None, version=0): |
|
4789 """ |
|
4790 Private slot to start the Qt-Assistant executable. |
|
4791 |
|
4792 @param home full pathname of a file to display |
|
4793 @type str |
|
4794 @param version indication for the requested version (4 = Qt 4/5) |
|
4795 @type int |
|
4796 """ |
|
4797 if version < 4: |
|
4798 E5MessageBox.information( |
|
4799 self, |
|
4800 self.tr("Qt 3 support"), |
|
4801 self.tr("""Qt v.3 is not supported by eric6.""")) |
|
4802 return |
|
4803 |
|
4804 args = [] |
|
4805 if home: |
|
4806 if version == 4: |
|
4807 args.append('-showUrl') |
|
4808 args.append(home) |
|
4809 |
|
4810 if Utilities.isMacPlatform(): |
|
4811 assistant, args = Utilities.prepareQtMacBundle( |
|
4812 "assistant", version, args) |
|
4813 else: |
|
4814 if version == 4: |
|
4815 assistant = os.path.join( |
|
4816 Utilities.getQtBinariesPath(), |
|
4817 Utilities.generateQtToolName("assistant")) |
|
4818 if Utilities.isWindowsPlatform(): |
|
4819 assistant += '.exe' |
|
4820 |
|
4821 proc = QProcess() |
|
4822 if not proc.startDetached(assistant, args): |
|
4823 E5MessageBox.critical( |
|
4824 self, |
|
4825 self.tr('Process Generation Error'), |
|
4826 self.tr( |
|
4827 '<p>Could not start Qt-Assistant.<br>' |
|
4828 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4829 ).format(assistant)) |
|
4830 |
|
4831 def __assistant4(self): |
|
4832 """ |
|
4833 Private slot to start the Qt-Assistant 4/5 executable. |
|
4834 """ |
|
4835 self.__assistant(version=4) |
|
4836 |
|
4837 def __startWebBrowser(self): |
|
4838 """ |
|
4839 Private slot to start the eric6 web browser. |
|
4840 """ |
|
4841 self.launchHelpViewer("") |
|
4842 |
|
4843 def __customViewer(self, home=None): |
|
4844 """ |
|
4845 Private slot to start a custom viewer. |
|
4846 |
|
4847 @param home full pathname of a file to display (string) |
|
4848 """ |
|
4849 customViewer = Preferences.getHelp("CustomViewer") |
|
4850 if not customViewer: |
|
4851 E5MessageBox.information( |
|
4852 self, |
|
4853 self.tr("Help"), |
|
4854 self.tr( |
|
4855 """Currently no custom viewer is selected.""" |
|
4856 """ Please use the preferences dialog to specify one.""")) |
|
4857 return |
|
4858 |
|
4859 proc = QProcess() |
|
4860 args = [] |
|
4861 if home: |
|
4862 args.append(home) |
|
4863 |
|
4864 if not proc.startDetached(customViewer, args): |
|
4865 E5MessageBox.critical( |
|
4866 self, |
|
4867 self.tr('Process Generation Error'), |
|
4868 self.tr( |
|
4869 '<p>Could not start custom viewer.<br>' |
|
4870 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4871 ).format(customViewer)) |
|
4872 |
|
4873 def __chmViewer(self, home=None): |
|
4874 """ |
|
4875 Private slot to start the win help viewer to show *.chm files. |
|
4876 |
|
4877 @param home full pathname of a file to display (string) |
|
4878 """ |
|
4879 if home: |
|
4880 proc = QProcess() |
|
4881 args = [] |
|
4882 args.append(home) |
|
4883 |
|
4884 if not proc.startDetached("hh", args): |
|
4885 E5MessageBox.critical( |
|
4886 self, |
|
4887 self.tr('Process Generation Error'), |
|
4888 self.tr( |
|
4889 '<p>Could not start the help viewer.<br>' |
|
4890 'Ensure that it is available as <b>hh</b>.</p>' |
|
4891 )) |
|
4892 |
|
4893 @pyqtSlot() |
|
4894 @pyqtSlot(str) |
|
4895 def __UIPreviewer(self, fn=None): |
|
4896 """ |
|
4897 Private slot to start the UI Previewer executable. |
|
4898 |
|
4899 @param fn filename of the form to be previewed (string) |
|
4900 """ |
|
4901 proc = QProcess() |
|
4902 |
|
4903 viewer = os.path.join(getConfig("ericDir"), "eric6_uipreviewer.py") |
|
4904 |
|
4905 args = [] |
|
4906 args.append(viewer) |
|
4907 |
|
4908 if fn is not None: |
|
4909 try: |
|
4910 if os.path.isfile(fn) and os.path.getsize(fn): |
|
4911 args.append(fn) |
|
4912 else: |
|
4913 E5MessageBox.critical( |
|
4914 self, |
|
4915 self.tr('Problem'), |
|
4916 self.tr( |
|
4917 '<p>The file <b>{0}</b> does not exist or' |
|
4918 ' is zero length.</p>') |
|
4919 .format(fn)) |
|
4920 return |
|
4921 except EnvironmentError: |
|
4922 E5MessageBox.critical( |
|
4923 self, |
|
4924 self.tr('Problem'), |
|
4925 self.tr( |
|
4926 '<p>The file <b>{0}</b> does not exist or' |
|
4927 ' is zero length.</p>') |
|
4928 .format(fn)) |
|
4929 return |
|
4930 |
|
4931 if not os.path.isfile(viewer) or \ |
|
4932 not proc.startDetached(sys.executable, args): |
|
4933 E5MessageBox.critical( |
|
4934 self, |
|
4935 self.tr('Process Generation Error'), |
|
4936 self.tr( |
|
4937 '<p>Could not start UI Previewer.<br>' |
|
4938 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4939 ).format(viewer)) |
|
4940 |
|
4941 @pyqtSlot() |
|
4942 @pyqtSlot(str) |
|
4943 @pyqtSlot(str, bool) |
|
4944 def __TRPreviewer(self, fileNames=None, ignore=False): |
|
4945 """ |
|
4946 Private slot to start the Translation Previewer executable. |
|
4947 |
|
4948 @param fileNames filenames of forms and/or translations to be previewed |
|
4949 (list of strings) |
|
4950 @param ignore flag indicating non existing files should be ignored |
|
4951 (boolean) |
|
4952 """ |
|
4953 proc = QProcess() |
|
4954 |
|
4955 viewer = os.path.join(getConfig("ericDir"), "eric6_trpreviewer.py") |
|
4956 |
|
4957 args = [] |
|
4958 args.append(viewer) |
|
4959 |
|
4960 if fileNames is not None: |
|
4961 for fn in fileNames: |
|
4962 try: |
|
4963 if os.path.isfile(fn) and os.path.getsize(fn): |
|
4964 args.append(fn) |
|
4965 else: |
|
4966 if not ignore: |
|
4967 E5MessageBox.critical( |
|
4968 self, |
|
4969 self.tr('Problem'), |
|
4970 self.tr( |
|
4971 '<p>The file <b>{0}</b> does not exist or' |
|
4972 ' is zero length.</p>') |
|
4973 .format(fn)) |
|
4974 return |
|
4975 except EnvironmentError: |
|
4976 if not ignore: |
|
4977 E5MessageBox.critical( |
|
4978 self, |
|
4979 self.tr('Problem'), |
|
4980 self.tr( |
|
4981 '<p>The file <b>{0}</b> does not exist or' |
|
4982 ' is zero length.</p>') |
|
4983 .format(fn)) |
|
4984 return |
|
4985 |
|
4986 if not os.path.isfile(viewer) or \ |
|
4987 not proc.startDetached(sys.executable, args): |
|
4988 E5MessageBox.critical( |
|
4989 self, |
|
4990 self.tr('Process Generation Error'), |
|
4991 self.tr( |
|
4992 '<p>Could not start Translation Previewer.<br>' |
|
4993 'Ensure that it is available as <b>{0}</b>.</p>' |
|
4994 ).format(viewer)) |
|
4995 |
|
4996 def __sqlBrowser(self): |
|
4997 """ |
|
4998 Private slot to start the SQL browser tool. |
|
4999 """ |
|
5000 proc = QProcess() |
|
5001 |
|
5002 browser = os.path.join(getConfig("ericDir"), "eric6_sqlbrowser.py") |
|
5003 |
|
5004 args = [] |
|
5005 args.append(browser) |
|
5006 |
|
5007 if not os.path.isfile(browser) or \ |
|
5008 not proc.startDetached(sys.executable, args): |
|
5009 E5MessageBox.critical( |
|
5010 self, |
|
5011 self.tr('Process Generation Error'), |
|
5012 self.tr( |
|
5013 '<p>Could not start SQL Browser.<br>' |
|
5014 'Ensure that it is available as <b>{0}</b>.</p>' |
|
5015 ).format(browser)) |
|
5016 |
|
5017 @pyqtSlot() |
|
5018 @pyqtSlot(str) |
|
5019 def __openHexEditor(self, fn=""): |
|
5020 """ |
|
5021 Private slot to open the hex editor window. |
|
5022 |
|
5023 @param fn filename of the file to show (string) |
|
5024 """ |
|
5025 from HexEdit.HexEditMainWindow import HexEditMainWindow |
|
5026 dlg = HexEditMainWindow(fn, self, fromEric=True, project=self.project) |
|
5027 dlg.show() |
|
5028 |
|
5029 @pyqtSlot() |
|
5030 @pyqtSlot(str) |
|
5031 def __editPixmap(self, fn=""): |
|
5032 """ |
|
5033 Private slot to show a pixmap in a dialog. |
|
5034 |
|
5035 @param fn filename of the file to show (string) |
|
5036 """ |
|
5037 from IconEditor.IconEditorWindow import IconEditorWindow |
|
5038 dlg = IconEditorWindow(fn, self, fromEric=True, project=self.project) |
|
5039 dlg.show() |
|
5040 |
|
5041 @pyqtSlot() |
|
5042 @pyqtSlot(str) |
|
5043 def __showPixmap(self, fn): |
|
5044 """ |
|
5045 Private slot to show a pixmap in a dialog. |
|
5046 |
|
5047 @param fn filename of the file to show (string) |
|
5048 """ |
|
5049 from Graphics.PixmapDiagram import PixmapDiagram |
|
5050 dlg = PixmapDiagram(fn, self) |
|
5051 if dlg.getStatus(): |
|
5052 dlg.show() |
|
5053 |
|
5054 @pyqtSlot() |
|
5055 @pyqtSlot(str) |
|
5056 def __showSvg(self, fn): |
|
5057 """ |
|
5058 Private slot to show a SVG file in a dialog. |
|
5059 |
|
5060 @param fn filename of the file to show (string) |
|
5061 """ |
|
5062 from Graphics.SvgDiagram import SvgDiagram |
|
5063 dlg = SvgDiagram(fn, self) |
|
5064 dlg.show() |
|
5065 |
|
5066 def __snapshot(self): |
|
5067 """ |
|
5068 Private slot to start the snapshot tool. |
|
5069 """ |
|
5070 proc = QProcess() |
|
5071 |
|
5072 snap = os.path.join(getConfig("ericDir"), "eric6_snap.py") |
|
5073 |
|
5074 args = [] |
|
5075 args.append(snap) |
|
5076 |
|
5077 if not os.path.isfile(snap) or \ |
|
5078 not proc.startDetached(sys.executable, args): |
|
5079 E5MessageBox.critical( |
|
5080 self, |
|
5081 self.tr('Process Generation Error'), |
|
5082 self.tr( |
|
5083 '<p>Could not start Snapshot tool.<br>' |
|
5084 'Ensure that it is available as <b>{0}</b>.</p>' |
|
5085 ).format(snap)) |
|
5086 |
|
5087 def __toolActionTriggered(self, act): |
|
5088 """ |
|
5089 Private slot called by external tools toolbar actions. |
|
5090 |
|
5091 @param act reference to the action that triggered the slot |
|
5092 @type QAction |
|
5093 """ |
|
5094 toolGroupName, toolMenuText = act.objectName().split('@@', 1) |
|
5095 for toolGroup in self.toolGroups: |
|
5096 if toolGroup[0] == toolGroupName: |
|
5097 for tool in toolGroup[1]: |
|
5098 if tool['menutext'] == toolMenuText: |
|
5099 self.__startToolProcess(tool) |
|
5100 return |
|
5101 |
|
5102 E5MessageBox.information( |
|
5103 self, |
|
5104 self.tr("External Tools"), |
|
5105 self.tr( |
|
5106 """No tool entry found for external tool '{0}' """ |
|
5107 """in tool group '{1}'.""") |
|
5108 .format(toolMenuText, toolGroupName)) |
|
5109 return |
|
5110 |
|
5111 E5MessageBox.information( |
|
5112 self, |
|
5113 self.tr("External Tools"), |
|
5114 self.tr("""No toolgroup entry '{0}' found.""") |
|
5115 .format(toolGroupName) |
|
5116 ) |
|
5117 |
|
5118 def __toolExecute(self, act): |
|
5119 """ |
|
5120 Private slot to execute a particular tool. |
|
5121 |
|
5122 @param act reference to the action that was triggered (QAction) |
|
5123 """ |
|
5124 if self.toolGroupsMenuTriggered: |
|
5125 # ignore actions triggered from the select tool group submenu |
|
5126 self.toolGroupsMenuTriggered = False |
|
5127 return |
|
5128 |
|
5129 if self.currentToolGroup < 0: |
|
5130 # it was an action not to be handled here |
|
5131 return |
|
5132 |
|
5133 idx = act.data() |
|
5134 if idx is not None and idx >= 0: |
|
5135 tool = self.toolGroups[self.currentToolGroup][1][idx] |
|
5136 self.__startToolProcess(tool) |
|
5137 |
|
5138 def __startToolProcess(self, tool): |
|
5139 """ |
|
5140 Private slot to start an external tool process. |
|
5141 |
|
5142 @param tool list of tool entries |
|
5143 """ |
|
5144 proc = QProcess() |
|
5145 procData = (None,) |
|
5146 program = tool['executable'] |
|
5147 args = [] |
|
5148 argv = Utilities.parseOptionString(tool['arguments']) |
|
5149 args.extend(argv) |
|
5150 t = self.tr("Starting process '{0} {1}'.\n")\ |
|
5151 .format(program, tool['arguments']) |
|
5152 self.appendToStdout(t) |
|
5153 |
|
5154 proc.finished.connect(self.__toolFinished) |
|
5155 if tool['redirect'] != 'no': |
|
5156 proc.readyReadStandardOutput.connect(self.__processToolStdout) |
|
5157 proc.readyReadStandardError.connect(self.__processToolStderr) |
|
5158 if tool['redirect'] in ["insert", "replaceSelection"]: |
|
5159 aw = self.viewmanager.activeWindow() |
|
5160 procData = (aw, tool['redirect'], []) |
|
5161 if aw is not None: |
|
5162 aw.beginUndoAction() |
|
5163 |
|
5164 proc.start(program, args) |
|
5165 if not proc.waitForStarted(): |
|
5166 E5MessageBox.critical( |
|
5167 self, |
|
5168 self.tr('Process Generation Error'), |
|
5169 self.tr( |
|
5170 '<p>Could not start the tool entry <b>{0}</b>.<br>' |
|
5171 'Ensure that it is available as <b>{1}</b>.</p>') |
|
5172 .format(tool['menutext'], tool['executable'])) |
|
5173 else: |
|
5174 self.toolProcs.append((program, proc, procData)) |
|
5175 if tool['redirect'] == 'no': |
|
5176 proc.closeReadChannel(QProcess.StandardOutput) |
|
5177 proc.closeReadChannel(QProcess.StandardError) |
|
5178 proc.closeWriteChannel() |
|
5179 |
|
5180 def __processToolStdout(self): |
|
5181 """ |
|
5182 Private slot to handle the readyReadStdout signal of a tool process. |
|
5183 """ |
|
5184 ioEncoding = Preferences.getSystem("IOEncoding") |
|
5185 |
|
5186 # loop through all running tool processes |
|
5187 for program, toolProc, toolProcData in self.toolProcs: |
|
5188 toolProc.setReadChannel(QProcess.StandardOutput) |
|
5189 |
|
5190 if toolProcData[0] is None or \ |
|
5191 toolProcData[1] not in ["insert", "replaceSelection"]: |
|
5192 # not connected to an editor or wrong mode |
|
5193 while toolProc.canReadLine(): |
|
5194 output = str(toolProc.readLine(), ioEncoding, 'replace') |
|
5195 s = "{0} - {1}".format(program, output) |
|
5196 self.appendToStdout(s) |
|
5197 else: |
|
5198 if toolProcData[1] == "insert": |
|
5199 text = str(toolProc.readAll(), ioEncoding, 'replace') |
|
5200 toolProcData[0].insert(text) |
|
5201 elif toolProcData[1] == "replaceSelection": |
|
5202 text = str(toolProc.readAll(), ioEncoding, 'replace') |
|
5203 toolProcData[2].append(text) |
|
5204 |
|
5205 def __processToolStderr(self): |
|
5206 """ |
|
5207 Private slot to handle the readyReadStderr signal of a tool process. |
|
5208 """ |
|
5209 ioEncoding = Preferences.getSystem("IOEncoding") |
|
5210 |
|
5211 # loop through all running tool processes |
|
5212 for program, toolProc, _toolProcData in self.toolProcs: |
|
5213 toolProc.setReadChannel(QProcess.StandardError) |
|
5214 |
|
5215 while toolProc.canReadLine(): |
|
5216 error = str(toolProc.readLine(), ioEncoding, 'replace') |
|
5217 s = "{0} - {1}".format(program, error) |
|
5218 self.appendToStderr(s) |
|
5219 |
|
5220 def __toolFinished(self, exitCode, exitStatus): |
|
5221 """ |
|
5222 Private slot to handle the finished signal of a tool process. |
|
5223 |
|
5224 @param exitCode exit code of the process (integer) |
|
5225 @param exitStatus exit status of the process (QProcess.ExitStatus) |
|
5226 """ |
|
5227 exitedProcs = [] |
|
5228 |
|
5229 # loop through all running tool processes |
|
5230 for program, toolProc, toolProcData in self.toolProcs: |
|
5231 if toolProc.state() == QProcess.NotRunning: |
|
5232 exitedProcs.append((program, toolProc, toolProcData)) |
|
5233 if toolProcData[0] is not None: |
|
5234 if toolProcData[1] == "replaceSelection": |
|
5235 text = ''.join(toolProcData[2]) |
|
5236 toolProcData[0].replace(text) |
|
5237 toolProcData[0].endUndoAction() |
|
5238 |
|
5239 # now delete the exited procs from the list of running processes |
|
5240 for proc in exitedProcs: |
|
5241 self.toolProcs.remove(proc) |
|
5242 t = self.tr("Process '{0}' has exited.\n").format(proc[0]) |
|
5243 self.appendToStdout(t) |
|
5244 |
|
5245 def __showPythonDoc(self): |
|
5246 """ |
|
5247 Private slot to show the Python 3 documentation. |
|
5248 """ |
|
5249 pythonDocDir = Preferences.getHelp("PythonDocDir") |
|
5250 if not pythonDocDir: |
|
5251 if Utilities.isWindowsPlatform(): |
|
5252 venvName = Preferences.getDebugger("Python3VirtualEnv") |
|
5253 interpreter = e5App().getObject("VirtualEnvManager")\ |
|
5254 .getVirtualenvInterpreter(venvName) |
|
5255 if interpreter: |
|
5256 default = os.path.join(os.path.dirname(interpreter), "doc") |
|
5257 else: |
|
5258 default = "" |
|
5259 pythonDocDir = \ |
|
5260 Utilities.getEnvironmentEntry("PYTHON3DOCDIR", default) |
|
5261 else: |
|
5262 pythonDocDir = Utilities.getEnvironmentEntry( |
|
5263 "PYTHON3DOCDIR", |
|
5264 '/usr/share/doc/packages/python3/html') |
|
5265 if not pythonDocDir.startswith(("http://", "https://", "qthelp://")): |
|
5266 if pythonDocDir.startswith("file://"): |
|
5267 pythonDocDir = pythonDocDir[7:] |
|
5268 if not os.path.splitext(pythonDocDir)[1]: |
|
5269 home = Utilities.normjoinpath(pythonDocDir, 'index.html') |
|
5270 |
|
5271 if Utilities.isWindowsPlatform() and not os.path.exists(home): |
|
5272 pyversion = sys.hexversion >> 16 |
|
5273 vers = "{0:d}{1:d}".format((pyversion >> 8) & 0xff, |
|
5274 pyversion & 0xff) |
|
5275 home = os.path.join( |
|
5276 pythonDocDir, "python{0}.chm".format(vers)) |
|
5277 else: |
|
5278 home = pythonDocDir |
|
5279 |
|
5280 if not os.path.exists(home): |
|
5281 E5MessageBox.warning( |
|
5282 self, |
|
5283 self.tr("Documentation Missing"), |
|
5284 self.tr("""<p>The documentation starting point""" |
|
5285 """ "<b>{0}</b>" could not be found.</p>""") |
|
5286 .format(home)) |
|
5287 return |
|
5288 |
|
5289 if not home.endswith(".chm"): |
|
5290 if Utilities.isWindowsPlatform(): |
|
5291 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5292 else: |
|
5293 home = "file://" + home |
|
5294 else: |
|
5295 home = pythonDocDir |
|
5296 |
|
5297 if home.endswith(".chm"): |
|
5298 self.__chmViewer(home) |
|
5299 else: |
|
5300 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5301 if hvType == 1: |
|
5302 self.launchHelpViewer(home) |
|
5303 elif hvType == 2: |
|
5304 if home.startswith("qthelp://"): |
|
5305 self.__assistant(home, version=4) |
|
5306 else: |
|
5307 self.__webBrowser(home) |
|
5308 elif hvType == 3: |
|
5309 self.__webBrowser(home) |
|
5310 else: |
|
5311 self.__customViewer(home) |
|
5312 |
|
5313 def __showPython2Doc(self): |
|
5314 """ |
|
5315 Private slot to show the Python 2 documentation. |
|
5316 """ |
|
5317 pythonDocDir = Preferences.getHelp("Python2DocDir") |
|
5318 if not pythonDocDir: |
|
5319 if Utilities.isWindowsPlatform(): |
|
5320 venvName = Preferences.getDebugger("Python2VirtualEnv") |
|
5321 interpreter = e5App().getObject("VirtualEnvManager")\ |
|
5322 .getVirtualenvInterpreter(venvName) |
|
5323 if interpreter: |
|
5324 default = os.path.join(os.path.dirname(interpreter), "doc") |
|
5325 else: |
|
5326 default = "" |
|
5327 pythonDocDir = \ |
|
5328 Utilities.getEnvironmentEntry("PYTHON2DOCDIR", default) |
|
5329 else: |
|
5330 pythonDocDir = Utilities.getEnvironmentEntry( |
|
5331 "PYTHON2DOCDIR", |
|
5332 '/usr/share/doc/packages/python/html') |
|
5333 if not pythonDocDir.startswith(("http://", "https://", "qthelp://")): |
|
5334 if pythonDocDir.startswith("file://"): |
|
5335 pythonDocDir = pythonDocDir[7:] |
|
5336 if not os.path.splitext(pythonDocDir)[1]: |
|
5337 home = Utilities.normjoinpath(pythonDocDir, 'index.html') |
|
5338 else: |
|
5339 home = pythonDocDir |
|
5340 |
|
5341 if not os.path.exists(home): |
|
5342 E5MessageBox.warning( |
|
5343 self, |
|
5344 self.tr("Documentation Missing"), |
|
5345 self.tr("""<p>The documentation starting point""" |
|
5346 """ "<b>{0}</b>" could not be found.</p>""") |
|
5347 .format(home)) |
|
5348 return |
|
5349 |
|
5350 if not home.endswith(".chm"): |
|
5351 if Utilities.isWindowsPlatform(): |
|
5352 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5353 else: |
|
5354 home = "file://" + home |
|
5355 else: |
|
5356 home = pythonDocDir |
|
5357 |
|
5358 if home.endswith(".chm"): |
|
5359 self.__chmViewer(home) |
|
5360 else: |
|
5361 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5362 if hvType == 1: |
|
5363 self.launchHelpViewer(home) |
|
5364 elif hvType == 2: |
|
5365 if home.startswith("qthelp://"): |
|
5366 self.__assistant(home, version=4) |
|
5367 else: |
|
5368 self.__webBrowser(home) |
|
5369 elif hvType == 3: |
|
5370 self.__webBrowser(home) |
|
5371 else: |
|
5372 self.__customViewer(home) |
|
5373 |
|
5374 def __showQt4Doc(self): |
|
5375 """ |
|
5376 Private slot to show the Qt4 documentation. |
|
5377 """ |
|
5378 self.__showQtDoc(4) |
|
5379 |
|
5380 def __showQt5Doc(self): |
|
5381 """ |
|
5382 Private slot to show the Qt5 documentation. |
|
5383 """ |
|
5384 self.__showQtDoc(5) |
|
5385 |
|
5386 def __showQtDoc(self, version): |
|
5387 """ |
|
5388 Private method to show the Qt documentation. |
|
5389 |
|
5390 @param version Qt version to show documentation for (integer) |
|
5391 """ |
|
5392 assert version in [4, 5] |
|
5393 if version == 4: |
|
5394 qtDocDir = Preferences.getQt4DocDir() |
|
5395 elif version == 5: |
|
5396 qtDocDir = Preferences.getQt5DocDir() |
|
5397 |
|
5398 if qtDocDir.startswith("qthelp://"): |
|
5399 if not os.path.splitext(qtDocDir)[1]: |
|
5400 home = qtDocDir + "/index.html" |
|
5401 else: |
|
5402 home = qtDocDir |
|
5403 elif qtDocDir.startswith(("http://", "https://")): |
|
5404 home = qtDocDir |
|
5405 else: |
|
5406 if qtDocDir.startswith("file://"): |
|
5407 qtDocDir = qtDocDir[7:] |
|
5408 if not os.path.splitext(qtDocDir)[1]: |
|
5409 home = Utilities.normjoinpath(qtDocDir, 'index.html') |
|
5410 else: |
|
5411 home = qtDocDir |
|
5412 |
|
5413 if not os.path.exists(home): |
|
5414 E5MessageBox.warning( |
|
5415 self, |
|
5416 self.tr("Documentation Missing"), |
|
5417 self.tr("""<p>The documentation starting point""" |
|
5418 """ "<b>{0}</b>" could not be found.</p>""") |
|
5419 .format(home)) |
|
5420 return |
|
5421 |
|
5422 if Utilities.isWindowsPlatform(): |
|
5423 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5424 else: |
|
5425 home = "file://" + home |
|
5426 |
|
5427 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5428 if hvType == 1: |
|
5429 self.launchHelpViewer(home) |
|
5430 elif hvType == 2: |
|
5431 if home.startswith("qthelp://"): |
|
5432 self.__assistant(home, version=4) |
|
5433 else: |
|
5434 self.__webBrowser(home) |
|
5435 elif hvType == 3: |
|
5436 self.__webBrowser(home) |
|
5437 else: |
|
5438 self.__customViewer(home) |
|
5439 |
|
5440 def __showPyQt4Doc(self): |
|
5441 """ |
|
5442 Private slot to show the PyQt4 documentation. |
|
5443 """ |
|
5444 pyqt4DocDir = Preferences.getHelp("PyQt4DocDir") |
|
5445 if not pyqt4DocDir: |
|
5446 pyqt4DocDir = Utilities.getEnvironmentEntry("PYQT4DOCDIR", None) |
|
5447 |
|
5448 if not pyqt4DocDir: |
|
5449 E5MessageBox.warning( |
|
5450 self, |
|
5451 self.tr("Documentation"), |
|
5452 self.tr("""<p>The PyQt4 documentation starting point""" |
|
5453 """ has not been configured.</p>""")) |
|
5454 return |
|
5455 |
|
5456 if not pyqt4DocDir.startswith(("http://", "https://", "qthelp://")): |
|
5457 home = "" |
|
5458 if pyqt4DocDir: |
|
5459 if pyqt4DocDir.startswith("file://"): |
|
5460 pyqt4DocDir = pyqt4DocDir[7:] |
|
5461 if not os.path.splitext(pyqt4DocDir)[1]: |
|
5462 possibleHomes = [ |
|
5463 Utilities.normjoinpath(pyqt4DocDir, 'index.html'), |
|
5464 Utilities.normjoinpath(pyqt4DocDir, 'classes.html'), |
|
5465 ] |
|
5466 for possibleHome in possibleHomes: |
|
5467 if os.path.exists(possibleHome): |
|
5468 home = possibleHome |
|
5469 break |
|
5470 else: |
|
5471 home = pyqt4DocDir |
|
5472 |
|
5473 if not home or not os.path.exists(home): |
|
5474 E5MessageBox.warning( |
|
5475 self, |
|
5476 self.tr("Documentation Missing"), |
|
5477 self.tr("""<p>The documentation starting point""" |
|
5478 """ "<b>{0}</b>" could not be found.</p>""") |
|
5479 .format(home)) |
|
5480 return |
|
5481 |
|
5482 if Utilities.isWindowsPlatform(): |
|
5483 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5484 else: |
|
5485 home = "file://" + home |
|
5486 else: |
|
5487 home = pyqt4DocDir |
|
5488 |
|
5489 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5490 if hvType == 1: |
|
5491 self.launchHelpViewer(home) |
|
5492 elif hvType == 2: |
|
5493 if home.startswith("qthelp://"): |
|
5494 self.__assistant(home, version=4) |
|
5495 else: |
|
5496 self.__webBrowser(home) |
|
5497 elif hvType == 3: |
|
5498 self.__webBrowser(home) |
|
5499 else: |
|
5500 self.__customViewer(home) |
|
5501 |
|
5502 def __showPyQt5Doc(self): |
|
5503 """ |
|
5504 Private slot to show the PyQt5 documentation. |
|
5505 """ |
|
5506 pyqt5DocDir = Preferences.getHelp("PyQt5DocDir") |
|
5507 if not pyqt5DocDir: |
|
5508 pyqt5DocDir = Utilities.getEnvironmentEntry("PYQT5DOCDIR", None) |
|
5509 |
|
5510 if not pyqt5DocDir: |
|
5511 E5MessageBox.warning( |
|
5512 self, |
|
5513 self.tr("Documentation"), |
|
5514 self.tr("""<p>The PyQt5 documentation starting point""" |
|
5515 """ has not been configured.</p>""")) |
|
5516 return |
|
5517 |
|
5518 if not pyqt5DocDir.startswith(("http://", "https://", "qthelp://")): |
|
5519 home = "" |
|
5520 if pyqt5DocDir: |
|
5521 if pyqt5DocDir.startswith("file://"): |
|
5522 pyqt5DocDir = pyqt5DocDir[7:] |
|
5523 if not os.path.splitext(pyqt5DocDir)[1]: |
|
5524 possibleHomes = [ |
|
5525 Utilities.normjoinpath( |
|
5526 pyqt5DocDir, 'index.html'), |
|
5527 Utilities.normjoinpath( |
|
5528 pyqt5DocDir, 'class_reference.html'), |
|
5529 ] |
|
5530 for possibleHome in possibleHomes: |
|
5531 if os.path.exists(possibleHome): |
|
5532 home = possibleHome |
|
5533 break |
|
5534 else: |
|
5535 home = pyqt5DocDir |
|
5536 |
|
5537 if not home or not os.path.exists(home): |
|
5538 E5MessageBox.warning( |
|
5539 self, |
|
5540 self.tr("Documentation Missing"), |
|
5541 self.tr("""<p>The documentation starting point""" |
|
5542 """ "<b>{0}</b>" could not be found.</p>""") |
|
5543 .format(home)) |
|
5544 return |
|
5545 |
|
5546 if Utilities.isWindowsPlatform(): |
|
5547 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5548 else: |
|
5549 home = "file://" + home |
|
5550 else: |
|
5551 home = pyqt5DocDir |
|
5552 |
|
5553 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5554 if hvType == 1: |
|
5555 self.launchHelpViewer(home) |
|
5556 elif hvType == 2: |
|
5557 if home.startswith("qthelp://"): |
|
5558 self.__assistant(home, version=4) |
|
5559 else: |
|
5560 self.__webBrowser(home) |
|
5561 elif hvType == 3: |
|
5562 self.__webBrowser(home) |
|
5563 else: |
|
5564 self.__customViewer(home) |
|
5565 |
|
5566 def __showEricDoc(self): |
|
5567 """ |
|
5568 Private slot to show the Eric documentation. |
|
5569 """ |
|
5570 home = Preferences.getHelp("EricDocDir") |
|
5571 if not home: |
|
5572 home = Utilities.normjoinpath( |
|
5573 getConfig('ericDocDir'), "Source", "index.html") |
|
5574 |
|
5575 if not home.startswith(("http://", "https://", "qthelp://")): |
|
5576 if not os.path.exists(home): |
|
5577 E5MessageBox.warning( |
|
5578 self, |
|
5579 self.tr("Documentation Missing"), |
|
5580 self.tr("""<p>The documentation starting point""" |
|
5581 """ "<b>{0}</b>" could not be found.</p>""") |
|
5582 .format(home)) |
|
5583 return |
|
5584 |
|
5585 if Utilities.isWindowsPlatform(): |
|
5586 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5587 else: |
|
5588 home = "file://" + home |
|
5589 |
|
5590 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5591 if hvType == 1: |
|
5592 self.launchHelpViewer(home) |
|
5593 elif hvType == 2: |
|
5594 if home.startswith("qthelp://"): |
|
5595 self.__assistant(home, version=4) |
|
5596 else: |
|
5597 self.__webBrowser(home) |
|
5598 elif hvType == 3: |
|
5599 self.__webBrowser(home) |
|
5600 else: |
|
5601 self.__customViewer(home) |
|
5602 |
|
5603 def __showPySideDoc(self, variant): |
|
5604 """ |
|
5605 Private slot to show the PySide/PySide2 documentation. |
|
5606 |
|
5607 @param variant PySide variant (1 or 2) |
|
5608 @type str |
|
5609 """ |
|
5610 assert variant in ("1", "2") |
|
5611 |
|
5612 if variant == "1": |
|
5613 pysideDocDir = Preferences.getHelp("PySideDocDir") |
|
5614 if not pysideDocDir: |
|
5615 pysideDocDir = Utilities.getEnvironmentEntry( |
|
5616 "PYSIDEDOCDIR", None) |
|
5617 else: |
|
5618 pysideDocDir = Preferences.getHelp("PySide2DocDir") |
|
5619 if not pysideDocDir: |
|
5620 pysideDocDir = Utilities.getEnvironmentEntry( |
|
5621 "PYSIDE2DOCDIR", None) |
|
5622 |
|
5623 if not pysideDocDir: |
|
5624 E5MessageBox.warning( |
|
5625 self, |
|
5626 self.tr("Documentation"), |
|
5627 self.tr("""<p>The PySide{0} documentation starting point""" |
|
5628 """ has not been configured.</p>""").format( |
|
5629 "" if variant == "1" else variant) |
|
5630 ) |
|
5631 return |
|
5632 |
|
5633 if not pysideDocDir.startswith(("http://", "https://", "qthelp://")): |
|
5634 if pysideDocDir.startswith("file://"): |
|
5635 pysideDocDir = pysideDocDir[7:] |
|
5636 if not os.path.splitext(pysideDocDir)[1]: |
|
5637 home = Utilities.normjoinpath(pysideDocDir, 'index.html') |
|
5638 else: |
|
5639 home = pysideDocDir |
|
5640 if not os.path.exists(home): |
|
5641 E5MessageBox.warning( |
|
5642 self, |
|
5643 self.tr("Documentation Missing"), |
|
5644 self.tr("""<p>The documentation starting point""" |
|
5645 """ "<b>{0}</b>" could not be found.</p>""") |
|
5646 .format(home)) |
|
5647 return |
|
5648 |
|
5649 if Utilities.isWindowsPlatform(): |
|
5650 home = "file:///" + Utilities.fromNativeSeparators(home) |
|
5651 else: |
|
5652 home = "file://" + home |
|
5653 else: |
|
5654 home = pysideDocDir |
|
5655 |
|
5656 hvType = Preferences.getWebBrowser("HelpViewerType") |
|
5657 if hvType == 1: |
|
5658 self.launchHelpViewer(home) |
|
5659 elif hvType == 2: |
|
5660 if home.startswith("qthelp://"): |
|
5661 self.__assistant(home, version=4) |
|
5662 else: |
|
5663 self.__webBrowser(home) |
|
5664 elif hvType == 3: |
|
5665 self.__webBrowser(home) |
|
5666 else: |
|
5667 self.__customViewer(home) |
|
5668 |
|
5669 @pyqtSlot(QUrl) |
|
5670 def handleUrl(self, url): |
|
5671 """ |
|
5672 Public slot to handle opening a URL. |
|
5673 |
|
5674 @param url URL to be shown |
|
5675 @type QUrl |
|
5676 """ |
|
5677 self.launchHelpViewer(url) |
|
5678 |
|
5679 def launchHelpViewer(self, home, searchWord=None, useSingle=False): |
|
5680 """ |
|
5681 Public slot to start the help viewer/web browser. |
|
5682 |
|
5683 @param home filename of file to be shown or URL to be opened |
|
5684 @type str or QUrl |
|
5685 @keyparam searchWord word to search for |
|
5686 @type str |
|
5687 @keyparam useSingle flag indicating to use a single browser window |
|
5688 @type bool |
|
5689 """ |
|
5690 if isinstance(home, QUrl): |
|
5691 home = home.toString(QUrl.None_) |
|
5692 |
|
5693 if len(home) > 0: |
|
5694 homeUrl = QUrl(home) |
|
5695 if not homeUrl.scheme(): |
|
5696 home = QUrl.fromLocalFile(home).toString() |
|
5697 |
|
5698 launchResult = self.__launchExternalWebBrowser( |
|
5699 home, searchWord=searchWord) |
|
5700 if not launchResult: |
|
5701 self.__webBrowser(home) |
|
5702 |
|
5703 def __launchExternalWebBrowser(self, home, searchWord=None): |
|
5704 """ |
|
5705 Private method to start an external web browser and communicate with |
|
5706 it. |
|
5707 |
|
5708 @param home filename of file to be shown or URL to be opened |
|
5709 @type str |
|
5710 @keyparam searchWord word to search for |
|
5711 @type str |
|
5712 @return flag indicating a successful launch |
|
5713 @rtype bool |
|
5714 """ |
|
5715 clientArgs = [] |
|
5716 if searchWord: |
|
5717 clientArgs.append("--search={0}".format(searchWord)) |
|
5718 |
|
5719 if self.__webBrowserProcess is None: |
|
5720 webBrowsers = [ |
|
5721 os.path.join( |
|
5722 os.path.dirname(__file__), "..", "eric6_browser.py"), |
|
5723 # QtWebEngine based web browser |
|
5724 os.path.join( |
|
5725 os.path.dirname(__file__), "..", "eric6_webbrowser.py"), |
|
5726 # QtWebKit based web browser |
|
5727 ] |
|
5728 process = QProcess() |
|
5729 for browser in webBrowsers: |
|
5730 args = [ |
|
5731 browser, |
|
5732 "--quiet", |
|
5733 "--qthelp", |
|
5734 "--single", |
|
5735 "--name={0}".format(self.__webBrowserSAName), |
|
5736 home |
|
5737 ] |
|
5738 process.start(sys.executable, args) |
|
5739 if not process.waitForStarted(): |
|
5740 E5MessageBox.warning( |
|
5741 self, |
|
5742 self.tr("Start Web Browser"), |
|
5743 self.tr("""The eric6 web browser could not be""" |
|
5744 """ started.""")) |
|
5745 return False |
|
5746 |
|
5747 res = self.__connectToWebBrowser(process) |
|
5748 if res == 1: |
|
5749 # connection unsuccessful |
|
5750 return False |
|
5751 elif res == 0: |
|
5752 # successful |
|
5753 break |
|
5754 else: |
|
5755 return False |
|
5756 |
|
5757 process.finished.connect(self.__webBrowserFinished) |
|
5758 self.__webBrowserProcess = process |
|
5759 |
|
5760 else: |
|
5761 clientArgs.append("--newtab={0}".format(home)) |
|
5762 |
|
5763 if clientArgs: |
|
5764 self.__webBrowserClient.processArgs(clientArgs, disconnect=False) |
|
5765 |
|
5766 return True |
|
5767 |
|
5768 def __connectToWebBrowser(self, process): |
|
5769 """ |
|
5770 Private method to connect to a started web browser. |
|
5771 |
|
5772 @param process reference to the started web browser process |
|
5773 @type QProcess |
|
5774 @return error indication (1 = connection not possible, 0 = ok, |
|
5775 -1 = server exited with an error code) |
|
5776 @rtype int |
|
5777 """ |
|
5778 from WebBrowser.WebBrowserSingleApplication import \ |
|
5779 WebBrowserSingleApplicationClient |
|
5780 |
|
5781 webBrowserClient = WebBrowserSingleApplicationClient( |
|
5782 self.__webBrowserSAName) |
|
5783 connectCount = 30 |
|
5784 while connectCount: |
|
5785 res = webBrowserClient.connect() |
|
5786 if res != 0: |
|
5787 break |
|
5788 else: |
|
5789 connectCount -= 1 |
|
5790 QThread.msleep(1000) |
|
5791 QApplication.processEvents() |
|
5792 if process.state() == QProcess.NotRunning and \ |
|
5793 process.exitStatus() == QProcess.NormalExit and \ |
|
5794 process.exitCode() == 100: |
|
5795 # Process exited prematurely due to missing pre-requisites |
|
5796 return -1 |
|
5797 if res <= 0: |
|
5798 E5MessageBox.warning( |
|
5799 self, |
|
5800 self.tr("Start Web Browser"), |
|
5801 self.tr("""<p>The eric6 web browser is not started.</p>""" |
|
5802 """<p>Reason: {0}</p>""").format( |
|
5803 webBrowserClient.errstr()) |
|
5804 ) |
|
5805 return 1 |
|
5806 |
|
5807 self.__webBrowserClient = webBrowserClient |
|
5808 return 0 |
|
5809 |
|
5810 def __webBrowserFinished(self): |
|
5811 """ |
|
5812 Private slot handling the end of the external web browser process. |
|
5813 """ |
|
5814 self.__webBrowserProcess.deleteLater() |
|
5815 |
|
5816 self.__webBrowserProcess = None |
|
5817 self.__webBrowserClient = None |
|
5818 |
|
5819 def __webBrowserShutdown(self): |
|
5820 """ |
|
5821 Private method to shut down the web browser. |
|
5822 """ |
|
5823 self.__webBrowserClient.processArgs(["--shutdown"], disconnect=False) |
|
5824 |
|
5825 def __helpViewer(self): |
|
5826 """ |
|
5827 Private slot to start an empty help viewer/web browser. |
|
5828 """ |
|
5829 searchWord = self.viewmanager.textForFind(False) |
|
5830 if searchWord == "": |
|
5831 searchWord = None |
|
5832 |
|
5833 self.launchHelpViewer("", searchWord=searchWord) |
|
5834 |
|
5835 def __webBrowser(self, home=""): |
|
5836 """ |
|
5837 Private slot to start the eric6 web browser. |
|
5838 |
|
5839 @param home full pathname of a file to display (string) |
|
5840 """ |
|
5841 started = QDesktopServices.openUrl(QUrl(home)) |
|
5842 if not started: |
|
5843 E5MessageBox.critical( |
|
5844 self, |
|
5845 self.tr('Open Browser'), |
|
5846 self.tr('Could not start a web browser')) |
|
5847 |
|
5848 @pyqtSlot() |
|
5849 @pyqtSlot(str) |
|
5850 def showPreferences(self, pageName=None): |
|
5851 """ |
|
5852 Public slot to set the preferences. |
|
5853 |
|
5854 @param pageName name of the configuration page to show (string) |
|
5855 """ |
|
5856 from Preferences.ConfigurationDialog import ConfigurationDialog |
|
5857 dlg = ConfigurationDialog( |
|
5858 self, 'Configuration', |
|
5859 expandedEntries=self.__expandedConfigurationEntries, |
|
5860 ) |
|
5861 dlg.preferencesChanged.connect(self.__preferencesChanged) |
|
5862 dlg.masterPasswordChanged.connect(self.__masterPasswordChanged) |
|
5863 dlg.show() |
|
5864 if pageName is not None: |
|
5865 dlg.showConfigurationPageByName(pageName) |
|
5866 elif self.__lastConfigurationPageName: |
|
5867 dlg.showConfigurationPageByName(self.__lastConfigurationPageName) |
|
5868 else: |
|
5869 dlg.showConfigurationPageByName("empty") |
|
5870 dlg.exec_() |
|
5871 QApplication.processEvents() |
|
5872 if dlg.result() == QDialog.Accepted: |
|
5873 dlg.setPreferences() |
|
5874 Preferences.syncPreferences() |
|
5875 self.__preferencesChanged() |
|
5876 self.__lastConfigurationPageName = dlg.getConfigurationPageName() |
|
5877 self.__expandedConfigurationEntries = dlg.getExpandedEntries() |
|
5878 |
|
5879 def __exportPreferences(self): |
|
5880 """ |
|
5881 Private slot to export the current preferences. |
|
5882 """ |
|
5883 Preferences.exportPreferences() |
|
5884 |
|
5885 def __importPreferences(self): |
|
5886 """ |
|
5887 Private slot to import preferences. |
|
5888 """ |
|
5889 Preferences.importPreferences() |
|
5890 self.__preferencesChanged() |
|
5891 |
|
5892 def __preferencesChanged(self): |
|
5893 """ |
|
5894 Private slot to handle a change of the preferences. |
|
5895 """ |
|
5896 self.setStyle(Preferences.getUI("Style"), |
|
5897 Preferences.getUI("StyleSheet")) |
|
5898 |
|
5899 if Preferences.getUI("SingleApplicationMode"): |
|
5900 if self.SAServer is None: |
|
5901 self.SAServer = E5SingleApplicationServer() |
|
5902 else: |
|
5903 if self.SAServer is not None: |
|
5904 self.SAServer.shutdown() |
|
5905 self.SAServer = None |
|
5906 self.newWindowAct.setEnabled( |
|
5907 not Preferences.getUI("SingleApplicationMode")) |
|
5908 |
|
5909 self.maxEditorPathLen = Preferences.getUI("CaptionFilenameLength") |
|
5910 self.captionShowsFilename = Preferences.getUI("CaptionShowsFilename") |
|
5911 if not self.captionShowsFilename: |
|
5912 self.__setWindowCaption(editor="") |
|
5913 else: |
|
5914 aw = self.viewmanager.activeWindow() |
|
5915 fn = aw and aw.getFileName() or None |
|
5916 if fn: |
|
5917 self.__setWindowCaption(editor=fn) |
|
5918 else: |
|
5919 self.__setWindowCaption(editor="") |
|
5920 |
|
5921 self.__httpAlternatives = Preferences.getUI("VersionsUrls6") |
|
5922 self.performVersionCheck(False) |
|
5923 |
|
5924 self.__configureDockareaCornerUsage() |
|
5925 |
|
5926 from QScintilla.SpellChecker import SpellChecker |
|
5927 SpellChecker.setDefaultLanguage( |
|
5928 Preferences.getEditor("SpellCheckingDefaultLanguage")) |
|
5929 |
|
5930 if self.__layoutType == "Sidebars": |
|
5931 delay = Preferences.getUI("SidebarDelay") |
|
5932 self.leftSidebar.setDelay(delay) |
|
5933 self.bottomSidebar.setDelay(delay) |
|
5934 self.rightSidebar.setDelay(delay) |
|
5935 |
|
5936 if Preferences.getUI("UseSystemProxy"): |
|
5937 QNetworkProxyFactory.setUseSystemConfiguration(True) |
|
5938 else: |
|
5939 self.__proxyFactory = E5NetworkProxyFactory() |
|
5940 QNetworkProxyFactory.setApplicationProxyFactory( |
|
5941 self.__proxyFactory) |
|
5942 QNetworkProxyFactory.setUseSystemConfiguration(False) |
|
5943 |
|
5944 from HexEdit.HexEditMainWindow import HexEditMainWindow |
|
5945 for hexEditor in HexEditMainWindow.windows: |
|
5946 hexEditor.preferencesChanged() |
|
5947 |
|
5948 # set the keyboard input interval |
|
5949 interval = Preferences.getUI("KeyboardInputInterval") |
|
5950 if interval > 0: |
|
5951 QApplication.setKeyboardInputInterval(interval) |
|
5952 else: |
|
5953 QApplication.setKeyboardInputInterval(-1) |
|
5954 |
|
5955 if not self.__disableCrashSession: |
|
5956 if Preferences.getUI("CrashSessionEnabled"): |
|
5957 self.__writeCrashSession() |
|
5958 else: |
|
5959 self.__deleteCrashSession() |
|
5960 |
|
5961 self.preferencesChanged.emit() |
|
5962 |
|
5963 def __masterPasswordChanged(self, oldPassword, newPassword): |
|
5964 """ |
|
5965 Private slot to handle the change of the master password. |
|
5966 |
|
5967 @param oldPassword current master password (string) |
|
5968 @param newPassword new master password (string) |
|
5969 """ |
|
5970 import Globals |
|
5971 |
|
5972 self.masterPasswordChanged.emit(oldPassword, newPassword) |
|
5973 Preferences.convertPasswords(oldPassword, newPassword) |
|
5974 variant = Globals.getWebBrowserSupport() |
|
5975 if variant == "QtWebEngine": |
|
5976 from WebBrowser.Passwords.PasswordManager import \ |
|
5977 PasswordManager |
|
5978 pwManager = PasswordManager() |
|
5979 pwManager.masterPasswordChanged(oldPassword, newPassword) |
|
5980 elif variant == "QtWebKit": |
|
5981 from Helpviewer.Passwords.PasswordManager import \ |
|
5982 PasswordManager |
|
5983 pwManager = PasswordManager() |
|
5984 pwManager.masterPasswordChanged(oldPassword, newPassword) |
|
5985 Utilities.crypto.changeRememberedMaster(newPassword) |
|
5986 |
|
5987 def __reloadAPIs(self): |
|
5988 """ |
|
5989 Private slot to reload the api information. |
|
5990 """ |
|
5991 self.reloadAPIs.emit() |
|
5992 |
|
5993 def __showExternalTools(self): |
|
5994 """ |
|
5995 Private slot to display a dialog show a list of external tools used |
|
5996 by eric6. |
|
5997 """ |
|
5998 if self.programsDialog is None: |
|
5999 from Preferences.ProgramsDialog import ProgramsDialog |
|
6000 self.programsDialog = ProgramsDialog(self) |
|
6001 self.programsDialog.show() |
|
6002 |
|
6003 def __configViewProfiles(self): |
|
6004 """ |
|
6005 Private slot to configure the various view profiles. |
|
6006 """ |
|
6007 from Preferences.ViewProfileDialog import ViewProfileDialog |
|
6008 dlg = ViewProfileDialog(self.__layoutType, self.profiles['edit'][1], |
|
6009 self.profiles['debug'][1]) |
|
6010 if dlg.exec_() == QDialog.Accepted: |
|
6011 edit, debug = dlg.getVisibilities() |
|
6012 self.profiles['edit'][1] = edit |
|
6013 self.profiles['debug'][1] = debug |
|
6014 Preferences.setUI("ViewProfiles2", self.profiles) |
|
6015 if self.currentProfile == "edit": |
|
6016 self.__setEditProfile(False) |
|
6017 elif self.currentProfile == "debug": |
|
6018 self.setDebugProfile(False) |
|
6019 |
|
6020 def __configToolBars(self): |
|
6021 """ |
|
6022 Private slot to configure the various toolbars. |
|
6023 """ |
|
6024 from E5Gui.E5ToolBarDialog import E5ToolBarDialog |
|
6025 dlg = E5ToolBarDialog(self.toolbarManager) |
|
6026 if dlg.exec_() == QDialog.Accepted: |
|
6027 Preferences.setUI( |
|
6028 "ToolbarManagerState", self.toolbarManager.saveState()) |
|
6029 |
|
6030 def __configShortcuts(self): |
|
6031 """ |
|
6032 Private slot to configure the keyboard shortcuts. |
|
6033 """ |
|
6034 if self.shortcutsDialog is None: |
|
6035 from Preferences.ShortcutsDialog import ShortcutsDialog |
|
6036 self.shortcutsDialog = ShortcutsDialog(self) |
|
6037 self.shortcutsDialog.populate() |
|
6038 self.shortcutsDialog.show() |
|
6039 |
|
6040 def __exportShortcuts(self): |
|
6041 """ |
|
6042 Private slot to export the keyboard shortcuts. |
|
6043 """ |
|
6044 fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
|
6045 None, |
|
6046 self.tr("Export Keyboard Shortcuts"), |
|
6047 "", |
|
6048 self.tr("Keyboard shortcut file (*.e4k)"), |
|
6049 "", |
|
6050 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) |
|
6051 |
|
6052 if not fn: |
|
6053 return |
|
6054 |
|
6055 ext = QFileInfo(fn).suffix() |
|
6056 if not ext: |
|
6057 ex = selectedFilter.split("(*")[1].split(")")[0] |
|
6058 if ex: |
|
6059 fn += ex |
|
6060 |
|
6061 from Preferences import Shortcuts |
|
6062 Shortcuts.exportShortcuts(fn) |
|
6063 |
|
6064 def __importShortcuts(self): |
|
6065 """ |
|
6066 Private slot to import the keyboard shortcuts. |
|
6067 """ |
|
6068 fn = E5FileDialog.getOpenFileName( |
|
6069 None, |
|
6070 self.tr("Import Keyboard Shortcuts"), |
|
6071 "", |
|
6072 self.tr("Keyboard shortcut file (*.e4k)")) |
|
6073 |
|
6074 if fn: |
|
6075 from Preferences import Shortcuts |
|
6076 Shortcuts.importShortcuts(fn) |
|
6077 |
|
6078 def __showCertificatesDialog(self): |
|
6079 """ |
|
6080 Private slot to show the certificates management dialog. |
|
6081 """ |
|
6082 from E5Network.E5SslCertificatesDialog import E5SslCertificatesDialog |
|
6083 |
|
6084 dlg = E5SslCertificatesDialog(self) |
|
6085 dlg.exec_() |
|
6086 |
|
6087 def __clearPrivateData(self): |
|
6088 """ |
|
6089 Private slot to clear the private data lists. |
|
6090 """ |
|
6091 from .ClearPrivateDataDialog import ClearPrivateDataDialog |
|
6092 dlg = ClearPrivateDataDialog(self) |
|
6093 if dlg.exec_() == QDialog.Accepted: |
|
6094 # recent files, recent projects, recent multi projects, |
|
6095 # debug histories, shell histories |
|
6096 (files, projects, multiProjects, debug, shell, vcs, plugins) = \ |
|
6097 dlg.getData() |
|
6098 if files: |
|
6099 # clear list of recently opened files |
|
6100 self.viewmanager.clearRecent() |
|
6101 if projects: |
|
6102 # clear list of recently opened projects and other histories |
|
6103 self.project.clearHistories() |
|
6104 if multiProjects: |
|
6105 # clear list of recently opened multi projects |
|
6106 self.multiProject.clearRecent() |
|
6107 if debug: |
|
6108 # clear the various debug histories |
|
6109 self.debuggerUI.clearHistories() |
|
6110 if shell: |
|
6111 # clear the shell histories |
|
6112 self.shell.clearAllHistories() |
|
6113 if vcs: |
|
6114 # clear the VCS related histories |
|
6115 self.pluginManager.clearPluginsPrivateData("version_control") |
|
6116 if plugins: |
|
6117 # clear private data of plug-ins not covered above |
|
6118 self.pluginManager.clearPluginsPrivateData("") |
|
6119 |
|
6120 Preferences.syncPreferences() |
|
6121 |
|
6122 def __newProject(self): |
|
6123 """ |
|
6124 Private slot to handle the NewProject signal. |
|
6125 """ |
|
6126 self.__setWindowCaption(project=self.project.name) |
|
6127 |
|
6128 def __projectOpened(self): |
|
6129 """ |
|
6130 Private slot to handle the projectOpened signal. |
|
6131 """ |
|
6132 from Debugger.DebugClientCapabilities import HasUnittest |
|
6133 self.__setWindowCaption(project=self.project.name) |
|
6134 cap = e5App().getObject("DebugServer")\ |
|
6135 .getClientCapabilities(self.project.getProjectLanguage()) |
|
6136 self.utProjectAct.setEnabled(cap & HasUnittest) |
|
6137 self.utProjectOpen = cap & HasUnittest |
|
6138 |
|
6139 def __projectClosed(self): |
|
6140 """ |
|
6141 Private slot to handle the projectClosed signal. |
|
6142 """ |
|
6143 self.__setWindowCaption(project="") |
|
6144 self.utProjectAct.setEnabled(False) |
|
6145 if not self.utEditorOpen: |
|
6146 self.utRestartAct.setEnabled(False) |
|
6147 self.utRerunFailedAct.setEnabled(False) |
|
6148 self.utProjectOpen = False |
|
6149 |
|
6150 def __programChange(self, fn): |
|
6151 """ |
|
6152 Private slot to handle the programChange signal. |
|
6153 |
|
6154 This primarily is here to set the currentProg variable. |
|
6155 |
|
6156 @param fn filename to be set as current prog (string) |
|
6157 """ |
|
6158 # Delete the old program if there was one. |
|
6159 if self.currentProg is not None: |
|
6160 del self.currentProg |
|
6161 |
|
6162 self.currentProg = os.path.normpath(fn) |
|
6163 |
|
6164 def __lastEditorClosed(self): |
|
6165 """ |
|
6166 Private slot to handle the lastEditorClosed signal. |
|
6167 """ |
|
6168 self.wizardsMenuAct.setEnabled(False) |
|
6169 self.utScriptAct.setEnabled(False) |
|
6170 self.utEditorOpen = False |
|
6171 if not self.utProjectOpen: |
|
6172 self.utRestartAct.setEnabled(False) |
|
6173 self.utRerunFailedAct.setEnabled(False) |
|
6174 self.__setWindowCaption(editor="") |
|
6175 |
|
6176 def __editorOpened(self, fn): |
|
6177 """ |
|
6178 Private slot to handle the editorOpened signal. |
|
6179 |
|
6180 @param fn filename of the opened editor (string) |
|
6181 """ |
|
6182 self.wizardsMenuAct.setEnabled( |
|
6183 len(self.__menus["wizards"].actions()) > 0) |
|
6184 |
|
6185 if fn and str(fn) != "None": |
|
6186 dbs = e5App().getObject("DebugServer") |
|
6187 for language in dbs.getSupportedLanguages(): |
|
6188 exts = dbs.getExtensions(language) |
|
6189 if fn.endswith(exts): |
|
6190 from Debugger.DebugClientCapabilities import HasUnittest |
|
6191 cap = dbs.getClientCapabilities(language) |
|
6192 self.utScriptAct.setEnabled(cap & HasUnittest) |
|
6193 self.utEditorOpen = cap & HasUnittest |
|
6194 return |
|
6195 |
|
6196 if self.viewmanager.getOpenEditor(fn).isPyFile(): |
|
6197 self.utScriptAct.setEnabled(True) |
|
6198 self.utEditorOpen = True |
|
6199 |
|
6200 def __checkActions(self, editor): |
|
6201 """ |
|
6202 Private slot to check some actions for their enable/disable status. |
|
6203 |
|
6204 @param editor editor window |
|
6205 """ |
|
6206 if editor: |
|
6207 fn = editor.getFileName() |
|
6208 else: |
|
6209 fn = None |
|
6210 |
|
6211 if fn: |
|
6212 dbs = e5App().getObject("DebugServer") |
|
6213 for language in dbs.getSupportedLanguages(): |
|
6214 exts = dbs.getExtensions(language) |
|
6215 if fn.endswith(exts): |
|
6216 from Debugger.DebugClientCapabilities import HasUnittest |
|
6217 cap = dbs.getClientCapabilities(language) |
|
6218 self.utScriptAct.setEnabled(cap & HasUnittest) |
|
6219 self.utEditorOpen = cap & HasUnittest |
|
6220 return |
|
6221 |
|
6222 if editor.isPyFile(): |
|
6223 self.utScriptAct.setEnabled(True) |
|
6224 self.utEditorOpen = True |
|
6225 return |
|
6226 |
|
6227 self.utScriptAct.setEnabled(False) |
|
6228 |
|
6229 def __writeTasks(self): |
|
6230 """ |
|
6231 Private slot to write the tasks data to an XML file (.e6t). |
|
6232 """ |
|
6233 fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e6t") |
|
6234 f = QFile(fn) |
|
6235 ok = f.open(QIODevice.WriteOnly) |
|
6236 if not ok: |
|
6237 E5MessageBox.critical( |
|
6238 self, |
|
6239 self.tr("Save tasks"), |
|
6240 self.tr( |
|
6241 "<p>The tasks file <b>{0}</b> could not be written.</p>") |
|
6242 .format(fn)) |
|
6243 return |
|
6244 |
|
6245 from E5XML.TasksWriter import TasksWriter |
|
6246 TasksWriter(f, False).writeXML() |
|
6247 f.close() |
|
6248 |
|
6249 def __readTasks(self): |
|
6250 """ |
|
6251 Private slot to read in the tasks file (.e6t). |
|
6252 """ |
|
6253 fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e6t") |
|
6254 if not os.path.exists(fn): |
|
6255 # try again with the old extension |
|
6256 fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e4t") |
|
6257 if not os.path.exists(fn): |
|
6258 return |
|
6259 f = QFile(fn) |
|
6260 if f.open(QIODevice.ReadOnly): |
|
6261 from E5XML.TasksReader import TasksReader |
|
6262 reader = TasksReader(f, viewer=self.taskViewer) |
|
6263 reader.readXML() |
|
6264 f.close() |
|
6265 else: |
|
6266 E5MessageBox.critical( |
|
6267 self, |
|
6268 self.tr("Read tasks"), |
|
6269 self.tr( |
|
6270 "<p>The tasks file <b>{0}</b> could not be read.</p>") |
|
6271 .format(fn)) |
|
6272 |
|
6273 def __writeSession(self, filename="", crashSession=False): |
|
6274 """ |
|
6275 Private slot to write the session data to an XML file (.e5s). |
|
6276 |
|
6277 @param filename name of a session file to write |
|
6278 @type str |
|
6279 @param crashSession flag indicating to write a crash session file |
|
6280 @type bool |
|
6281 @return flag indicating success |
|
6282 @rtype bool |
|
6283 """ |
|
6284 res = False |
|
6285 if filename: |
|
6286 fn = filename |
|
6287 elif crashSession: |
|
6288 fn = os.path.join(Utilities.getConfigDir(), |
|
6289 "eric6_crash_session.e5s") |
|
6290 else: |
|
6291 fn = os.path.join(Utilities.getConfigDir(), |
|
6292 "eric6session.e5s") |
|
6293 f = QFile(fn) |
|
6294 if f.open(QIODevice.WriteOnly): |
|
6295 from E5XML.SessionWriter import SessionWriter |
|
6296 SessionWriter(f, None).writeXML() |
|
6297 f.close() |
|
6298 res = True |
|
6299 else: |
|
6300 E5MessageBox.critical( |
|
6301 self, |
|
6302 self.tr("Save session"), |
|
6303 self.tr("<p>The session file <b>{0}</b> could not be" |
|
6304 " written.</p>") |
|
6305 .format(fn)) |
|
6306 return res |
|
6307 |
|
6308 def __readSession(self, filename=""): |
|
6309 """ |
|
6310 Private slot to read in the session file (.e5s or .e4s). |
|
6311 |
|
6312 @param filename name of a session file to read |
|
6313 @type str |
|
6314 @return flag indicating success |
|
6315 @rtype bool |
|
6316 """ |
|
6317 if filename: |
|
6318 fn = filename |
|
6319 else: |
|
6320 fn = os.path.join(Utilities.getConfigDir(), |
|
6321 "eric6session.e5s") |
|
6322 if not os.path.exists(fn): |
|
6323 fn = os.path.join(Utilities.getConfigDir(), |
|
6324 "eric6session.e4s") |
|
6325 if not os.path.exists(fn): |
|
6326 E5MessageBox.critical( |
|
6327 self, |
|
6328 self.tr("Read session"), |
|
6329 self.tr("<p>The session file <b>{0}</b> could not" |
|
6330 " be read.</p>") |
|
6331 .format(fn)) |
|
6332 fn = "" |
|
6333 |
|
6334 res = False |
|
6335 if fn: |
|
6336 f = QFile(fn) |
|
6337 if f.open(QIODevice.ReadOnly): |
|
6338 from E5XML.SessionReader import SessionReader |
|
6339 self.__readingSession = True |
|
6340 reader = SessionReader(f, True) |
|
6341 reader.readXML() |
|
6342 self.__readingSession = False |
|
6343 f.close() |
|
6344 res = True |
|
6345 else: |
|
6346 E5MessageBox.critical( |
|
6347 self, |
|
6348 self.tr("Read session"), |
|
6349 self.tr("<p>The session file <b>{0}</b> could not be" |
|
6350 " read.</p>") |
|
6351 .format(fn)) |
|
6352 |
|
6353 # Write a crash session after a session was read. |
|
6354 self.__writeCrashSession() |
|
6355 |
|
6356 return res |
|
6357 |
|
6358 def __saveSessionToFile(self): |
|
6359 """ |
|
6360 Private slot to save a session to disk. |
|
6361 """ |
|
6362 sessionFile, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
|
6363 self, |
|
6364 self.tr("Save session"), |
|
6365 Utilities.getHomeDir(), |
|
6366 self.tr("eric6 Session Files (*.e5s)"), |
|
6367 "") |
|
6368 |
|
6369 if not sessionFile: |
|
6370 return |
|
6371 |
|
6372 ext = QFileInfo(sessionFile).suffix() |
|
6373 if not ext: |
|
6374 ex = selectedFilter.split("(*")[1].split(")")[0] |
|
6375 if ex: |
|
6376 sessionFile += ex |
|
6377 |
|
6378 self.__writeSession(filename=sessionFile) |
|
6379 |
|
6380 def __loadSessionFromFile(self): |
|
6381 """ |
|
6382 Private slot to load a session from disk. |
|
6383 """ |
|
6384 sessionFile = E5FileDialog.getOpenFileName( |
|
6385 self, |
|
6386 self.tr("Load session"), |
|
6387 Utilities.getHomeDir(), |
|
6388 self.tr("eric6 Session Files (*.e5s)")) |
|
6389 |
|
6390 if not sessionFile: |
|
6391 return |
|
6392 |
|
6393 self.__readSession(filename=sessionFile) |
|
6394 |
|
6395 def __deleteCrashSession(self): |
|
6396 """ |
|
6397 Private slot to delete the crash session file. |
|
6398 """ |
|
6399 fn = os.path.join(Utilities.getConfigDir(), |
|
6400 "eric6_crash_session.e5s") |
|
6401 if os.path.exists(fn): |
|
6402 try: |
|
6403 os.remove(fn) |
|
6404 except OSError: |
|
6405 # ignore it silently |
|
6406 pass |
|
6407 |
|
6408 def __writeCrashSession(self): |
|
6409 """ |
|
6410 Private slot to write a crash session file. |
|
6411 """ |
|
6412 if not self.__readingSession and \ |
|
6413 not self.__disableCrashSession and \ |
|
6414 Preferences.getUI("CrashSessionEnabled"): |
|
6415 self.__writeSession(crashSession=True) |
|
6416 |
|
6417 def __readCrashSession(self): |
|
6418 """ |
|
6419 Private method to check for and read a crash session. |
|
6420 |
|
6421 @return flag indicating a crash session file was found and read |
|
6422 @rtype bool |
|
6423 """ |
|
6424 res = False |
|
6425 if not self.__disableCrashSession and \ |
|
6426 not self.__noCrashOpenAtStartup and \ |
|
6427 Preferences.getUI("OpenCrashSessionOnStartup"): |
|
6428 fn = os.path.join(Utilities.getConfigDir(), |
|
6429 "eric6_crash_session.e5s") |
|
6430 if os.path.exists(fn): |
|
6431 yes = E5MessageBox.yesNo( |
|
6432 self, |
|
6433 self.tr("Crash Session found!"), |
|
6434 self.tr("""A session file of a crashed session was""" |
|
6435 """ found. Shall this session be restored?""")) |
|
6436 if yes: |
|
6437 res = self.__readSession(filename=fn) |
|
6438 |
|
6439 return res |
|
6440 |
|
6441 def showFindFileByNameDialog(self): |
|
6442 """ |
|
6443 Public slot to show the Find File by Name dialog. |
|
6444 """ |
|
6445 if self.findFileNameDialog is None: |
|
6446 from .FindFileNameDialog import FindFileNameDialog |
|
6447 self.findFileNameDialog = FindFileNameDialog(self.project) |
|
6448 self.findFileNameDialog.sourceFile.connect( |
|
6449 self.viewmanager.openSourceFile) |
|
6450 self.findFileNameDialog.designerFile.connect(self.__designer) |
|
6451 self.findFileNameDialog.show() |
|
6452 self.findFileNameDialog.raise_() |
|
6453 self.findFileNameDialog.activateWindow() |
|
6454 |
|
6455 def showFindFilesDialog(self, txt="", searchDir="", openFiles=False): |
|
6456 """ |
|
6457 Public slot to show the Find In Files dialog. |
|
6458 |
|
6459 @keyparam txt text to search for (string) |
|
6460 @keyparam searchDir directory to search in (string) |
|
6461 @keyparam openFiles flag indicating to operate on open files (boolean) |
|
6462 """ |
|
6463 if self.findFilesDialog is None: |
|
6464 from .FindFileDialog import FindFileDialog |
|
6465 self.findFilesDialog = FindFileDialog(self.project) |
|
6466 self.findFilesDialog.sourceFile.connect( |
|
6467 self.viewmanager.openSourceFile) |
|
6468 self.findFilesDialog.designerFile.connect(self.__designer) |
|
6469 if searchDir: |
|
6470 self.findFilesDialog.setSearchDirectory(searchDir) |
|
6471 self.findFilesDialog.show(txt) |
|
6472 if openFiles: |
|
6473 self.findFilesDialog.setOpenFiles() |
|
6474 self.findFilesDialog.raise_() |
|
6475 self.findFilesDialog.activateWindow() |
|
6476 |
|
6477 def showReplaceFilesDialog(self, txt="", searchDir="", openFiles=False): |
|
6478 """ |
|
6479 Public slot to show the Find & Replace In Files dialog. |
|
6480 |
|
6481 @keyparam txt text to search for (string) |
|
6482 @keyparam searchDir directory to search in (string) |
|
6483 @keyparam openFiles flag indicating to operate on open files (boolean) |
|
6484 """ |
|
6485 if self.replaceFilesDialog is None: |
|
6486 from .FindFileDialog import FindFileDialog |
|
6487 self.replaceFilesDialog = \ |
|
6488 FindFileDialog(self.project, replaceMode=True) |
|
6489 self.replaceFilesDialog.sourceFile.connect( |
|
6490 self.viewmanager.openSourceFile) |
|
6491 self.replaceFilesDialog.designerFile.connect(self.__designer) |
|
6492 if searchDir: |
|
6493 self.replaceFilesDialog.setSearchDirectory(searchDir) |
|
6494 self.replaceFilesDialog.show(txt) |
|
6495 if openFiles: |
|
6496 self.replaceFilesDialog.setOpenFiles() |
|
6497 self.replaceFilesDialog.raise_() |
|
6498 self.replaceFilesDialog.activateWindow() |
|
6499 |
|
6500 ########################################################## |
|
6501 ## Below are slots to handle StdOut and StdErr |
|
6502 ########################################################## |
|
6503 |
|
6504 def appendToStdout(self, s): |
|
6505 """ |
|
6506 Public slot to append text to the stdout log viewer tab. |
|
6507 |
|
6508 @param s output to be appended (string) |
|
6509 """ |
|
6510 self.appendStdout.emit(s) |
|
6511 |
|
6512 def appendToStderr(self, s): |
|
6513 """ |
|
6514 Public slot to append text to the stderr log viewer tab. |
|
6515 |
|
6516 @param s output to be appended (string) |
|
6517 """ |
|
6518 self.appendStderr.emit(s) |
|
6519 |
|
6520 ########################################################## |
|
6521 ## Below are slots needed by the plugin menu |
|
6522 ########################################################## |
|
6523 |
|
6524 def __showPluginInfo(self): |
|
6525 """ |
|
6526 Private slot to show the plugin info dialog. |
|
6527 """ |
|
6528 from PluginManager.PluginInfoDialog import PluginInfoDialog |
|
6529 self.__pluginInfoDialog = PluginInfoDialog(self.pluginManager, self) |
|
6530 self.__pluginInfoDialog.show() |
|
6531 |
|
6532 @pyqtSlot() |
|
6533 def __installPlugins(self, pluginFileNames=None): |
|
6534 """ |
|
6535 Private slot to show a dialog to install a new plugin. |
|
6536 |
|
6537 @param pluginFileNames list of plugin files suggested for |
|
6538 installation list of strings |
|
6539 """ |
|
6540 from PluginManager.PluginInstallDialog import PluginInstallDialog |
|
6541 dlg = PluginInstallDialog( |
|
6542 self.pluginManager, |
|
6543 [] if pluginFileNames is None else pluginFileNames[:], |
|
6544 self) |
|
6545 dlg.exec_() |
|
6546 if dlg.restartNeeded(): |
|
6547 self.__restart(ask=True) |
|
6548 |
|
6549 def __deinstallPlugin(self): |
|
6550 """ |
|
6551 Private slot to show a dialog to uninstall a plugin. |
|
6552 """ |
|
6553 from PluginManager.PluginUninstallDialog import PluginUninstallDialog |
|
6554 dlg = PluginUninstallDialog(self.pluginManager, self) |
|
6555 dlg.exec_() |
|
6556 |
|
6557 def showPluginsAvailable(self): |
|
6558 """ |
|
6559 Public slot to show the plugins available for download. |
|
6560 """ |
|
6561 from PluginManager.PluginRepositoryDialog import PluginRepositoryDialog |
|
6562 dlg = PluginRepositoryDialog(self.pluginManager, self) |
|
6563 res = dlg.exec_() |
|
6564 if res == (QDialog.Accepted + 1): |
|
6565 self.__installPlugins(dlg.getDownloadedPlugins()) |
|
6566 |
|
6567 def __pluginsConfigure(self): |
|
6568 """ |
|
6569 Private slot to show the plugin manager configuration page. |
|
6570 """ |
|
6571 self.showPreferences("pluginManagerPage") |
|
6572 |
|
6573 def checkPluginUpdatesAvailable(self): |
|
6574 """ |
|
6575 Public method to check the availability of updates of plug-ins. |
|
6576 """ |
|
6577 if self.isOnline(): |
|
6578 self.pluginManager.checkPluginUpdatesAvailable() |
|
6579 |
|
6580 ################################################################# |
|
6581 ## Drag and Drop Support |
|
6582 ################################################################# |
|
6583 |
|
6584 def dragEnterEvent(self, event): |
|
6585 """ |
|
6586 Protected method to handle the drag enter event. |
|
6587 |
|
6588 @param event the drag enter event (QDragEnterEvent) |
|
6589 """ |
|
6590 self.inDragDrop = event.mimeData().hasUrls() |
|
6591 if self.inDragDrop: |
|
6592 event.acceptProposedAction() |
|
6593 |
|
6594 def dragMoveEvent(self, event): |
|
6595 """ |
|
6596 Protected method to handle the drag move event. |
|
6597 |
|
6598 @param event the drag move event (QDragMoveEvent) |
|
6599 """ |
|
6600 if self.inDragDrop: |
|
6601 event.acceptProposedAction() |
|
6602 |
|
6603 def dragLeaveEvent(self, event): |
|
6604 """ |
|
6605 Protected method to handle the drag leave event. |
|
6606 |
|
6607 @param event the drag leave event (QDragLeaveEvent) |
|
6608 """ |
|
6609 if self.inDragDrop: |
|
6610 self.inDragDrop = False |
|
6611 |
|
6612 def dropEvent(self, event): |
|
6613 """ |
|
6614 Protected method to handle the drop event. |
|
6615 |
|
6616 @param event the drop event (QDropEvent) |
|
6617 """ |
|
6618 if event.mimeData().hasUrls(): |
|
6619 event.acceptProposedAction() |
|
6620 for url in event.mimeData().urls(): |
|
6621 fname = url.toLocalFile() |
|
6622 if fname: |
|
6623 if QFileInfo(fname).isFile(): |
|
6624 self.viewmanager.openSourceFile(fname) |
|
6625 else: |
|
6626 E5MessageBox.information( |
|
6627 self, |
|
6628 self.tr("Drop Error"), |
|
6629 self.tr("""<p><b>{0}</b> is not a file.</p>""") |
|
6630 .format(fname)) |
|
6631 |
|
6632 self.inDragDrop = False |
|
6633 |
|
6634 ########################################################## |
|
6635 ## Below are methods needed for shutting down the IDE |
|
6636 ########################################################## |
|
6637 |
|
6638 def closeEvent(self, event): |
|
6639 """ |
|
6640 Protected event handler for the close event. |
|
6641 |
|
6642 This event handler saves the preferences. |
|
6643 |
|
6644 @param event close event (QCloseEvent) |
|
6645 """ |
|
6646 if self.__shutdown(): |
|
6647 event.accept() |
|
6648 if not self.inCloseEvent: |
|
6649 self.inCloseEvent = True |
|
6650 QTimer.singleShot(0, e5App().closeAllWindows) |
|
6651 else: |
|
6652 event.ignore() |
|
6653 |
|
6654 def __shutdown(self): |
|
6655 """ |
|
6656 Private method to perform all necessary steps to close down the IDE. |
|
6657 |
|
6658 @return flag indicating success |
|
6659 """ |
|
6660 if self.shutdownCalled: |
|
6661 return True |
|
6662 |
|
6663 if self.__webBrowserProcess is not None: |
|
6664 self.__webBrowserShutdown() |
|
6665 |
|
6666 if self.irc is not None: |
|
6667 if not self.irc.shutdown(): |
|
6668 return False |
|
6669 |
|
6670 sessionCreated = self.__writeSession() |
|
6671 |
|
6672 self.__astViewer.hide() |
|
6673 |
|
6674 if not self.project.closeProject(): |
|
6675 return False |
|
6676 |
|
6677 if not self.multiProject.closeMultiProject(): |
|
6678 return False |
|
6679 |
|
6680 if not self.viewmanager.closeViewManager(): |
|
6681 return False |
|
6682 |
|
6683 if sessionCreated and not self.__disableCrashSession: |
|
6684 self.__deleteCrashSession() |
|
6685 |
|
6686 if self.codeDocumentationViewer is not None: |
|
6687 self.codeDocumentationViewer.shutdown() |
|
6688 |
|
6689 self.__previewer.shutdown() |
|
6690 |
|
6691 self.__astViewer.shutdown() |
|
6692 |
|
6693 self.shell.closeShell() |
|
6694 |
|
6695 self.__writeTasks() |
|
6696 |
|
6697 if self.templateViewer is not None: |
|
6698 self.templateViewer.save() |
|
6699 |
|
6700 if not self.debuggerUI.shutdownServer(): |
|
6701 return False |
|
6702 self.debuggerUI.shutdown() |
|
6703 |
|
6704 self.backgroundService.shutdown() |
|
6705 |
|
6706 if self.cooperation is not None: |
|
6707 self.cooperation.shutdown() |
|
6708 |
|
6709 self.pluginManager.doShutdown() |
|
6710 |
|
6711 self.virtualenvManager.shutdown() |
|
6712 |
|
6713 if self.__layoutType == "Sidebars": |
|
6714 self.leftSidebar.shutdown() |
|
6715 self.bottomSidebar.shutdown() |
|
6716 self.rightSidebar.shutdown() |
|
6717 |
|
6718 if self.SAServer is not None: |
|
6719 self.SAServer.shutdown() |
|
6720 self.SAServer = None |
|
6721 |
|
6722 # set proxy factory to None to avoid crashes |
|
6723 QNetworkProxyFactory.setApplicationProxyFactory(None) |
|
6724 |
|
6725 Preferences.setGeometry("MainMaximized", self.isMaximized()) |
|
6726 if not self.isMaximized(): |
|
6727 Preferences.setGeometry("MainGeometry", self.saveGeometry()) |
|
6728 |
|
6729 if self.browser is not None: |
|
6730 self.browser.saveToplevelDirs() |
|
6731 |
|
6732 Preferences.setUI( |
|
6733 "ToolbarManagerState", self.toolbarManager.saveState()) |
|
6734 self.__saveCurrentViewProfile(True) |
|
6735 Preferences.saveToolGroups(self.toolGroups, self.currentToolGroup) |
|
6736 Preferences.syncPreferences() |
|
6737 self.shutdownCalled = True |
|
6738 return True |
|
6739 |
|
6740 def isOnline(self): |
|
6741 """ |
|
6742 Public method to get the online state. |
|
6743 |
|
6744 @return online state |
|
6745 @rtype bool |
|
6746 """ |
|
6747 return self.networkIcon.isOnline() |
|
6748 |
|
6749 def __onlineStateChanged(self, online): |
|
6750 """ |
|
6751 Private slot handling changes in online state. |
|
6752 |
|
6753 @param online flag indicating the online state |
|
6754 @type bool |
|
6755 """ |
|
6756 if online: |
|
6757 self.performVersionCheck(False) |
|
6758 |
|
6759 ############################################## |
|
6760 ## Below are methods to check for new versions |
|
6761 ############################################## |
|
6762 |
|
6763 def showAvailableVersionsInfo(self): |
|
6764 """ |
|
6765 Public method to show the eric6 versions available for download. |
|
6766 """ |
|
6767 self.performVersionCheck(manual=True, showVersions=True) |
|
6768 |
|
6769 @pyqtSlot() |
|
6770 def performVersionCheck(self, manual=True, alternative=0, |
|
6771 showVersions=False): |
|
6772 """ |
|
6773 Public method to check the internet for an eric6 update. |
|
6774 |
|
6775 @param manual flag indicating an invocation via the menu (boolean) |
|
6776 @param alternative index of server to download from (integer) |
|
6777 @keyparam showVersions flag indicating the show versions mode (boolean) |
|
6778 """ |
|
6779 if self.isOnline(): |
|
6780 if not manual: |
|
6781 if VersionOnly.startswith("@@"): |
|
6782 return |
|
6783 else: |
|
6784 period = Preferences.getUI("PerformVersionCheck") |
|
6785 if period == 0: |
|
6786 return |
|
6787 elif period in [2, 3, 4]: |
|
6788 lastCheck = Preferences.Prefs.settings.value( |
|
6789 "Updates/LastCheckDate", QDate(1970, 1, 1)) |
|
6790 if lastCheck.isValid(): |
|
6791 now = QDate.currentDate() |
|
6792 if period == 2 and lastCheck.day() == now.day(): |
|
6793 # daily |
|
6794 return |
|
6795 elif period == 3 and lastCheck.daysTo(now) < 7: |
|
6796 # weekly |
|
6797 return |
|
6798 elif period == 4 and (lastCheck.daysTo(now) < |
|
6799 lastCheck.daysInMonth()): |
|
6800 # monthly |
|
6801 return |
|
6802 |
|
6803 self.__inVersionCheck = True |
|
6804 self.manualUpdatesCheck = manual |
|
6805 self.showAvailableVersions = showVersions |
|
6806 self.httpAlternative = alternative |
|
6807 url = QUrl(self.__httpAlternatives[alternative]) |
|
6808 self.__versionCheckCanceled = False |
|
6809 if manual: |
|
6810 if self.__versionCheckProgress is None: |
|
6811 self.__versionCheckProgress = E5ProgressDialog( |
|
6812 "", self.tr("&Cancel"), |
|
6813 0, len(self.__httpAlternatives), |
|
6814 self.tr("%v/%m"), self) |
|
6815 self.__versionCheckProgress.setWindowTitle( |
|
6816 self.tr("Version Check")) |
|
6817 self.__versionCheckProgress.setMinimumDuration(0) |
|
6818 self.__versionCheckProgress.canceled.connect( |
|
6819 self.__versionsDownloadCanceled) |
|
6820 self.__versionCheckProgress.setLabelText( |
|
6821 self.tr("Trying host {0}").format(url.host())) |
|
6822 self.__versionCheckProgress.setValue(alternative) |
|
6823 request = QNetworkRequest(url) |
|
6824 request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, |
|
6825 QNetworkRequest.AlwaysNetwork) |
|
6826 reply = self.__networkManager.get(request) |
|
6827 reply.finished.connect(lambda: self.__versionsDownloadDone(reply)) |
|
6828 self.__replies.append(reply) |
|
6829 else: |
|
6830 if manual: |
|
6831 E5MessageBox.warning( |
|
6832 self, |
|
6833 self.tr("Error getting versions information"), |
|
6834 self.tr("""The versions information cannot not be""" |
|
6835 """ downloaded because you are <b>offline</b>.""" |
|
6836 """ Please go online and try again.""")) |
|
6837 |
|
6838 @pyqtSlot() |
|
6839 def __versionsDownloadDone(self, reply): |
|
6840 """ |
|
6841 Private slot called, after the versions file has been downloaded |
|
6842 from the internet. |
|
6843 |
|
6844 @param reply reference to the network reply |
|
6845 @type QNetworkReply |
|
6846 """ |
|
6847 if self.__versionCheckCanceled: |
|
6848 self.__inVersionCheck = False |
|
6849 if self.__versionCheckProgress is not None: |
|
6850 self.__versionCheckProgress.reset() |
|
6851 self.__versionCheckProgress = None |
|
6852 return |
|
6853 |
|
6854 reply.deleteLater() |
|
6855 if reply in self.__replies: |
|
6856 self.__replies.remove(reply) |
|
6857 if reply.error() == QNetworkReply.NoError: |
|
6858 ioEncoding = Preferences.getSystem("IOEncoding") |
|
6859 versions = str(reply.readAll(), ioEncoding, 'replace').splitlines() |
|
6860 reply.close() |
|
6861 if reply.error() != QNetworkReply.NoError or \ |
|
6862 len(versions) == 0 or \ |
|
6863 versions[0].startswith("<"): |
|
6864 # network error or an error page |
|
6865 self.httpAlternative += 1 |
|
6866 if self.httpAlternative >= len(self.__httpAlternatives): |
|
6867 self.__inVersionCheck = False |
|
6868 if self.__versionCheckProgress is not None: |
|
6869 self.__versionCheckProgress.reset() |
|
6870 self.__versionCheckProgress = None |
|
6871 firstFailure = Preferences.Prefs.settings.value( |
|
6872 "Updates/FirstFailedCheckDate", QDate.currentDate()) |
|
6873 failedDuration = firstFailure.daysTo(QDate.currentDate()) |
|
6874 Preferences.Prefs.settings.setValue( |
|
6875 "Updates/FirstFailedCheckDate", firstFailure) |
|
6876 if self.manualUpdatesCheck: |
|
6877 E5MessageBox.warning( |
|
6878 self, |
|
6879 self.tr("Error getting versions information"), |
|
6880 self.tr("""The versions information could not be""" |
|
6881 """ downloaded.""" |
|
6882 """ Please go online and try again.""")) |
|
6883 elif failedDuration > 7: |
|
6884 E5MessageBox.warning( |
|
6885 self, |
|
6886 self.tr("Error getting versions information"), |
|
6887 self.tr("""The versions information could not be""" |
|
6888 """ downloaded for the last 7 days.""" |
|
6889 """ Please go online and try again.""")) |
|
6890 return |
|
6891 else: |
|
6892 self.performVersionCheck(self.manualUpdatesCheck, |
|
6893 self.httpAlternative, |
|
6894 self.showAvailableVersions) |
|
6895 return |
|
6896 |
|
6897 self.__inVersionCheck = False |
|
6898 if self.__versionCheckProgress is not None: |
|
6899 self.__versionCheckProgress.reset() |
|
6900 self.__versionCheckProgress = None |
|
6901 self.__updateVersionsUrls(versions) |
|
6902 if self.showAvailableVersions: |
|
6903 self.__showAvailableVersionInfos(versions) |
|
6904 else: |
|
6905 Preferences.Prefs.settings.remove("Updates/FirstFailedCheckDate") |
|
6906 Preferences.Prefs.settings.setValue( |
|
6907 "Updates/LastCheckDate", QDate.currentDate()) |
|
6908 self.__versionCheckResult(versions) |
|
6909 |
|
6910 def __updateVersionsUrls(self, versions): |
|
6911 """ |
|
6912 Private method to update the URLs from which to retrieve the versions |
|
6913 file. |
|
6914 |
|
6915 @param versions contents of the downloaded versions file (list of |
|
6916 strings) |
|
6917 """ |
|
6918 if len(versions) > 5 and versions[4] == "---": |
|
6919 line = 5 |
|
6920 urls = [] |
|
6921 while line < len(versions): |
|
6922 urls.append(versions[line]) |
|
6923 line += 1 |
|
6924 |
|
6925 Preferences.setUI("VersionsUrls6", urls) |
|
6926 |
|
6927 def __versionCheckResult(self, versions): |
|
6928 """ |
|
6929 Private method to show the result of the version check action. |
|
6930 |
|
6931 @param versions contents of the downloaded versions file (list of |
|
6932 strings) |
|
6933 """ |
|
6934 url = "" |
|
6935 try: |
|
6936 if "snapshot-" in VersionOnly: |
|
6937 # check snapshot version like snapshot-20170810 |
|
6938 if "snapshot-" in versions[2]: |
|
6939 installedSnapshotDate = VersionOnly.rsplit("-", 1)[-1] |
|
6940 availableSnapshotDate = versions[2].rsplit("-", 1)[-1] |
|
6941 if availableSnapshotDate > installedSnapshotDate: |
|
6942 res = E5MessageBox.yesNo( |
|
6943 self, |
|
6944 self.tr("Update available"), |
|
6945 self.tr( |
|
6946 """The update to <b>{0}</b> of eric6 is""" |
|
6947 """ available at <b>{1}</b>. Would you like""" |
|
6948 """ to get it?""") |
|
6949 .format(versions[2], versions[3]), |
|
6950 yesDefault=True) |
|
6951 url = res and versions[3] or '' |
|
6952 else: |
|
6953 if self.manualUpdatesCheck: |
|
6954 E5MessageBox.information( |
|
6955 self, |
|
6956 self.tr("Update Check"), |
|
6957 self.tr( |
|
6958 """You are using a snapshot release of""" |
|
6959 """ eric6. A more up-to-date stable release""" |
|
6960 """ might be available.""")) |
|
6961 elif VersionOnly.startswith(("rev_", "@@")): |
|
6962 # check installation from source |
|
6963 if self.manualUpdatesCheck: |
|
6964 E5MessageBox.information( |
|
6965 self, |
|
6966 self.tr("Update Check"), |
|
6967 self.tr( |
|
6968 """You installed eric directly from the source""" |
|
6969 """ code. There is no possibility to check""" |
|
6970 """ for the availability of an update.""")) |
|
6971 else: |
|
6972 # check release version |
|
6973 installedVersionTuple = self.__versionToTuple(VersionOnly) |
|
6974 availableVersionTuple = self.__versionToTuple(versions[0]) |
|
6975 if availableVersionTuple > installedVersionTuple: |
|
6976 res = E5MessageBox.yesNo( |
|
6977 self, |
|
6978 self.tr("Update available"), |
|
6979 self.tr( |
|
6980 """The update to <b>{0}</b> of eric6 is""" |
|
6981 """ available at <b>{1}</b>. Would you like""" |
|
6982 """ to get it?""") |
|
6983 .format(versions[0], versions[1]), |
|
6984 yesDefault=True) |
|
6985 url = res and versions[1] or '' |
|
6986 else: |
|
6987 if self.manualUpdatesCheck: |
|
6988 E5MessageBox.information( |
|
6989 self, |
|
6990 self.tr("Eric6 is up to date"), |
|
6991 self.tr( |
|
6992 """You are using the latest version of""" |
|
6993 """ eric6""")) |
|
6994 except (IndexError, TypeError): |
|
6995 E5MessageBox.warning( |
|
6996 self, |
|
6997 self.tr("Error during updates check"), |
|
6998 self.tr("""Could not perform updates check.""")) |
|
6999 |
|
7000 if url: |
|
7001 QDesktopServices.openUrl(QUrl(url)) |
|
7002 |
|
7003 @pyqtSlot() |
|
7004 def __versionsDownloadCanceled(self): |
|
7005 """ |
|
7006 Private slot called to cancel the version check. |
|
7007 """ |
|
7008 if self.__replies: |
|
7009 self.__versionCheckCanceled = True |
|
7010 self.__replies[-1].abort() |
|
7011 |
|
7012 def __showAvailableVersionInfos(self, versions): |
|
7013 """ |
|
7014 Private method to show the versions available for download. |
|
7015 |
|
7016 @param versions contents of the downloaded versions file (list of |
|
7017 strings) |
|
7018 """ |
|
7019 versionText = self.tr( |
|
7020 """<h3>Available versions</h3>""" |
|
7021 """<table>""") |
|
7022 line = 0 |
|
7023 while line < len(versions): |
|
7024 if versions[line] == "---": |
|
7025 break |
|
7026 |
|
7027 versionText += """<tr><td>{0}</td><td><a href="{1}">{2}</a>""" \ |
|
7028 """</td></tr>""".format( |
|
7029 versions[line], versions[line + 1], |
|
7030 'sourceforge' in versions[line + 1] and |
|
7031 "SourceForge" or versions[line + 1]) |
|
7032 line += 2 |
|
7033 versionText += self.tr("""</table>""") |
|
7034 |
|
7035 self.__versionsDialog = E5MessageBox.E5MessageBox( |
|
7036 E5MessageBox.NoIcon, |
|
7037 Program, |
|
7038 versionText, |
|
7039 modal=False, |
|
7040 buttons=E5MessageBox.Ok, |
|
7041 parent=self |
|
7042 ) |
|
7043 self.__versionsDialog.setIconPixmap( |
|
7044 UI.PixmapCache.getPixmap("eric.png").scaled(64, 64)) |
|
7045 self.__versionsDialog.show() |
|
7046 |
|
7047 def __sslErrors(self, reply, errors): |
|
7048 """ |
|
7049 Private slot to handle SSL errors. |
|
7050 |
|
7051 @param reply reference to the reply object (QNetworkReply) |
|
7052 @param errors list of SSL errors (list of QSslError) |
|
7053 """ |
|
7054 ignored = self.__sslErrorHandler.sslErrorsReply(reply, errors)[0] |
|
7055 if ignored == E5SslErrorHandler.NotIgnored: |
|
7056 self.__downloadCancelled = True |
|
7057 |
|
7058 ####################################### |
|
7059 ## Below are methods for various checks |
|
7060 ####################################### |
|
7061 |
|
7062 def checkConfigurationStatus(self): |
|
7063 """ |
|
7064 Public method to check, if eric6 has been configured. If it is not, |
|
7065 the configuration dialog is shown. |
|
7066 """ |
|
7067 if not Preferences.isConfigured(): |
|
7068 self.__initDebugToolbarsLayout() |
|
7069 |
|
7070 E5MessageBox.information( |
|
7071 self, |
|
7072 self.tr("First time usage"), |
|
7073 self.tr("""eric6 has not been configured yet. """ |
|
7074 """The configuration dialog will be started.""")) |
|
7075 self.showPreferences() |
|
7076 |
|
7077 def checkProjectsWorkspace(self): |
|
7078 """ |
|
7079 Public method to check, if a projects workspace has been configured. If |
|
7080 it has not, a dialog is shown. |
|
7081 """ |
|
7082 if not Preferences.isConfigured(): |
|
7083 # eric hasn't been configured at all |
|
7084 self.checkConfigurationStatus() |
|
7085 |
|
7086 workspace = Preferences.getMultiProject("Workspace") |
|
7087 if workspace == "": |
|
7088 default = Utilities.getHomeDir() |
|
7089 workspace = E5FileDialog.getExistingDirectory( |
|
7090 None, |
|
7091 self.tr("Select Workspace Directory"), |
|
7092 default, |
|
7093 E5FileDialog.Options(E5FileDialog.Option(0))) |
|
7094 Preferences.setMultiProject("Workspace", workspace) |
|
7095 |
|
7096 def versionIsNewer(self, required, snapshot=None): |
|
7097 """ |
|
7098 Public method to check, if the eric6 version is good compared to |
|
7099 the required version. |
|
7100 |
|
7101 @param required required version (string) |
|
7102 @param snapshot required snapshot version (string) |
|
7103 @return flag indicating, that the version is newer than the required |
|
7104 one (boolean) |
|
7105 """ |
|
7106 if VersionOnly.startswith("@@"): |
|
7107 # development version, always newer |
|
7108 return True |
|
7109 |
|
7110 if VersionOnly.startswith("rev_"): |
|
7111 # installed from cloned sources, always newer |
|
7112 return True |
|
7113 |
|
7114 if "snapshot-" in VersionOnly: |
|
7115 # check snapshot version |
|
7116 if snapshot is None: |
|
7117 return True |
|
7118 else: |
|
7119 vers = VersionOnly.split("snapshot-")[1] |
|
7120 return vers > snapshot |
|
7121 |
|
7122 versionTuple = self.__versionToTuple(VersionOnly) |
|
7123 if isinstance(required, str): |
|
7124 required = self.__versionToTuple(required) |
|
7125 try: |
|
7126 res = versionTuple > required |
|
7127 except TypeError: |
|
7128 # some mismatching types, assume newer |
|
7129 res = True |
|
7130 return res |
|
7131 |
|
7132 def __versionToTuple(self, version): |
|
7133 """ |
|
7134 Private method to convert a version string into a tuple. |
|
7135 |
|
7136 @param version version string |
|
7137 @type str |
|
7138 @return version tuple |
|
7139 @rtype tuple of int |
|
7140 """ |
|
7141 versionParts = [] |
|
7142 for part in version.split("."): |
|
7143 part = part.strip() |
|
7144 if part: |
|
7145 try: |
|
7146 part = int(part) |
|
7147 except ValueError: |
|
7148 # not an integer, ignore |
|
7149 continue |
|
7150 versionParts.append(part) |
|
7151 return tuple(versionParts) |
|
7152 |
|
7153 ################################# |
|
7154 ## Below are some utility methods |
|
7155 ################################# |
|
7156 |
|
7157 def __getFloatingGeometry(self, w): |
|
7158 """ |
|
7159 Private method to get the geometry of a floating windows. |
|
7160 |
|
7161 @param w reference to the widget to be saved (QWidget) |
|
7162 @return list giving the widget's geometry and its visibility |
|
7163 """ |
|
7164 s = w.size() |
|
7165 p = w.pos() |
|
7166 return [p.x(), p.y(), s.width(), s.height(), not w.isHidden()] |
|
7167 |
|
7168 def getOriginalPathString(self): |
|
7169 """ |
|
7170 Public method to get the original PATH environment variable |
|
7171 (i.e. before modifications by eric6 and PyQt5). |
|
7172 |
|
7173 @return original PATH environment variable |
|
7174 @rtype str |
|
7175 """ |
|
7176 return self.__originalPathString |
|
7177 |
|
7178 ############################ |
|
7179 ## some event handlers below |
|
7180 ############################ |
|
7181 |
|
7182 def showEvent(self, evt): |
|
7183 """ |
|
7184 Protected method to handle the show event. |
|
7185 |
|
7186 @param evt reference to the show event (QShowEvent) |
|
7187 """ |
|
7188 if self.__startup: |
|
7189 if Preferences.getGeometry("MainMaximized"): |
|
7190 self.setWindowState(Qt.WindowStates(Qt.WindowMaximized)) |
|
7191 self.__startup = False |
|
7192 |
|
7193 ########################################## |
|
7194 ## Support for desktop notifications below |
|
7195 ########################################## |
|
7196 |
|
7197 def showNotification(self, icon, heading, text, timeout=None): |
|
7198 """ |
|
7199 Public method to show a desktop notification. |
|
7200 |
|
7201 @param icon icon to be shown in the notification |
|
7202 @type QPixmap |
|
7203 @param heading heading of the notification |
|
7204 @type str |
|
7205 @param text text of the notification |
|
7206 @type str |
|
7207 @param timeout time in seconds the notification should be shown |
|
7208 (None = use configured timeout, 0 = indefinitely) |
|
7209 @type int |
|
7210 """ |
|
7211 if Preferences.getUI("NotificationsEnabled"): |
|
7212 if self.__notification is None: |
|
7213 from .NotificationWidget import NotificationWidget |
|
7214 self.__notification = NotificationWidget(parent=self) |
|
7215 self.__notification.setPixmap(icon) |
|
7216 self.__notification.setHeading(heading) |
|
7217 self.__notification.setText(text) |
|
7218 if timeout is None: |
|
7219 timeout = Preferences.getUI("NotificationTimeout") |
|
7220 self.__notification.setTimeout(timeout) |
|
7221 self.__notification.move(Preferences.getUI("NotificationPosition")) |
|
7222 self.__notification.show() |
|
7223 |
|
7224 def notificationsEnabled(self): |
|
7225 """ |
|
7226 Public method to check, if notifications are enabled. |
|
7227 |
|
7228 @return flag indicating, if notifications are enabled (boolean) |
|
7229 """ |
|
7230 return Preferences.getUI("NotificationsEnabled") |
|
7231 |
|
7232 ######################### |
|
7233 ## Support for IRC below |
|
7234 ######################### |
|
7235 |
|
7236 def autoConnectIrc(self): |
|
7237 """ |
|
7238 Public method to initiate the IRC auto connection. |
|
7239 """ |
|
7240 if self.irc is not None: |
|
7241 self.irc.autoConnect() |
|
7242 |
|
7243 def __ircAutoConnected(self): |
|
7244 """ |
|
7245 Private slot handling the automatic connection of the IRC client. |
|
7246 """ |
|
7247 self.__activateIRC() |
|
7248 |
|
7249 ############################################### |
|
7250 ## Support for Code Documentation Viewer below |
|
7251 ############################################### |
|
7252 |
|
7253 def documentationViewer(self): |
|
7254 """ |
|
7255 Public method to provide a reference to the code documentation viewer. |
|
7256 |
|
7257 @return reference to the code documentation viewer |
|
7258 @rtype CodeDocumentationViewer |
|
7259 """ |
|
7260 return self.codeDocumentationViewer |