diff -r b7c3b34661d5 -r 9d42b6c08a27 Project/IdlCompilerOptionsDialog.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Project/IdlCompilerOptionsDialog.py Sat Jul 28 19:14:11 2018 +0200 @@ -0,0 +1,370 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter some IDL compiler options. +""" + +from PyQt5.QtCore import pyqtSlot, Qt +from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QInputDialog + +from .Ui_IdlCompilerOptionsDialog import Ui_IdlCompilerOptionsDialog + +import UI.PixmapCache + +from E5Gui import E5PathPickerDialog +from E5Gui.E5PathPicker import E5PathPickerModes + + +class IdlCompilerOptionsDialog(QDialog, Ui_IdlCompilerOptionsDialog): + """ + Class implementing a dialog to enter some IDL compiler options. + """ + def __init__(self, includeDirectories, definedNames, undefinedNames, + project=None, parent=None): + """ + Constructor + + @param includeDirectories list of include directories + @type list of str + @param definedNames list of defined variables with name and value + separated by '=' + @type list of str + @param undefinedNames list of undefined names + @type list of str + @param projectDirectory directory name of the project + @type str + @param parent reference to the parent widget + @type QWidget + """ + super(IdlCompilerOptionsDialog, self).__init__(parent) + self.setupUi(self) + + self.__project = project + + self.idAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) + self.idDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) + self.idEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) + + self.dnAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) + self.dnDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) + self.dnEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) + + self.unAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) + self.unDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) + self.unEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) + + self.__populateIncludeDirectoriesList(includeDirectories) + self.__populateDefineNamesList(definedNames) + self.unList.addItems(undefinedNames) + + self.__updateIncludeDirectoryButtons() + self.__updateDefineNameButtons() + self.__updateUndefineNameButtons() + + ####################################################################### + ## Methods implementing the 'Include Directory' option + ####################################################################### + + def __updateIncludeDirectoryButtons(self): + """ + Private method to set the state of the 'Include Directory' buttons. + """ + enable = len(self.idList.selectedItems()) + self.idDeleteButton.setEnabled(enable) + self.idEditButton.setEnabled(enable) + + def __populateIncludeDirectoriesList(self, includeDirectories): + """ + Private method to populate the 'Include Directories' list. + + @param includeDirectories list of include directories + @type list of str + """ + for directory in includeDirectories: + if self.__project: + path = self.__project.getRelativeUniversalPath(directory) + if not path: + # it is the project directory + path = "." + self.idList.addItem(path) + else: + self.idList.addItem(directory) + + def __generateIncludeDirectoriesList(self): + """ + Private method to prepare the list of 'Include Directories'. + + @return list of 'Include Directories' + @rtype list of str + """ + return [ + self.idList.item(row).text() + for row in range(self.idList.count()) + ] + + def __includeDirectoriesContain(self, directory): + """ + Private method to test, if the currently defined 'Include Directories' + contain a given one. + + @param directory directory name to be tested + @type str + @return flag indicating that the given directory is already included + @rtype bool + """ + for row in range(self.idList.count()): + if self.idList.item(row).text() == directory: + return True + + return False + + @pyqtSlot() + def on_idList_itemSelectionChanged(self): + """ + Private slot handling the selection of an 'Include Directory' entry. + """ + self.__updateIncludeDirectoryButtons() + + @pyqtSlot() + def on_idAddButton_clicked(self): + """ + Private slot to add an 'Include Directory'. + """ + if self.__project: + defaultDirectory = self.__project.getProjectPath() + else: + defaultDirectory = "" + path, ok = E5PathPickerDialog.getPath( + self, + self.tr("Include Directory"), + self.tr("Select Include Directory"), + E5PathPickerModes.DirectoryShowFilesMode, + defaultDirectory=defaultDirectory + ) + if ok and path: + if self.__project: + path = self.__project.getRelativeUniversalPath(path) + if not path: + path = "." + if not self.__includeDirectoriesContain(path): + self.idList.addItem(path) + + @pyqtSlot() + def on_idDeleteButton_clicked(self): + """ + Private slot to delete the selected 'Include Directory' entry. + """ + itm = self.idList.selectedItems()[0] + row = self.idList.row(itm) + self.idList.takeItem(row) + del itm + + @pyqtSlot() + def on_idEditButton_clicked(self): + """ + Private slot to edit the selected 'Include Directory' entry. + """ + itm = self.idList.selectedItems()[0] + if self.__project: + path = self.__project.getAbsoluteUniversalPath(itm.text()) + defaultDirectory = self.__project.getProjectPath() + else: + path = itm.text() + defaultDirectory = "" + path, ok = E5PathPickerDialog.getPath( + self, + self.tr("Include Directory"), + self.tr("Select Include Directory"), + E5PathPickerModes.DirectoryShowFilesMode, + path=path, + defaultDirectory=defaultDirectory + ) + if ok and path: + if self.__project: + path = self.__project.getRelativeUniversalPath(path) + if not path: + path = "." + if self.__includeDirectoriesContain(path) and itm.text() != path: + # the entry exists already, delete the edited one + row = self.idList.row(itm) + self.idList.takeItem(row) + del itm + else: + itm.setText(path) + + ####################################################################### + ## Methods implementing the 'Define Name' option + ####################################################################### + + def __updateDefineNameButtons(self): + """ + Private method to set the state of the 'Define Name' buttons. + """ + enable = len(self.dnList.selectedItems()) + self.dnDeleteButton.setEnabled(enable) + self.dnEditButton.setEnabled(enable) + + def __populateDefineNamesList(self, definedNames): + """ + Private method to populate the list of defined names. + + @param definedNames list of defined variables with name and value + separated by '=' + @type list of str + """ + for definedName in definedNames: + if definedName: + nameValueList = definedName.split("=") + name = nameValueList[0].strip() + if len(nameValueList) > 1: + value = nameValueList[1].strip() + else: + value = "" + QTreeWidgetItem(self.dnList, [name, value]) + + self.dnList.sortItems(0, Qt.AscendingOrder) + + @pyqtSlot() + def on_dnList_itemSelectionChanged(self): + """ + Private slot handling the selection of a 'Define Name' entry. + """ + self.__updateDefineNameButtons() + + @pyqtSlot() + def on_dnAddButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + @pyqtSlot() + def on_dnDeleteButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + @pyqtSlot() + def on_dnEditButton_clicked(self): + """ + Slot documentation goes here. + """ + # TODO: not implemented yet + raise NotImplementedError + + ####################################################################### + ## Methods implementing the 'Undefine Name' option + ####################################################################### + + def __updateUndefineNameButtons(self): + """ + Private method to set the state of the 'Undefine Name' buttons. + """ + enable = len(self.unList.selectedItems()) + self.unDeleteButton.setEnabled(enable) + self.unEditButton.setEnabled(enable) + + def __generateUndefinedNamesList(self): + """ + Private method to prepare the list of 'Undefined Names'. + + @return list of 'Undefined Names' + @rtype list of str + """ + return [ + self.unList.item(row).text() + for row in range(self.unList.count()) + ] + + def __undefinedNamesContain(self, name): + """ + Private method to test, if the currently defined 'Undefined Names' + contain a given one. + + @param name variable name to be tested + @type str + @return flag indicating that the given name is already included + @rtype bool + """ + for row in range(self.unList.count()): + if self.unList.item(row).text() == name: + return True + + return False + + @pyqtSlot() + def on_unList_itemSelectionChanged(self): + """ + Private slot handling the selection of a 'Undefine Name' entry. + """ + self.__updateUndefineNameButtons() + + @pyqtSlot() + def on_unAddButton_clicked(self): + """ + Private slot to add a 'Undefine Name' entry. + """ + name, ok = QInputDialog.getText( + self, + self.tr("Undefine Name"), + self.tr("Enter a variable name to be undefined:") + ) + name = name.strip() + if ok and name and not self.__undefinedNamesContain(name): + self.unList.addItem(name) + + @pyqtSlot() + def on_unDeleteButton_clicked(self): + """ + Private slot to delete the selected 'Undefine Name' entry. + """ + itm = self.unList.selectedItems()[0] + row = self.unList.row(itm) + self.unList.takeItem(row) + del itm + + @pyqtSlot() + def on_unEditButton_clicked(self): + """ + Private slot to edit the selected 'Undefine Name' entry. + """ + itm = self.unList.selectedItems()[0] + name, ok = QInputDialog.getText( + self, + self.tr("Undefine Name"), + self.tr("Enter a variable name to be undefined:"), + text=itm.text() + ) + name = name.strip() + if ok and name: + if self.__undefinedNamesContain(name) and itm.text() != name: + # the entry exists already, delete the edited one + row = self.unList.row(itm) + self.unList.takeItem(row) + del itm + else: + itm.setText(name) + + ####################################################################### + ## Methods implementing the result preparation + ####################################################################### + + def getData(self): + """ + Public method to return the data entered by the user. + + @return tuple containing the list of include directories, list of + defined names and list of undefined names + @rtype tuple of (list of str, list of str, list of str) + """ + return ( + self.__generateIncludeDirectoriesList(), + [], + self.__generateUndefinedNamesList(), + )