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