|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2006 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the Programs page. |
|
8 """ |
|
9 |
|
10 import os |
|
11 import sys |
|
12 import re |
|
13 |
|
14 from PyQt4.QtCore import pyqtSlot, Qt, QProcess |
|
15 from PyQt4.QtGui import QApplication, QTreeWidgetItem, QHeaderView, QCursor, \ |
|
16 QDialog, QDialogButtonBox |
|
17 |
|
18 from E4Gui.E4Application import e4App |
|
19 |
|
20 from Ui_ProgramsDialog import Ui_ProgramsDialog |
|
21 |
|
22 import Preferences |
|
23 import Utilities |
|
24 |
|
25 class ProgramsDialog(QDialog, Ui_ProgramsDialog): |
|
26 """ |
|
27 Class implementing the Programs page. |
|
28 """ |
|
29 def __init__(self, parent = None): |
|
30 """ |
|
31 Constructor |
|
32 |
|
33 @param parent The parent widget of this dialog. (QWidget) |
|
34 """ |
|
35 QDialog.__init__(self, parent) |
|
36 self.setupUi(self) |
|
37 self.setObjectName("ProgramsDialog") |
|
38 |
|
39 self.__hasSearched = False |
|
40 |
|
41 self.programsList.headerItem().setText(self.programsList.columnCount(), "") |
|
42 |
|
43 self.searchButton = \ |
|
44 self.buttonBox.addButton(self.trUtf8("Search"), QDialogButtonBox.ActionRole) |
|
45 self.searchButton.setToolTip(self.trUtf8("Press to search for programs")) |
|
46 |
|
47 def show(self): |
|
48 """ |
|
49 Public slot to show the dialog. |
|
50 """ |
|
51 QDialog.show(self) |
|
52 if not self.__hasSearched: |
|
53 self.on_programsSearchButton_clicked() |
|
54 |
|
55 def on_buttonBox_clicked(self, button): |
|
56 """ |
|
57 Private slot called by a button of the button box clicked. |
|
58 |
|
59 @param button button that was clicked (QAbstractButton) |
|
60 """ |
|
61 if button == self.searchButton: |
|
62 self.on_programsSearchButton_clicked() |
|
63 |
|
64 @pyqtSlot() |
|
65 def on_programsSearchButton_clicked(self): |
|
66 """ |
|
67 Private slot to search for all supported/required programs. |
|
68 """ |
|
69 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) |
|
70 QApplication.processEvents() |
|
71 |
|
72 self.programsList.clear() |
|
73 header = self.programsList.header() |
|
74 header.setSortIndicator(0, Qt.AscendingOrder) |
|
75 header.setSortIndicatorShown(False) |
|
76 |
|
77 # 1. do the Qt4 programs |
|
78 # 1a. Translation Converter |
|
79 exe = Utilities.isWindowsPlatform() and \ |
|
80 "%s.exe" % Utilities.generateQtToolName("lrelease") or \ |
|
81 Utilities.generateQtToolName("lrelease") |
|
82 version = self.__createProgramEntry(self.trUtf8("Translation Converter (Qt4)"), |
|
83 exe, '-version', 'lrelease', -1) |
|
84 # 1b. Qt4 Designer |
|
85 exe = Utilities.isWindowsPlatform() and \ |
|
86 "%s.exe" % Utilities.generateQtToolName("designer") or \ |
|
87 Utilities.generateQtToolName("designer") |
|
88 self.__createProgramEntry(self.trUtf8("Qt4 Designer"), exe, version = version) |
|
89 # 1c. Qt4 Linguist |
|
90 exe = Utilities.isWindowsPlatform() and \ |
|
91 "%s.exe" % Utilities.generateQtToolName("linguist") or \ |
|
92 Utilities.generateQtToolName("linguist") |
|
93 self.__createProgramEntry(self.trUtf8("Qt4 Linguist"), exe, version = version) |
|
94 # 1d. Qt4 Assistant |
|
95 exe = Utilities.isWindowsPlatform() and \ |
|
96 "%s.exe" % Utilities.generateQtToolName("assistant") or \ |
|
97 Utilities.generateQtToolName("assistant") |
|
98 self.__createProgramEntry(self.trUtf8("Qt4 Assistant"), exe, version = version) |
|
99 |
|
100 # 2. do the PyQt programs |
|
101 # 2a. Translation Extractor PyQt4 |
|
102 self.__createProgramEntry(self.trUtf8("Translation Extractor (Python, Qt4)"), |
|
103 Utilities.isWindowsPlatform() and "pylupdate4.exe" or "pylupdate4", |
|
104 '-version', 'pylupdate', -1) |
|
105 # 2b. Forms Compiler PyQt4 |
|
106 self.__createProgramEntry(self.trUtf8("Forms Compiler (Python, Qt4)"), |
|
107 Utilities.isWindowsPlatform() and "pyuic4.bat" or "pyuic4", |
|
108 '--version', 'Python User', 4) |
|
109 # 2c. Resource Compiler PyQt4 |
|
110 self.__createProgramEntry(self.trUtf8("Resource Compiler (Python, Qt4)"), |
|
111 Utilities.isWindowsPlatform() and "pyrcc4.exe" or "pyrcc4", |
|
112 '-version', 'Resource Compiler', -1) |
|
113 |
|
114 # 3. do the PySide programs |
|
115 # 3a. Translation Extractor PySide |
|
116 self.__createProgramEntry(self.trUtf8("Translation Extractor (Python, PySide)"), |
|
117 Utilities.isWindowsPlatform() and "pyside-lupdate.exe" or "pyside-lupdate", |
|
118 '-version', '', -1, versionRe = 'lupdate') |
|
119 # 3b. Forms Compiler PySide |
|
120 self.__createProgramEntry(self.trUtf8("Forms Compiler (Python, PySide)"), |
|
121 Utilities.isWindowsPlatform() and "pyside-uic.bat" or "pyside-uic", |
|
122 '--version', 'Python User', 4) |
|
123 # 3.c Resource Compiler PySide |
|
124 self.__createProgramEntry(self.trUtf8("Resource Compiler (Python, PySide)"), |
|
125 Utilities.isWindowsPlatform() and "pyside-rcc4.exe" or "pyside-rcc4", |
|
126 '-version', 'Resource Compiler', -1) |
|
127 |
|
128 # 4. do the Ruby programs |
|
129 # 4a. Forms Compiler for Qt4 |
|
130 self.__createProgramEntry(self.trUtf8("Forms Compiler (Ruby, Qt4)"), |
|
131 Utilities.isWindowsPlatform() and "rbuic4.exe" or "rbuic4", |
|
132 '-version', 'Qt', -1) |
|
133 # 4b. Resource Compiler for Qt4 |
|
134 self.__createProgramEntry(self.trUtf8("Resource Compiler (Ruby, Qt4)"), |
|
135 Utilities.isWindowsPlatform() and "rbrcc.exe" or "rbrcc", |
|
136 '-version', 'Ruby Resource Compiler', -1) |
|
137 |
|
138 # 5. do the Eric4 programs |
|
139 # 5a. Translation Previewer |
|
140 self.__createProgramEntry(self.trUtf8("Eric4 Translation Previewer"), |
|
141 Utilities.isWindowsPlatform() and "eric4-trpreviewer.bat" or "eric4-trpreviewer", |
|
142 '--version', 'Eric4', -2) |
|
143 # 5b. Forms Previewer |
|
144 self.__createProgramEntry(self.trUtf8("Eric4 Forms Previewer"), |
|
145 Utilities.isWindowsPlatform() and "eric4-uipreviewer.bat" or "eric4-uipreviewer", |
|
146 '--version', 'Eric4', -2) |
|
147 |
|
148 # 6. do the CORBA programs |
|
149 # 6a. omniORB |
|
150 exe = unicode(Preferences.getCorba("omniidl")) |
|
151 if Utilities.isWindowsPlatform(): |
|
152 exe += ".exe" |
|
153 self.__createProgramEntry(self.trUtf8("CORBA IDL Compiler"), exe, |
|
154 '-V', 'omniidl', -1) |
|
155 |
|
156 # 7. do the spell checking entry |
|
157 try: |
|
158 import enchant |
|
159 try: |
|
160 text = os.path.dirname(enchant.__file__) |
|
161 except AttributeError: |
|
162 text = "enchant" |
|
163 try: |
|
164 version = enchant.__version__ |
|
165 except AttributeError: |
|
166 version = self.trUtf8("(unknown)") |
|
167 except (ImportError, AttributeError, OSError): |
|
168 text = "enchant" |
|
169 version = "" |
|
170 self.__createEntry(self.trUtf8("Spell Checker - PyEnchant"), text, version) |
|
171 |
|
172 # do the plugin related programs |
|
173 pm = e4App().getObject("PluginManager") |
|
174 for info in pm.getPluginExeDisplayData(): |
|
175 if info["programEntry"]: |
|
176 self.__createProgramEntry( |
|
177 info["header"], |
|
178 info["exe"], |
|
179 versionCommand = info["versionCommand"], |
|
180 versionStartsWith = info["versionStartsWith"], |
|
181 versionPosition = info["versionPosition"], |
|
182 version = info["version"], |
|
183 versionCleanup = info["versionCleanup"], |
|
184 ) |
|
185 else: |
|
186 self.__createEntry( |
|
187 info["header"], |
|
188 info["text"], |
|
189 info["version"] |
|
190 ) |
|
191 |
|
192 self.programsList.sortByColumn(0, Qt.AscendingOrder) |
|
193 QApplication.restoreOverrideCursor() |
|
194 |
|
195 self.__hasSearched = True |
|
196 |
|
197 def __createProgramEntry(self, description, exe, |
|
198 versionCommand = "", versionStartsWith = "", |
|
199 versionPosition = 0, version = "", |
|
200 versionCleanup = None, versionRe = None): |
|
201 """ |
|
202 Private method to generate a program entry. |
|
203 |
|
204 @param description descriptive text (string) |
|
205 @param exe name of the executable program (string) |
|
206 @param versionCommand command line switch to get the version info (string) |
|
207 if this is empty, the given version will be shown. |
|
208 @param versionStartsWith start of line identifying version info (string) |
|
209 @param versionPosition index of part containing the version info (integer) |
|
210 @keyparam version version string to show (string) |
|
211 @keyparam versionCleanup tuple of two integers giving string positions |
|
212 start and stop for the version string (tuple of integers) |
|
213 @keyparam versionRe regexp to determine the line identifying version |
|
214 info (string). Takes precedence over versionStartsWith. |
|
215 @return version string of detected or given version (string) |
|
216 """ |
|
217 itm = QTreeWidgetItem(self.programsList, [description]) |
|
218 font = itm.font(0) |
|
219 font.setBold(True) |
|
220 itm.setFont(0, font) |
|
221 if not exe: |
|
222 itm.setText(1, self.trUtf8("(not configured)")) |
|
223 else: |
|
224 if os.path.isabs(exe): |
|
225 if not Utilities.isExecutable(exe): |
|
226 exe = "" |
|
227 else: |
|
228 exe = Utilities.getExecutablePath(exe) |
|
229 if exe: |
|
230 if versionCommand and versionStartsWith and versionPosition: |
|
231 proc = QProcess() |
|
232 proc.setProcessChannelMode(QProcess.MergedChannels) |
|
233 proc.start(exe, [versionCommand]) |
|
234 finished = proc.waitForFinished(10000) |
|
235 if finished: |
|
236 output = \ |
|
237 unicode(proc.readAllStandardOutput(), |
|
238 Preferences.getSystem("IOEncoding"), |
|
239 'replace') |
|
240 if versionRe is None: |
|
241 versionRe = "^%s" % re.escape(versionStartsWith) |
|
242 versionRe = re.compile(versionRe, re.UNICODE) |
|
243 for line in output.splitlines(): |
|
244 if versionRe.search(line): |
|
245 version = line.split()[versionPosition] |
|
246 if versionCleanup: |
|
247 version = version[versionCleanup[0]:versionCleanup[1]] |
|
248 break |
|
249 else: |
|
250 version = self.trUtf8("(not executable)") |
|
251 itm2 = QTreeWidgetItem(itm, [exe, version]) |
|
252 itm.setExpanded(True) |
|
253 else: |
|
254 itm.setText(1, self.trUtf8("(not found)")) |
|
255 QApplication.processEvents() |
|
256 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
|
257 self.programsList.header().setStretchLastSection(True) |
|
258 return version |
|
259 |
|
260 def __createEntry(self, description, entryText, entryVersion): |
|
261 """ |
|
262 Private method to generate a program entry. |
|
263 |
|
264 @param description descriptive text (string) |
|
265 @param entryText text to show (string) |
|
266 @param entryVersion version string to show (string). |
|
267 """ |
|
268 itm = QTreeWidgetItem(self.programsList, [description]) |
|
269 font = itm.font(0) |
|
270 font.setBold(True) |
|
271 itm.setFont(0, font) |
|
272 |
|
273 if len(entryVersion): |
|
274 itm2 = QTreeWidgetItem(itm, [entryText, entryVersion]) |
|
275 itm.setExpanded(True) |
|
276 else: |
|
277 itm.setText(1, self.trUtf8("(not found)")) |
|
278 QApplication.processEvents() |
|
279 self.programsList.header().resizeSections(QHeaderView.ResizeToContents) |
|
280 self.programsList.header().setStretchLastSection(True) |