|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2002 - 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a configuration dialog for the tools menu. |
|
8 """ |
|
9 |
|
10 import sys |
|
11 import os |
|
12 import copy |
|
13 |
|
14 from PyQt4.QtCore import * |
|
15 from PyQt4.QtGui import * |
|
16 |
|
17 from E4Gui.E4Completers import E4FileCompleter |
|
18 |
|
19 from Ui_ToolConfigurationDialog import Ui_ToolConfigurationDialog |
|
20 import Utilities |
|
21 |
|
22 class ToolConfigurationDialog(QDialog, Ui_ToolConfigurationDialog): |
|
23 """ |
|
24 Class implementing a configuration dialog for the tools menu. |
|
25 """ |
|
26 def __init__(self, toollist, parent=None): |
|
27 """ |
|
28 Constructor |
|
29 |
|
30 @param toollist list of configured tools |
|
31 @param parent parent widget (QWidget) |
|
32 """ |
|
33 QDialog.__init__(self, parent) |
|
34 self.setupUi(self) |
|
35 |
|
36 self.iconCompleter = E4FileCompleter(self.iconEdit) |
|
37 self.executableCompleter = E4FileCompleter(self.executableEdit) |
|
38 |
|
39 self.redirectionModes = [ |
|
40 ("no", self.trUtf8("no redirection")), |
|
41 ("show", self.trUtf8("show output")), |
|
42 ("insert", self.trUtf8("insert into current editor")), |
|
43 ("replaceSelection", self.trUtf8("replace selection of current editor")), |
|
44 ] |
|
45 |
|
46 self.toollist = copy.deepcopy(toollist) |
|
47 for tool in toollist: |
|
48 self.toolsList.addItem(tool['menutext']) |
|
49 |
|
50 for mode in self.redirectionModes: |
|
51 self.redirectCombo.addItem(mode[1]) |
|
52 |
|
53 if len(toollist): |
|
54 self.toolsList.setCurrentRow(0) |
|
55 self.on_toolsList_currentRowChanged(0) |
|
56 |
|
57 t = self.argumentsEdit.whatsThis() |
|
58 if t: |
|
59 t += Utilities.getPercentReplacementHelp() |
|
60 self.argumentsEdit.setWhatsThis(t) |
|
61 |
|
62 def __findModeIndex(self, shortName): |
|
63 """ |
|
64 Private method to find the mode index by its short name. |
|
65 |
|
66 @param shortName short name of the mode (string) |
|
67 @return index of the mode (integer) |
|
68 """ |
|
69 ind = 0 |
|
70 for mode in self.redirectionModes: |
|
71 if mode[0] == shortName: |
|
72 return ind |
|
73 ind += 1 |
|
74 return 1 # default is "show output" |
|
75 |
|
76 @pyqtSlot() |
|
77 def on_newButton_clicked(self): |
|
78 """ |
|
79 Private slot to clear all entry fields. |
|
80 """ |
|
81 self.executableEdit.clear() |
|
82 self.menuEdit.clear() |
|
83 self.iconEdit.clear() |
|
84 self.argumentsEdit.clear() |
|
85 self.redirectCombo.setCurrentIndex(1) |
|
86 |
|
87 @pyqtSlot() |
|
88 def on_addButton_clicked(self): |
|
89 """ |
|
90 Private slot to add a new entry. |
|
91 """ |
|
92 menutext = self.menuEdit.text() |
|
93 icon = self.iconEdit.text() |
|
94 executable = self.executableEdit.text() |
|
95 arguments = self.argumentsEdit.text() |
|
96 redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0] |
|
97 |
|
98 if not executable: |
|
99 QMessageBox.critical(self, |
|
100 self.trUtf8("Add tool entry"), |
|
101 self.trUtf8("You have to set an executable to add to the" |
|
102 " Tools-Menu first.")) |
|
103 return |
|
104 |
|
105 if not menutext: |
|
106 QMessageBox.critical(self, |
|
107 self.trUtf8("Add tool entry"), |
|
108 self.trUtf8("You have to insert a menuentry text to add the" |
|
109 " selected program to the Tools-Menu first.")) |
|
110 return |
|
111 |
|
112 if not Utilities.isinpath(executable): |
|
113 QMessageBox.critical(self, |
|
114 self.trUtf8("Add tool entry"), |
|
115 self.trUtf8("The selected file could not be found or" |
|
116 " is not an executable." |
|
117 " Please choose an executable filename.")) |
|
118 return |
|
119 |
|
120 if len(self.toolsList.findItems(menutext, Qt.MatchFlags(Qt.MatchExactly))): |
|
121 QMessageBox.critical(self, |
|
122 self.trUtf8("Add tool entry"), |
|
123 self.trUtf8("An entry for the menu text {0} already exists.")\ |
|
124 .format(menutext)) |
|
125 return |
|
126 |
|
127 self.toolsList.addItem(menutext) |
|
128 tool = { |
|
129 'menutext' : unicode(menutext), |
|
130 'icon' : unicode(icon), |
|
131 'executable' : executable, |
|
132 'arguments' : unicode(arguments), |
|
133 'redirect' : redirect, |
|
134 } |
|
135 self.toollist.append(tool) |
|
136 |
|
137 @pyqtSlot() |
|
138 def on_changeButton_clicked(self): |
|
139 """ |
|
140 Private slot to change an entry. |
|
141 """ |
|
142 row = self.toolsList.currentRow() |
|
143 if row < 0: |
|
144 return |
|
145 |
|
146 menutext = self.menuEdit.text() |
|
147 icon = self.iconEdit.text() |
|
148 executable = self.executableEdit.text() |
|
149 arguments = self.argumentsEdit.text() |
|
150 redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0] |
|
151 |
|
152 if not executable: |
|
153 QMessageBox.critical(self, |
|
154 self.trUtf8("Change tool entry"), |
|
155 self.trUtf8("You have to set an executable to change the" |
|
156 " Tools-Menu entry.")) |
|
157 return |
|
158 |
|
159 if not menutext: |
|
160 QMessageBox.critical(self, |
|
161 self.trUtf8("Change tool entry"), |
|
162 self.trUtf8("You have to insert a menuentry text to change the" |
|
163 " selected Tools-Menu entry.")) |
|
164 return |
|
165 |
|
166 if not Utilities.isinpath(executable): |
|
167 QMessageBox.critical(self, |
|
168 self.trUtf8("Change tool entry"), |
|
169 self.trUtf8("The selected file could not be found or" |
|
170 " is not an executable." |
|
171 " Please choose an existing executable filename.")) |
|
172 return |
|
173 |
|
174 self.toollist[row] = { |
|
175 'menutext' : menutext, |
|
176 'icon' : icon, |
|
177 'executable' : executable, |
|
178 'arguments' : arguments, |
|
179 'redirect' : redirect, |
|
180 } |
|
181 self.toolsList.currentItem().setText(menutext) |
|
182 self.changeButton.setEnabled(False) |
|
183 |
|
184 @pyqtSlot() |
|
185 def on_deleteButton_clicked(self): |
|
186 """ |
|
187 Private slot to delete the selected entry. |
|
188 """ |
|
189 row = self.toolsList.currentRow() |
|
190 if row < 0: |
|
191 return |
|
192 |
|
193 del self.toollist[row] |
|
194 itm = self.toolsList.takeItem(row) |
|
195 del itm |
|
196 if row >= len(self.toollist): |
|
197 row -= 1 |
|
198 self.toolsList.setCurrentRow(row) |
|
199 self.on_toolsList_currentRowChanged(row) |
|
200 |
|
201 @pyqtSlot() |
|
202 def on_downButton_clicked(self): |
|
203 """ |
|
204 Private slot to move an entry down in the list. |
|
205 """ |
|
206 curr = self.toolsList.currentRow() |
|
207 self.__swap(curr, curr + 1) |
|
208 self.toolsList.clear() |
|
209 for tool in self.toollist: |
|
210 self.toolsList.addItem(tool['menutext']) |
|
211 self.toolsList.setCurrentRow(curr + 1) |
|
212 if curr + 1 == len(self.toollist): |
|
213 self.downButton.setEnabled(False) |
|
214 self.upButton.setEnabled(True) |
|
215 |
|
216 @pyqtSlot() |
|
217 def on_upButton_clicked(self): |
|
218 """ |
|
219 Private slot to move an entry up in the list. |
|
220 """ |
|
221 curr = self.toolsList.currentRow() |
|
222 self.__swap(curr - 1, curr) |
|
223 self.toolsList.clear() |
|
224 for tool in self.toollist: |
|
225 self.toolsList.addItem(tool['menutext']) |
|
226 self.toolsList.setCurrentRow(curr - 1) |
|
227 if curr - 1 == 0: |
|
228 self.upButton.setEnabled(False) |
|
229 self.downButton.setEnabled(True) |
|
230 |
|
231 @pyqtSlot() |
|
232 def on_separatorButton_clicked(self): |
|
233 """ |
|
234 Private slot to add a menu separator. |
|
235 """ |
|
236 self.toolsList.addItem('--') |
|
237 tool = { |
|
238 'menutext' : '--', |
|
239 'icon' : '', |
|
240 'executable' : '', |
|
241 'arguments' : '', |
|
242 'redirect' : 'no', |
|
243 } |
|
244 self.toollist.append(tool) |
|
245 |
|
246 @pyqtSlot() |
|
247 def on_executableButton_clicked(self): |
|
248 """ |
|
249 Private slot to handle the executable selection via a file selection dialog. |
|
250 """ |
|
251 execfile = QFileDialog.getOpenFileName(\ |
|
252 self, |
|
253 self.trUtf8("Select executable"), |
|
254 self.executableEdit.text(), |
|
255 "") |
|
256 if execfile: |
|
257 execfile = Utilities.toNativeSeparators(execfile) |
|
258 if not Utilities.isinpath(execfile): |
|
259 QMessageBox.critical(self, |
|
260 self.trUtf8("Select executable"), |
|
261 self.trUtf8("The selected file is not an executable." |
|
262 " Please choose an executable filename.")) |
|
263 return |
|
264 |
|
265 self.executableEdit.setText(execfile) |
|
266 |
|
267 @pyqtSlot() |
|
268 def on_iconButton_clicked(self): |
|
269 """ |
|
270 Private slot to handle the icon selection via a file selection dialog. |
|
271 """ |
|
272 icon = QFileDialog.getOpenFileName(\ |
|
273 self, |
|
274 self.trUtf8("Select icon file"), |
|
275 self.iconEdit.text(), |
|
276 self.trUtf8("Icon files (*.png)")) |
|
277 if icon: |
|
278 self.iconEdit.setText(icon) |
|
279 |
|
280 def on_toolsList_currentRowChanged(self, row): |
|
281 """ |
|
282 Private slot to set the lineedits depending on the selected entry. |
|
283 |
|
284 @param row the row of the selected entry (integer) |
|
285 """ |
|
286 if row >= 0 and row < len(self.toollist): |
|
287 if self.toollist[row]['menutext'] == '--': |
|
288 self.executableEdit.clear() |
|
289 self.menuEdit.clear() |
|
290 self.iconEdit.clear() |
|
291 self.argumentsEdit.clear() |
|
292 self.redirectCombo.setCurrentIndex(0) |
|
293 else: |
|
294 tool = self.toollist[row] |
|
295 self.menuEdit.setText(tool['menutext']) |
|
296 self.iconEdit.setText(tool['icon']) |
|
297 self.executableEdit.setText(tool['executable']) |
|
298 self.argumentsEdit.setText(tool['arguments']) |
|
299 self.redirectCombo.setCurrentIndex(self.__findModeIndex(tool['redirect'])) |
|
300 |
|
301 self.changeButton.setEnabled(False) |
|
302 self.deleteButton.setEnabled(True) |
|
303 |
|
304 if row != 0: |
|
305 self.upButton.setEnabled(True) |
|
306 else: |
|
307 self.upButton.setEnabled(False) |
|
308 |
|
309 if row+1 != len(self.toollist): |
|
310 self.downButton.setEnabled(True) |
|
311 else: |
|
312 self.downButton.setEnabled(False) |
|
313 else: |
|
314 self.executableEdit.clear() |
|
315 self.menuEdit.clear() |
|
316 self.iconEdit.clear() |
|
317 self.argumentsEdit.clear() |
|
318 self.downButton.setEnabled(False) |
|
319 self.upButton.setEnabled(False) |
|
320 self.deleteButton.setEnabled(False) |
|
321 self.changeButton.setEnabled(False) |
|
322 |
|
323 def __toolEntryChanged(self): |
|
324 """ |
|
325 Private slot to perform actions when a tool entry was changed. |
|
326 """ |
|
327 row = self.toolsList.currentRow() |
|
328 if row >= 0 and \ |
|
329 row < len(self.toollist) and \ |
|
330 self.toollist[row]['menutext'] != '--': |
|
331 self.changeButton.setEnabled(True) |
|
332 |
|
333 def on_menuEdit_textChanged(self, text): |
|
334 """ |
|
335 Private slot called, when the menu text was changed. |
|
336 |
|
337 @param text the new text (string) (ignored) |
|
338 """ |
|
339 self.__toolEntryChanged() |
|
340 |
|
341 def on_iconEdit_textChanged(self, text): |
|
342 """ |
|
343 Private slot called, when the icon path was changed. |
|
344 |
|
345 @param text the new text (string) (ignored) |
|
346 """ |
|
347 self.__toolEntryChanged() |
|
348 |
|
349 def on_executableEdit_textChanged(self, text): |
|
350 """ |
|
351 Private slot called, when the executable was changed. |
|
352 |
|
353 @param text the new text (string) (ignored) |
|
354 """ |
|
355 self.__toolEntryChanged() |
|
356 |
|
357 def on_argumentsEdit_textChanged(self, text): |
|
358 """ |
|
359 Private slot called, when the arguments string was changed. |
|
360 |
|
361 @param text the new text (string) (ignored) |
|
362 """ |
|
363 self.__toolEntryChanged() |
|
364 |
|
365 @pyqtSlot(int) |
|
366 def on_redirectCombo_currentIndexChanged(self, index): |
|
367 """ |
|
368 Private slot called, when the redirection mode was changed. |
|
369 |
|
370 @param index the selected mode index (integer) (ignored) |
|
371 """ |
|
372 self.__toolEntryChanged() |
|
373 |
|
374 def getToollist(self): |
|
375 """ |
|
376 Public method to retrieve the tools list. |
|
377 |
|
378 @return a list of tuples containing the menu text, the executable, |
|
379 the executables arguments and a redirection flag |
|
380 """ |
|
381 return self.toollist[:] |
|
382 |
|
383 def __swap(self, itm1, itm2): |
|
384 """ |
|
385 Private method used two swap two list entries given by their index. |
|
386 |
|
387 @param itm1 index of first entry (int) |
|
388 @param itm2 index of second entry (int) |
|
389 """ |
|
390 tmp = self.toollist[itm1] |
|
391 self.toollist[itm1] = self.toollist[itm2] |
|
392 self.toollist[itm2] = tmp |