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