|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2006 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a starter for the system tray. |
|
8 """ |
|
9 |
|
10 import sys |
|
11 import os |
|
12 |
|
13 from PyQt4.QtCore import SIGNAL, QProcess, QSettings, QFileInfo, QVariant |
|
14 from PyQt4.QtGui import QSystemTrayIcon, QMenu, qApp, QCursor, QMessageBox |
|
15 |
|
16 import Globals |
|
17 import UI.PixmapCache |
|
18 |
|
19 import Utilities |
|
20 |
|
21 from eric4config import getConfig |
|
22 |
|
23 class TrayStarter(QSystemTrayIcon): |
|
24 """ |
|
25 Class implementing a starter for the system tray. |
|
26 """ |
|
27 def __init__(self): |
|
28 """ |
|
29 Constructor |
|
30 """ |
|
31 QSystemTrayIcon.__init__(self, UI.PixmapCache.getIcon("erict.png")) |
|
32 |
|
33 self.maxMenuFilePathLen = 75 |
|
34 |
|
35 self.rsettings = QSettings(QSettings.IniFormat, |
|
36 QSettings.UserScope, |
|
37 Globals.settingsNameOrganization, |
|
38 Globals.settingsNameRecent) |
|
39 |
|
40 self.recentProjects = [] |
|
41 self.__loadRecentProjects() |
|
42 self.recentMultiProjects = [] |
|
43 self.__loadRecentMultiProjects() |
|
44 self.recentFiles = [] |
|
45 self.__loadRecentFiles() |
|
46 |
|
47 self.connect(self, SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), |
|
48 self.__activated) |
|
49 |
|
50 self.__menu = QMenu(self.trUtf8("Eric4 tray starter")) |
|
51 |
|
52 self.recentProjectsMenu = QMenu(self.trUtf8('Recent Projects'), self.__menu) |
|
53 self.connect(self.recentProjectsMenu, SIGNAL('aboutToShow()'), |
|
54 self.__showRecentProjectsMenu) |
|
55 self.connect(self.recentProjectsMenu, SIGNAL('triggered(QAction *)'), |
|
56 self.__openRecent) |
|
57 |
|
58 self.recentMultiProjectsMenu = \ |
|
59 QMenu(self.trUtf8('Recent Multiprojects'), self.__menu) |
|
60 self.connect(self.recentMultiProjectsMenu, SIGNAL('aboutToShow()'), |
|
61 self.__showRecentMultiProjectsMenu) |
|
62 self.connect(self.recentMultiProjectsMenu, SIGNAL('triggered(QAction *)'), |
|
63 self.__openRecent) |
|
64 |
|
65 self.recentFilesMenu = QMenu(self.trUtf8('Recent Files'), self.__menu) |
|
66 self.connect(self.recentFilesMenu, SIGNAL('aboutToShow()'), |
|
67 self.__showRecentFilesMenu) |
|
68 self.connect(self.recentFilesMenu, SIGNAL('triggered(QAction *)'), |
|
69 self.__openRecent) |
|
70 |
|
71 act = self.__menu.addAction(self.trUtf8("Eric4 tray starter")) |
|
72 font = act.font() |
|
73 font.setBold(True) |
|
74 act.setFont(font) |
|
75 self.__menu.addSeparator() |
|
76 |
|
77 self.__menu.addAction(self.trUtf8("QRegExp editor"), self.__startQRegExp) |
|
78 self.__menu.addAction(self.trUtf8("Python re editor"), self.__startPyRe) |
|
79 self.__menu.addSeparator() |
|
80 |
|
81 self.__menu.addAction(UI.PixmapCache.getIcon("uiPreviewer.png"), |
|
82 self.trUtf8("UI Previewer"), self.__startUIPreviewer) |
|
83 self.__menu.addAction(UI.PixmapCache.getIcon("trPreviewer.png"), |
|
84 self.trUtf8("Translations Previewer"), self.__startTRPreviewer) |
|
85 self.__menu.addAction(UI.PixmapCache.getIcon("unittest.png"), |
|
86 self.trUtf8("Unittest"), self.__startUnittest) |
|
87 self.__menu.addAction(UI.PixmapCache.getIcon("ericWeb.png"), |
|
88 self.trUtf8("Web Browser"), self.__startHelpViewer) |
|
89 self.__menu.addSeparator() |
|
90 |
|
91 self.__menu.addAction(UI.PixmapCache.getIcon("diffFiles.png"), |
|
92 self.trUtf8("Compare Files"), self.__startDiff) |
|
93 self.__menu.addAction(UI.PixmapCache.getIcon("compareFiles.png"), |
|
94 self.trUtf8("Compare Files side by side"), self.__startCompare) |
|
95 self.__menu.addSeparator() |
|
96 |
|
97 self.__menu.addAction(UI.PixmapCache.getIcon("sqlBrowser.png"), |
|
98 self.trUtf8("SQL Browser"), self.__startSqlBrowser) |
|
99 self.__menu.addSeparator() |
|
100 |
|
101 self.__menu.addAction(UI.PixmapCache.getIcon("pluginInstall.png"), |
|
102 self.trUtf8("Install Plugin"), self.__startPluginInstall) |
|
103 self.__menu.addAction(UI.PixmapCache.getIcon("pluginUninstall.png"), |
|
104 self.trUtf8("Uninstall Plugin"), self.__startPluginUninstall) |
|
105 self.__menu.addAction(UI.PixmapCache.getIcon("pluginRepository.png"), |
|
106 self.trUtf8("Plugin Repository"), self.__startPluginRepository) |
|
107 self.__menu.addSeparator() |
|
108 |
|
109 self.__menu.addAction(UI.PixmapCache.getIcon("configure.png"), |
|
110 self.trUtf8('Preferences'), self.__startPreferences) |
|
111 self.__menu.addAction(UI.PixmapCache.getIcon("erict.png"), |
|
112 self.trUtf8("eric4 IDE"), self.__startEric) |
|
113 self.__menu.addAction(UI.PixmapCache.getIcon("editor.png"), |
|
114 self.trUtf8("eric4 Mini Editor"), self.__startMiniEditor) |
|
115 self.__menu.addSeparator() |
|
116 |
|
117 # recent files |
|
118 self.menuRecentFilesAct = self.__menu.addMenu(self.recentFilesMenu) |
|
119 # recent multi projects |
|
120 self.menuRecentMultiProjectsAct = \ |
|
121 self.__menu.addMenu(self.recentMultiProjectsMenu) |
|
122 # recent projects |
|
123 self.menuRecentProjectsAct = self.__menu.addMenu(self.recentProjectsMenu) |
|
124 self.__menu.addSeparator() |
|
125 |
|
126 self.__menu.addAction(UI.PixmapCache.getIcon("exit.png"), |
|
127 self.trUtf8('Quit'), qApp.quit) |
|
128 |
|
129 def __loadRecentProjects(self): |
|
130 """ |
|
131 Private method to load the recently opened project filenames. |
|
132 """ |
|
133 rp = self.rsettings.value(Globals.recentNameProject) |
|
134 if rp.isValid(): |
|
135 for f in rp.toStringList(): |
|
136 if QFileInfo(f).exists(): |
|
137 self.recentProjects.append(f) |
|
138 |
|
139 def __loadRecentMultiProjects(self): |
|
140 """ |
|
141 Private method to load the recently opened multi project filenames. |
|
142 """ |
|
143 rmp = self.rsettings.value(Globals.recentNameMultiProject) |
|
144 if rmp.isValid(): |
|
145 for f in rmp.toStringList(): |
|
146 if QFileInfo(f).exists(): |
|
147 self.recentMultiProjects.append(f) |
|
148 |
|
149 def __loadRecentFiles(self): |
|
150 """ |
|
151 Private method to load the recently opened filenames. |
|
152 """ |
|
153 rf = self.rsettings.value(Globals.recentNameFiles) |
|
154 if rf.isValid(): |
|
155 for f in rf.toStringList(): |
|
156 if QFileInfo(f).exists(): |
|
157 self.recentFiles.append(f) |
|
158 |
|
159 def __activated(self, reason): |
|
160 """ |
|
161 Private slot to handle the activated signal. |
|
162 |
|
163 @param reason reason code of the signal (QSystemTrayIcon.ActivationReason) |
|
164 """ |
|
165 if reason == QSystemTrayIcon.Context or \ |
|
166 reason == QSystemTrayIcon.MiddleClick: |
|
167 self.__showContextMenu() |
|
168 elif reason == QSystemTrayIcon.DoubleClick: |
|
169 self.__startEric() |
|
170 |
|
171 def __showContextMenu(self): |
|
172 """ |
|
173 Private slot to show the context menu. |
|
174 """ |
|
175 self.menuRecentProjectsAct.setEnabled(len(self.recentProjects) > 0) |
|
176 self.menuRecentMultiProjectsAct.setEnabled(len(self.recentMultiProjects) > 0) |
|
177 self.menuRecentFilesAct.setEnabled(len(self.recentFiles) > 0) |
|
178 |
|
179 pos = QCursor.pos() |
|
180 x = pos.x() - self.__menu.sizeHint().width() |
|
181 pos.setX(x > 0 and x or 0) |
|
182 y = pos.y() - self.__menu.sizeHint().height() |
|
183 pos.setY(y > 0 and y or 0) |
|
184 self.__menu.popup(pos) |
|
185 |
|
186 def __startProc(self, applName, *applArgs): |
|
187 """ |
|
188 Private method to start an eric4 application. |
|
189 |
|
190 @param applName name of the eric4 application script (string) |
|
191 @param *applArgs variable list of application arguments |
|
192 """ |
|
193 proc = QProcess() |
|
194 applPath = os.path.join(getConfig("ericDir"), applName) |
|
195 |
|
196 args = [] |
|
197 args.append(applPath) |
|
198 for arg in applArgs: |
|
199 args.append(arg) |
|
200 |
|
201 if not os.path.isfile(applPath) or not proc.startDetached(sys.executable, args): |
|
202 QMessageBox.critical(self, |
|
203 self.trUtf8('Process Generation Error'), |
|
204 self.trUtf8( |
|
205 '<p>Could not start the process.<br>' |
|
206 'Ensure that it is available as <b>{0}</b>.</p>' |
|
207 ).format(applPath), |
|
208 self.trUtf8('OK')) |
|
209 |
|
210 def __startMiniEditor(self): |
|
211 """ |
|
212 Private slot to start the eric4 Mini Editor. |
|
213 """ |
|
214 self.__startProc("eric4-editor.py", "--config=%s" % Utilities.getConfigDir()) |
|
215 |
|
216 def __startEric(self): |
|
217 """ |
|
218 Private slot to start the eric4 IDE. |
|
219 """ |
|
220 self.__startProc("eric4.py", "--config=%s" % Utilities.getConfigDir()) |
|
221 |
|
222 def __startPreferences(self): |
|
223 """ |
|
224 Private slot to start the eric4 configuration dialog. |
|
225 """ |
|
226 self.__startProc("eric4-configure.py", "--config=%s" % Utilities.getConfigDir()) |
|
227 |
|
228 def __startPluginInstall(self): |
|
229 """ |
|
230 Private slot to start the eric4 plugin installation dialog. |
|
231 """ |
|
232 self.__startProc("eric4-plugininstall.py", |
|
233 "--config=%s" % Utilities.getConfigDir()) |
|
234 |
|
235 def __startPluginUninstall(self): |
|
236 """ |
|
237 Private slot to start the eric4 plugin uninstallation dialog. |
|
238 """ |
|
239 self.__startProc("eric4-pluginuninstall.py", |
|
240 "--config=%s" % Utilities.getConfigDir()) |
|
241 |
|
242 def __startPluginRepository(self): |
|
243 """ |
|
244 Private slot to start the eric4 plugin repository dialog. |
|
245 """ |
|
246 self.__startProc("eric4-pluginrepository.py", |
|
247 "--config=%s" % Utilities.getConfigDir()) |
|
248 |
|
249 def __startHelpViewer(self): |
|
250 """ |
|
251 Private slot to start the eric4 web browser. |
|
252 """ |
|
253 self.__startProc("eric4-webbrowser.py", "--config=%s" % Utilities.getConfigDir()) |
|
254 |
|
255 def __startUIPreviewer(self): |
|
256 """ |
|
257 Private slot to start the eric4 UI previewer. |
|
258 """ |
|
259 self.__startProc("eric4-uipreviewer.py", "--config=%s" % Utilities.getConfigDir()) |
|
260 |
|
261 def __startTRPreviewer(self): |
|
262 """ |
|
263 Private slot to start the eric4 translations previewer. |
|
264 """ |
|
265 self.__startProc("eric4-trpreviewer.py", "--config=%s" % Utilities.getConfigDir()) |
|
266 |
|
267 def __startUnittest(self): |
|
268 """ |
|
269 Private slot to start the eric4 unittest dialog. |
|
270 """ |
|
271 self.__startProc("eric4-unittest.py", "--config=%s" % Utilities.getConfigDir()) |
|
272 |
|
273 def __startDiff(self): |
|
274 """ |
|
275 Private slot to start the eric4 diff dialog. |
|
276 """ |
|
277 self.__startProc("eric4-diff.py", "--config=%s" % Utilities.getConfigDir()) |
|
278 |
|
279 def __startCompare(self): |
|
280 """ |
|
281 Private slot to start the eric4 compare dialog. |
|
282 """ |
|
283 self.__startProc("eric4-compare.py", "--config=%s" % Utilities.getConfigDir()) |
|
284 |
|
285 def __startSqlBrowser(self): |
|
286 """ |
|
287 Private slot to start the eric4 sql browser dialog. |
|
288 """ |
|
289 self.__startProc("eric4-sqlbrowser.py", "--config=%s" % Utilities.getConfigDir()) |
|
290 |
|
291 def __startQRegExp(self): |
|
292 """ |
|
293 Private slot to start the eric4 QRegExp editor dialog. |
|
294 """ |
|
295 self.__startProc("eric4-qregexp.py", "--config=%s" % Utilities.getConfigDir()) |
|
296 |
|
297 def __startPyRe(self): |
|
298 """ |
|
299 Private slot to start the eric4 Python re editor dialog. |
|
300 """ |
|
301 self.__startProc("eric4-re.py", "--config=%s" % Utilities.getConfigDir()) |
|
302 |
|
303 def __showRecentProjectsMenu(self): |
|
304 """ |
|
305 Private method to set up the recent projects menu. |
|
306 """ |
|
307 self.recentProjects = [] |
|
308 self.rsettings.sync() |
|
309 self.__loadRecentProjects() |
|
310 |
|
311 self.recentProjectsMenu.clear() |
|
312 |
|
313 idx = 1 |
|
314 for rp in self.recentProjects: |
|
315 if idx < 10: |
|
316 formatStr = '&%d. %s' |
|
317 else: |
|
318 formatStr = '%d. %s' |
|
319 act = self.recentProjectsMenu.addAction( |
|
320 formatStr % (idx, |
|
321 Utilities.compactPath(rp, self.maxMenuFilePathLen))) |
|
322 act.setData(QVariant(rp)) |
|
323 idx += 1 |
|
324 |
|
325 def __showRecentMultiProjectsMenu(self): |
|
326 """ |
|
327 Private method to set up the recent multi projects menu. |
|
328 """ |
|
329 self.recentMultiProjects = [] |
|
330 self.rsettings.sync() |
|
331 self.__loadRecentMultiProjects() |
|
332 |
|
333 self.recentMultiProjectsMenu.clear() |
|
334 |
|
335 idx = 1 |
|
336 for rmp in self.recentMultiProjects: |
|
337 if idx < 10: |
|
338 formatStr = '&%d. %s' |
|
339 else: |
|
340 formatStr = '%d. %s' |
|
341 act = self.recentMultiProjectsMenu.addAction( |
|
342 formatStr % (idx, |
|
343 Utilities.compactPath(rmp, self.maxMenuFilePathLen))) |
|
344 act.setData(QVariant(rmp)) |
|
345 idx += 1 |
|
346 |
|
347 def __showRecentFilesMenu(self): |
|
348 """ |
|
349 Private method to set up the recent files menu. |
|
350 """ |
|
351 self.recentFiles = [] |
|
352 self.rsettings.sync() |
|
353 self.__loadRecentFiles() |
|
354 |
|
355 self.recentFilesMenu.clear() |
|
356 |
|
357 idx = 1 |
|
358 for rf in self.recentFiles: |
|
359 if idx < 10: |
|
360 formatStr = '&%d. %s' |
|
361 else: |
|
362 formatStr = '%d. %s' |
|
363 act = self.recentFilesMenu.addAction(\ |
|
364 formatStr % (idx, |
|
365 Utilities.compactPath(rf, self.maxMenuFilePathLen))) |
|
366 act.setData(QVariant(rf)) |
|
367 idx += 1 |
|
368 |
|
369 def __openRecent(self, act): |
|
370 """ |
|
371 Private method to open a project or file from the list of rencently opened |
|
372 projects or files. |
|
373 |
|
374 @param act reference to the action that triggered (QAction) |
|
375 """ |
|
376 filename = act.data().toString() |
|
377 if filename: |
|
378 self.__startProc("eric4.py", filename) |