|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2018 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to enter some IDL compiler options. |
|
8 """ |
|
9 |
|
10 from PyQt6.QtCore import Qt, pyqtSlot |
|
11 from PyQt6.QtWidgets import QDialog, QInputDialog, QTreeWidgetItem |
|
12 |
|
13 from eric7.EricGui import EricPixmapCache |
|
14 from eric7.EricWidgets import EricPathPickerDialog |
|
15 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes |
|
16 |
|
17 from .IdlCompilerDefineNameDialog import IdlCompilerDefineNameDialog |
|
18 from .Ui_IdlCompilerOptionsDialog import Ui_IdlCompilerOptionsDialog |
|
19 |
|
20 |
|
21 class IdlCompilerOptionsDialog(QDialog, Ui_IdlCompilerOptionsDialog): |
|
22 """ |
|
23 Class implementing a dialog to enter some IDL compiler options. |
|
24 """ |
|
25 |
|
26 def __init__( |
|
27 self, |
|
28 includeDirectories, |
|
29 definedNames, |
|
30 undefinedNames, |
|
31 project=None, |
|
32 parent=None, |
|
33 ): |
|
34 """ |
|
35 Constructor |
|
36 |
|
37 @param includeDirectories list of include directories |
|
38 @type list of str |
|
39 @param definedNames list of defined variables with name and value |
|
40 separated by '=' |
|
41 @type list of str |
|
42 @param undefinedNames list of undefined names |
|
43 @type list of str |
|
44 @param project reference to the project object |
|
45 @type Project |
|
46 @param parent reference to the parent widget |
|
47 @type QWidget |
|
48 """ |
|
49 super().__init__(parent) |
|
50 self.setupUi(self) |
|
51 |
|
52 self.__project = project |
|
53 |
|
54 self.idAddButton.setIcon(EricPixmapCache.getIcon("plus")) |
|
55 self.idDeleteButton.setIcon(EricPixmapCache.getIcon("minus")) |
|
56 self.idEditButton.setIcon(EricPixmapCache.getIcon("edit")) |
|
57 |
|
58 self.dnAddButton.setIcon(EricPixmapCache.getIcon("plus")) |
|
59 self.dnDeleteButton.setIcon(EricPixmapCache.getIcon("minus")) |
|
60 self.dnEditButton.setIcon(EricPixmapCache.getIcon("edit")) |
|
61 |
|
62 self.unAddButton.setIcon(EricPixmapCache.getIcon("plus")) |
|
63 self.unDeleteButton.setIcon(EricPixmapCache.getIcon("minus")) |
|
64 self.unEditButton.setIcon(EricPixmapCache.getIcon("edit")) |
|
65 |
|
66 self.__populateIncludeDirectoriesList(includeDirectories) |
|
67 self.__populateDefineNamesList(definedNames) |
|
68 self.unList.addItems(undefinedNames) |
|
69 |
|
70 self.__updateIncludeDirectoryButtons() |
|
71 self.__updateDefineNameButtons() |
|
72 self.__updateUndefineNameButtons() |
|
73 |
|
74 ####################################################################### |
|
75 ## Methods implementing the 'Include Directory' option |
|
76 ####################################################################### |
|
77 |
|
78 def __updateIncludeDirectoryButtons(self): |
|
79 """ |
|
80 Private method to set the state of the 'Include Directory' buttons. |
|
81 """ |
|
82 enable = len(self.idList.selectedItems()) |
|
83 self.idDeleteButton.setEnabled(enable) |
|
84 self.idEditButton.setEnabled(enable) |
|
85 |
|
86 def __populateIncludeDirectoriesList(self, includeDirectories): |
|
87 """ |
|
88 Private method to populate the 'Include Directories' list. |
|
89 |
|
90 @param includeDirectories list of include directories |
|
91 @type list of str |
|
92 """ |
|
93 for directory in includeDirectories: |
|
94 if self.__project: |
|
95 path = self.__project.getRelativeUniversalPath(directory) |
|
96 if not path: |
|
97 # it is the project directory |
|
98 path = "." |
|
99 self.idList.addItem(path) |
|
100 else: |
|
101 self.idList.addItem(directory) |
|
102 |
|
103 def __generateIncludeDirectoriesList(self): |
|
104 """ |
|
105 Private method to prepare the list of 'Include Directories'. |
|
106 |
|
107 @return list of 'Include Directories' |
|
108 @rtype list of str |
|
109 """ |
|
110 return [self.idList.item(row).text() for row in range(self.idList.count())] |
|
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.MatchFlag.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 defaultDirectory = self.__project.getProjectPath() if self.__project else "" |
|
137 path, ok = EricPathPickerDialog.getStrPath( |
|
138 self, |
|
139 self.tr("Include Directory"), |
|
140 self.tr("Select Include Directory"), |
|
141 EricPathPickerModes.DIRECTORY_SHOW_FILES_MODE, |
|
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 = EricPathPickerDialog.getStrPath( |
|
175 self, |
|
176 self.tr("Include Directory"), |
|
177 self.tr("Select Include Directory"), |
|
178 EricPathPickerModes.DIRECTORY_SHOW_FILES_MODE, |
|
179 strPath=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(name, Qt.MatchFlag.MatchExactly, 0)) > 0 |
|
257 |
|
258 @pyqtSlot() |
|
259 def on_dnList_itemSelectionChanged(self): |
|
260 """ |
|
261 Private slot handling the selection of a 'Define Name' entry. |
|
262 """ |
|
263 self.__updateDefineNameButtons() |
|
264 |
|
265 @pyqtSlot() |
|
266 def on_dnAddButton_clicked(self): |
|
267 """ |
|
268 Private slot to add a 'Define Name' entry. |
|
269 """ |
|
270 dlg = IdlCompilerDefineNameDialog(parent=self) |
|
271 if dlg.exec() == QDialog.DialogCode.Accepted: |
|
272 name, value = dlg.getData() |
|
273 if not self.__definedNamesContain(name): |
|
274 QTreeWidgetItem(self.dnList, [name, value]) |
|
275 |
|
276 self.dnList.sortItems(0, Qt.SortOrder.AscendingOrder) |
|
277 |
|
278 @pyqtSlot() |
|
279 def on_dnDeleteButton_clicked(self): |
|
280 """ |
|
281 Private slot to delete the selected 'Define Name' entry. |
|
282 """ |
|
283 itm = self.dnList.selectedItems()[0] |
|
284 index = self.dnList.indexOfTopLevelItem(itm) |
|
285 self.dnList.takeTopLevelItem(index) |
|
286 del itm |
|
287 |
|
288 @pyqtSlot() |
|
289 def on_dnEditButton_clicked(self): |
|
290 """ |
|
291 Private slot to edit the selected 'Define Name' entry. |
|
292 """ |
|
293 itm = self.dnList.selectedItems()[0] |
|
294 |
|
295 dlg = IdlCompilerDefineNameDialog( |
|
296 name=itm.text(0), value=itm.text(1), parent=self |
|
297 ) |
|
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(name, Qt.MatchFlag.MatchExactly, 0)[0] |
|
308 itm.setText(1, value) |
|
309 else: |
|
310 itm.setText(0, name) |
|
311 itm.setText(1, value) |
|
312 |
|
313 self.dnList.sortItems(0, Qt.SortOrder.AscendingOrder) |
|
314 |
|
315 ####################################################################### |
|
316 ## Methods implementing the 'Undefine Name' option |
|
317 ####################################################################### |
|
318 |
|
319 def __updateUndefineNameButtons(self): |
|
320 """ |
|
321 Private method to set the state of the 'Undefine Name' buttons. |
|
322 """ |
|
323 enable = len(self.unList.selectedItems()) |
|
324 self.unDeleteButton.setEnabled(enable) |
|
325 self.unEditButton.setEnabled(enable) |
|
326 |
|
327 def __generateUndefinedNamesList(self): |
|
328 """ |
|
329 Private method to prepare the list of 'Undefined Names'. |
|
330 |
|
331 @return list of 'Undefined Names' |
|
332 @rtype list of str |
|
333 """ |
|
334 return [self.unList.item(row).text() for row in range(self.unList.count())] |
|
335 |
|
336 def __undefinedNamesContain(self, name): |
|
337 """ |
|
338 Private method to test, if the currently defined 'Undefined Names' |
|
339 contain a given one. |
|
340 |
|
341 @param name variable name to be tested |
|
342 @type str |
|
343 @return flag indicating that the given name is already included |
|
344 @rtype bool |
|
345 """ |
|
346 return len(self.unList.findItems(name, Qt.MatchFlag.MatchExactly)) > 0 |
|
347 |
|
348 @pyqtSlot() |
|
349 def on_unList_itemSelectionChanged(self): |
|
350 """ |
|
351 Private slot handling the selection of a 'Undefine Name' entry. |
|
352 """ |
|
353 self.__updateUndefineNameButtons() |
|
354 |
|
355 @pyqtSlot() |
|
356 def on_unAddButton_clicked(self): |
|
357 """ |
|
358 Private slot to add a 'Undefine Name' entry. |
|
359 """ |
|
360 name, ok = QInputDialog.getText( |
|
361 self, |
|
362 self.tr("Undefine Name"), |
|
363 self.tr("Enter a variable name to be undefined:"), |
|
364 ) |
|
365 name = name.strip() |
|
366 if ok and name and not self.__undefinedNamesContain(name): |
|
367 self.unList.addItem(name) |
|
368 |
|
369 @pyqtSlot() |
|
370 def on_unDeleteButton_clicked(self): |
|
371 """ |
|
372 Private slot to delete the selected 'Undefine Name' entry. |
|
373 """ |
|
374 itm = self.unList.selectedItems()[0] |
|
375 row = self.unList.row(itm) |
|
376 self.unList.takeItem(row) |
|
377 del itm |
|
378 |
|
379 @pyqtSlot() |
|
380 def on_unEditButton_clicked(self): |
|
381 """ |
|
382 Private slot to edit the selected 'Undefine Name' entry. |
|
383 """ |
|
384 itm = self.unList.selectedItems()[0] |
|
385 name, ok = QInputDialog.getText( |
|
386 self, |
|
387 self.tr("Undefine Name"), |
|
388 self.tr("Enter a variable name to be undefined:"), |
|
389 text=itm.text(), |
|
390 ) |
|
391 name = name.strip() |
|
392 if ok and name: |
|
393 if self.__undefinedNamesContain(name) and itm.text() != name: |
|
394 # the entry exists already, delete the edited one |
|
395 row = self.unList.row(itm) |
|
396 self.unList.takeItem(row) |
|
397 del itm |
|
398 else: |
|
399 itm.setText(name) |
|
400 |
|
401 ####################################################################### |
|
402 ## Methods implementing the result preparation |
|
403 ####################################################################### |
|
404 |
|
405 def getData(self): |
|
406 """ |
|
407 Public method to return the data entered by the user. |
|
408 |
|
409 @return tuple containing the list of include directories, list of |
|
410 defined names and list of undefined names |
|
411 @rtype tuple of (list of str, list of str, list of str) |
|
412 """ |
|
413 return ( |
|
414 self.__generateIncludeDirectoriesList(), |
|
415 self.__generateDefinedNamesList(), |
|
416 self.__generateUndefinedNamesList(), |
|
417 ) |