|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2018 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to enter some IDL compiler options. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSlot, Qt |
|
13 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QInputDialog |
|
14 |
|
15 from .Ui_IdlCompilerOptionsDialog import Ui_IdlCompilerOptionsDialog |
|
16 |
|
17 import UI.PixmapCache |
|
18 |
|
19 from E5Gui import E5PathPickerDialog |
|
20 from E5Gui.E5PathPicker import E5PathPickerModes |
|
21 |
|
22 from .IdlCompilerDefineNameDialog import IdlCompilerDefineNameDialog |
|
23 |
|
24 |
|
25 class IdlCompilerOptionsDialog(QDialog, Ui_IdlCompilerOptionsDialog): |
|
26 """ |
|
27 Class implementing a dialog to enter some IDL compiler options. |
|
28 """ |
|
29 def __init__(self, includeDirectories, definedNames, undefinedNames, |
|
30 project=None, parent=None): |
|
31 """ |
|
32 Constructor |
|
33 |
|
34 @param includeDirectories list of include directories |
|
35 @type list of str |
|
36 @param definedNames list of defined variables with name and value |
|
37 separated by '=' |
|
38 @type list of str |
|
39 @param undefinedNames list of undefined names |
|
40 @type list of str |
|
41 @param project reference to the project object |
|
42 @type Project |
|
43 @param parent reference to the parent widget |
|
44 @type QWidget |
|
45 """ |
|
46 super(IdlCompilerOptionsDialog, self).__init__(parent) |
|
47 self.setupUi(self) |
|
48 |
|
49 self.__project = project |
|
50 |
|
51 self.idAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
52 self.idDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
53 self.idEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) |
|
54 |
|
55 self.dnAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
56 self.dnDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
57 self.dnEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) |
|
58 |
|
59 self.unAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
60 self.unDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
61 self.unEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) |
|
62 |
|
63 self.__populateIncludeDirectoriesList(includeDirectories) |
|
64 self.__populateDefineNamesList(definedNames) |
|
65 self.unList.addItems(undefinedNames) |
|
66 |
|
67 self.__updateIncludeDirectoryButtons() |
|
68 self.__updateDefineNameButtons() |
|
69 self.__updateUndefineNameButtons() |
|
70 |
|
71 ####################################################################### |
|
72 ## Methods implementing the 'Include Directory' option |
|
73 ####################################################################### |
|
74 |
|
75 def __updateIncludeDirectoryButtons(self): |
|
76 """ |
|
77 Private method to set the state of the 'Include Directory' buttons. |
|
78 """ |
|
79 enable = len(self.idList.selectedItems()) |
|
80 self.idDeleteButton.setEnabled(enable) |
|
81 self.idEditButton.setEnabled(enable) |
|
82 |
|
83 def __populateIncludeDirectoriesList(self, includeDirectories): |
|
84 """ |
|
85 Private method to populate the 'Include Directories' list. |
|
86 |
|
87 @param includeDirectories list of include directories |
|
88 @type list of str |
|
89 """ |
|
90 for directory in includeDirectories: |
|
91 if self.__project: |
|
92 path = self.__project.getRelativeUniversalPath(directory) |
|
93 if not path: |
|
94 # it is the project directory |
|
95 path = "." |
|
96 self.idList.addItem(path) |
|
97 else: |
|
98 self.idList.addItem(directory) |
|
99 |
|
100 def __generateIncludeDirectoriesList(self): |
|
101 """ |
|
102 Private method to prepare the list of 'Include Directories'. |
|
103 |
|
104 @return list of 'Include Directories' |
|
105 @rtype list of str |
|
106 """ |
|
107 return [ |
|
108 self.idList.item(row).text() |
|
109 for row in range(self.idList.count()) |
|
110 ] |
|
111 |
|
112 def __includeDirectoriesContain(self, directory): |
|
113 """ |
|
114 Private method to test, if the currently defined 'Include Directories' |
|
115 contain a given one. |
|
116 |
|
117 @param directory directory name to be tested |
|
118 @type str |
|
119 @return flag indicating that the given directory is already included |
|
120 @rtype bool |
|
121 """ |
|
122 return len(self.idList.findItems(directory, Qt.MatchExactly)) > 0 |
|
123 |
|
124 @pyqtSlot() |
|
125 def on_idList_itemSelectionChanged(self): |
|
126 """ |
|
127 Private slot handling the selection of an 'Include Directory' entry. |
|
128 """ |
|
129 self.__updateIncludeDirectoryButtons() |
|
130 |
|
131 @pyqtSlot() |
|
132 def on_idAddButton_clicked(self): |
|
133 """ |
|
134 Private slot to add an 'Include Directory'. |
|
135 """ |
|
136 if self.__project: |
|
137 defaultDirectory = self.__project.getProjectPath() |
|
138 else: |
|
139 defaultDirectory = "" |
|
140 path, ok = E5PathPickerDialog.getPath( |
|
141 self, |
|
142 self.tr("Include Directory"), |
|
143 self.tr("Select Include Directory"), |
|
144 E5PathPickerModes.DirectoryShowFilesMode, |
|
145 defaultDirectory=defaultDirectory |
|
146 ) |
|
147 if ok and path: |
|
148 if self.__project: |
|
149 path = self.__project.getRelativeUniversalPath(path) |
|
150 if not path: |
|
151 path = "." |
|
152 if not self.__includeDirectoriesContain(path): |
|
153 self.idList.addItem(path) |
|
154 |
|
155 @pyqtSlot() |
|
156 def on_idDeleteButton_clicked(self): |
|
157 """ |
|
158 Private slot to delete the selected 'Include Directory' entry. |
|
159 """ |
|
160 itm = self.idList.selectedItems()[0] |
|
161 row = self.idList.row(itm) |
|
162 self.idList.takeItem(row) |
|
163 del itm |
|
164 |
|
165 @pyqtSlot() |
|
166 def on_idEditButton_clicked(self): |
|
167 """ |
|
168 Private slot to edit the selected 'Include Directory' entry. |
|
169 """ |
|
170 itm = self.idList.selectedItems()[0] |
|
171 if self.__project: |
|
172 path = self.__project.getAbsoluteUniversalPath(itm.text()) |
|
173 defaultDirectory = self.__project.getProjectPath() |
|
174 else: |
|
175 path = itm.text() |
|
176 defaultDirectory = "" |
|
177 path, ok = E5PathPickerDialog.getPath( |
|
178 self, |
|
179 self.tr("Include Directory"), |
|
180 self.tr("Select Include Directory"), |
|
181 E5PathPickerModes.DirectoryShowFilesMode, |
|
182 path=path, |
|
183 defaultDirectory=defaultDirectory |
|
184 ) |
|
185 if ok and path: |
|
186 if self.__project: |
|
187 path = self.__project.getRelativeUniversalPath(path) |
|
188 if not path: |
|
189 path = "." |
|
190 if self.__includeDirectoriesContain(path) and itm.text() != path: |
|
191 # the entry exists already, delete the edited one |
|
192 row = self.idList.row(itm) |
|
193 self.idList.takeItem(row) |
|
194 del itm |
|
195 else: |
|
196 itm.setText(path) |
|
197 |
|
198 ####################################################################### |
|
199 ## Methods implementing the 'Define Name' option |
|
200 ####################################################################### |
|
201 |
|
202 def __updateDefineNameButtons(self): |
|
203 """ |
|
204 Private method to set the state of the 'Define Name' buttons. |
|
205 """ |
|
206 enable = len(self.dnList.selectedItems()) |
|
207 self.dnDeleteButton.setEnabled(enable) |
|
208 self.dnEditButton.setEnabled(enable) |
|
209 |
|
210 def __populateDefineNamesList(self, definedNames): |
|
211 """ |
|
212 Private method to populate the list of defined names. |
|
213 |
|
214 @param definedNames list of defined variables with name and value |
|
215 separated by '=' |
|
216 @type list of str |
|
217 """ |
|
218 for definedName in definedNames: |
|
219 if definedName: |
|
220 nameValueList = definedName.split("=") |
|
221 name = nameValueList[0].strip() |
|
222 if len(nameValueList) > 1: |
|
223 value = nameValueList[1].strip() |
|
224 else: |
|
225 value = "" |
|
226 QTreeWidgetItem(self.dnList, [name, value]) |
|
227 |
|
228 self.dnList.sortItems(0, Qt.AscendingOrder) |
|
229 |
|
230 def __generateDefinedNamesList(self): |
|
231 """ |
|
232 Private method to prepare the list of 'Defined Names'. |
|
233 |
|
234 @return list of 'Defined Names' |
|
235 @rtype list of str |
|
236 """ |
|
237 definedNames = [] |
|
238 for row in range(self.dnList.topLevelItemCount()): |
|
239 itm = self.dnList.topLevelItem(row) |
|
240 name = itm.text(0).strip() |
|
241 value = itm.text(1).strip() |
|
242 if value: |
|
243 definedNames.append("{0}={1}".format(name, value)) |
|
244 else: |
|
245 definedNames.append(name) |
|
246 |
|
247 return definedNames |
|
248 |
|
249 def __definedNamesContain(self, name): |
|
250 """ |
|
251 Private method to test, if the currently defined 'Defined Names' |
|
252 contain a given one. |
|
253 |
|
254 @param name variable name to be tested |
|
255 @type str |
|
256 @return flag indicating that the given name is already included |
|
257 @rtype bool |
|
258 """ |
|
259 return len(self.dnList.findItems(name, Qt.MatchExactly, 0)) > 0 |
|
260 |
|
261 @pyqtSlot() |
|
262 def on_dnList_itemSelectionChanged(self): |
|
263 """ |
|
264 Private slot handling the selection of a 'Define Name' entry. |
|
265 """ |
|
266 self.__updateDefineNameButtons() |
|
267 |
|
268 @pyqtSlot() |
|
269 def on_dnAddButton_clicked(self): |
|
270 """ |
|
271 Private slot to add a 'Define Name' entry. |
|
272 """ |
|
273 dlg = IdlCompilerDefineNameDialog(parent=self) |
|
274 if dlg.exec_() == QDialog.Accepted: |
|
275 name, value = dlg.getData() |
|
276 if not self.__definedNamesContain(name): |
|
277 QTreeWidgetItem(self.dnList, [name, value]) |
|
278 |
|
279 self.dnList.sortItems(0, Qt.AscendingOrder) |
|
280 |
|
281 @pyqtSlot() |
|
282 def on_dnDeleteButton_clicked(self): |
|
283 """ |
|
284 Private slot to delete the selected 'Define Name' entry. |
|
285 """ |
|
286 itm = self.dnList.selectedItems()[0] |
|
287 index = self.dnList.indexOfTopLevelItem(itm) |
|
288 self.dnList.takeTopLevelItem(index) |
|
289 del itm |
|
290 |
|
291 @pyqtSlot() |
|
292 def on_dnEditButton_clicked(self): |
|
293 """ |
|
294 Private slot to edit the selected 'Define Name' entry. |
|
295 """ |
|
296 itm = self.dnList.selectedItems()[0] |
|
297 |
|
298 dlg = IdlCompilerDefineNameDialog( |
|
299 name=itm.text(0), value=itm.text(1), parent=self) |
|
300 if dlg.exec_() == QDialog.Accepted: |
|
301 name, value = dlg.getData() |
|
302 if self.__definedNamesContain(name) and itm.text(0) != name: |
|
303 # the entry exists already, delete the edited one |
|
304 index = self.dnList.indexOfTopLevelItem(itm) |
|
305 self.dnList.takeTopLevelItem(index) |
|
306 del itm |
|
307 |
|
308 # change the named one |
|
309 itm = self.dnList.findItems(name, Qt.MatchExactly, 0)[0] |
|
310 itm.setText(1, value) |
|
311 else: |
|
312 itm.setText(0, name) |
|
313 itm.setText(1, value) |
|
314 |
|
315 self.dnList.sortItems(0, Qt.AscendingOrder) |
|
316 |
|
317 ####################################################################### |
|
318 ## Methods implementing the 'Undefine Name' option |
|
319 ####################################################################### |
|
320 |
|
321 def __updateUndefineNameButtons(self): |
|
322 """ |
|
323 Private method to set the state of the 'Undefine Name' buttons. |
|
324 """ |
|
325 enable = len(self.unList.selectedItems()) |
|
326 self.unDeleteButton.setEnabled(enable) |
|
327 self.unEditButton.setEnabled(enable) |
|
328 |
|
329 def __generateUndefinedNamesList(self): |
|
330 """ |
|
331 Private method to prepare the list of 'Undefined Names'. |
|
332 |
|
333 @return list of 'Undefined Names' |
|
334 @rtype list of str |
|
335 """ |
|
336 return [ |
|
337 self.unList.item(row).text() |
|
338 for row in range(self.unList.count()) |
|
339 ] |
|
340 |
|
341 def __undefinedNamesContain(self, name): |
|
342 """ |
|
343 Private method to test, if the currently defined 'Undefined Names' |
|
344 contain a given one. |
|
345 |
|
346 @param name variable name to be tested |
|
347 @type str |
|
348 @return flag indicating that the given name is already included |
|
349 @rtype bool |
|
350 """ |
|
351 return len(self.unList.findItems(name, Qt.MatchExactly)) > 0 |
|
352 |
|
353 @pyqtSlot() |
|
354 def on_unList_itemSelectionChanged(self): |
|
355 """ |
|
356 Private slot handling the selection of a 'Undefine Name' entry. |
|
357 """ |
|
358 self.__updateUndefineNameButtons() |
|
359 |
|
360 @pyqtSlot() |
|
361 def on_unAddButton_clicked(self): |
|
362 """ |
|
363 Private slot to add a 'Undefine Name' entry. |
|
364 """ |
|
365 name, ok = QInputDialog.getText( |
|
366 self, |
|
367 self.tr("Undefine Name"), |
|
368 self.tr("Enter a variable name to be undefined:") |
|
369 ) |
|
370 name = name.strip() |
|
371 if ok and name and not self.__undefinedNamesContain(name): |
|
372 self.unList.addItem(name) |
|
373 |
|
374 @pyqtSlot() |
|
375 def on_unDeleteButton_clicked(self): |
|
376 """ |
|
377 Private slot to delete the selected 'Undefine Name' entry. |
|
378 """ |
|
379 itm = self.unList.selectedItems()[0] |
|
380 row = self.unList.row(itm) |
|
381 self.unList.takeItem(row) |
|
382 del itm |
|
383 |
|
384 @pyqtSlot() |
|
385 def on_unEditButton_clicked(self): |
|
386 """ |
|
387 Private slot to edit the selected 'Undefine Name' entry. |
|
388 """ |
|
389 itm = self.unList.selectedItems()[0] |
|
390 name, ok = QInputDialog.getText( |
|
391 self, |
|
392 self.tr("Undefine Name"), |
|
393 self.tr("Enter a variable name to be undefined:"), |
|
394 text=itm.text() |
|
395 ) |
|
396 name = name.strip() |
|
397 if ok and name: |
|
398 if self.__undefinedNamesContain(name) and itm.text() != name: |
|
399 # the entry exists already, delete the edited one |
|
400 row = self.unList.row(itm) |
|
401 self.unList.takeItem(row) |
|
402 del itm |
|
403 else: |
|
404 itm.setText(name) |
|
405 |
|
406 ####################################################################### |
|
407 ## Methods implementing the result preparation |
|
408 ####################################################################### |
|
409 |
|
410 def getData(self): |
|
411 """ |
|
412 Public method to return the data entered by the user. |
|
413 |
|
414 @return tuple containing the list of include directories, list of |
|
415 defined names and list of undefined names |
|
416 @rtype tuple of (list of str, list of str, list of str) |
|
417 """ |
|
418 return ( |
|
419 self.__generateIncludeDirectoriesList(), |
|
420 self.__generateDefinedNamesList(), |
|
421 self.__generateUndefinedNamesList(), |
|
422 ) |