Пример #1
0
 def __init__(self,
              edgvVersion,
              areas,
              lines,
              oldCoverage,
              propertyList,
              enableSetupFromFile=True,
              onlySetup=False,
              propertyName=None,
              parent=None):
     """
     Constructor
     """
     super(self.__class__, self).__init__()
     self.setupUi(self)
     self.utils = Utils()
     self.areas = areas
     self.lines = lines
     self.propertyName = propertyName
     self.edgvVersion = edgvVersion
     self.areasCustomSelector.setTitle(self.tr('Areas'))
     self.linesCustomSelector.setTitle(self.tr('Lines'))
     self.propertyList = propertyList
     self.button(QtWidgets.QWizard.NextButton).clicked.connect(
         self.buildTree)
     self.button(QtWidgets.QWizard.FinishButton).clicked.connect(
         self.buildDict)
     self.setupWizard(oldCoverage, enableSetupFromFile)
     self.configDict = dict()
Пример #2
0
 def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
     """Constructor."""
     super(self.__class__, self).__init__(parent)
     self.abstractDb = abstractDb
     self.setupUi(self)
     self.jsonBuilder = CustomJSONBuilder()
     self.populateSchemaCombo()
     self.hideWidgetList([
         self.singleValueLabel, self.singleValueComboBox,
         self.actionComboBox
     ])
     self.singleAttribute = True
     self.filterCustomSelectorWidget.setTitle(
         self.tr('Select filter values'))
     self.populateSingleValue.connect(self.populateWidgetWithSingleValue)
     self.populateListValue.connect(self.populateWidgetWithListValue)
     geomTypeDict = self.abstractDb.getGeomTypeDict()
     geomDict = self.abstractDb.getGeomDict(geomTypeDict)
     self.domainDict = self.abstractDb.getDbDomainDict(geomDict)
     self.inhTree = self.abstractDb.getInheritanceTreeDict()
     self.utils = Utils()
     self.actionDict = {
         self.tr('Add to Filter (Leave empty if filter is empty)'):
         'addEmpty',
         self.tr('Add to Filter (Add value to empty filter)'): 'add',
         self.tr('Remove from Filter'): 'remove'
     }
     self.populateFromUiParameterJsonDict(uiParameterJsonDict)
Пример #3
0
 def __init__(self, genericDbManager=None, parent=None):
     """
     Constructor
     """
     super(GenericManagerWidget, self).__init__(parent)
     self.setupUi(self)
     self.genericDbManager = genericDbManager
     self.textDict = {
         'EarthCoverage': self.tr('Earth Coverage'),
         'Customization': self.tr('Customization'),
         'Style': self.tr('Style'),
         'ValidationConfig': self.tr('Validation'),
         'FieldToolBoxConfig': self.tr('Field Toolbox Configuration'),
         'Permission': self.tr('Permissions'),
         'AttributeRules': self.tr('Attribute Rule Configuration'),
         'SpatialRuleConfig': self.tr('Spatial Rule Configuration')
     }
     self.captionDict = {
         'EarthCoverage': self.tr('Earth Coverage'),
         'Customization': self.tr('Customization'),
         'Style': self.tr('Style'),
         'ValidationConfig': self.tr('Validation'),
         'FieldToolBoxConfig': self.tr('Reclassification Setup Files'),
         'Permission': self.tr('Select a dsgtools permission profile'),
         'AttributeRules': self.tr('Attribute Rule Configuration file'),
         'SpatialRuleConfig': self.tr('Spatial Rule Configuration file')
     }
     self.filterDict = {
         'EarthCoverage':
         self.tr('Earth Coverage Setup File (*.dsgearthcov)'),
         'Customization':
         self.tr('DsgTools Customization File (*.dsgcustom)'),
         'Style':
         self.tr('DsgTools Styles File (*.dsgstyle)'),
         'ValidationConfig':
         self.tr('DsgTools Validation Configuration File (*.dsgvalidcfg)'),
         'FieldToolBoxConfig':
         self.tr('Reclassification Setup Files (*.reclas)'),
         'Permission':
         self.tr('DsgTools Permission Profile File (*.dsgperm)'),
         'AttributeRules':
         self.tr('Attribute Rule Configuration file (*.dsgattrrul)'),
         'SpatialRuleConfig':
         self.tr('Spatial Rule Configuration file (*.dsgspatrul)')
     }
     self.widgetName = self.textDict[self.getWhoAmI()]
     self.genericDict = None
     self.setComponentsEnabled(False)
     self.utils = Utils()
     self.setHeaders()
     self.setButtons()
     self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
     self.treeWidget.customContextMenuRequested.connect(
         self.createMenuAssigned)
Пример #4
0
 def setupFields(self):
     """
     Setups up all fields and fill up with available data on the attribute
     map.
     """
     utils = Utils()
     row = 0  # in case no fields are provided
     for row, f in enumerate(self.fields):
         fName = f.name()
         fMap = self.attributeMap[fName] if fName in self.attributeMap \
                     else None
         if fName in self.attributeMap:
             fMap = self.attributeMap[fName]
             if fMap["ignored"]:
                 w = QLineEdit()
                 w.setText(self.tr("Field is set to be ignored"))
                 value = None
                 enabled = False
             else:
                 value = fMap["value"]
                 enabled = fMap["editable"]
             if fMap["isPk"]:
                 # visually identify primary key attributes
                 text = '<p>{0} <img src=":/plugins/DsgTools/icons/key.png" '\
                        'width="16" height="16"></p>'.format(fName)
             else:
                 text = fName
         else:
             value = None
             enabled = True
             text = fName
         if fName in self.attributeMap and self.attributeMap[fName][
                 "ignored"]:
             pass
         elif utils.fieldIsFloat(f):
             w = QDoubleSpinBox()
             w.setValue(0 if value is None else value)
         elif utils.fieldIsInt(f):
             w = QSpinBox()
             w.setValue(0 if value is None else value)
         else:
             w = QLineEdit()
             w.setText("" if value is None else value)
         w.setEnabled(enabled)
         # also to make easier to read data
         self._fieldsWidgets[fName] = w
         label = QLabel(text)
         label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
         w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
         self.widgetsLayout.addWidget(label, row, 0)
         self.widgetsLayout.addWidget(w, row, 1)
     self.widgetsLayout.addItem(
         QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding),
         row + 1, 1, 1, 2)  # row, col, rowSpan, colSpan
Пример #5
0
 def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
     super(GenericDbManager,self).__init__()
     self.parentWidget = parentWidget
     self.dbDict = dbDict
     self.serverAbstractDb = serverAbstractDb
     self.adminDb = self.instantiateAdminDb(serverAbstractDb)
     self.utils = Utils()
     self.extensionDict = {'EarthCoverage':'.dsgearthcov',
                 'Customization':'.dsgcustom',
                 'Style':'.dsgstyle',
                 'ValidationConfig':'.dsgvalidcfg',
                 'Permission':'.dsgperm',
                 'AttributeRules':'.dsgattrrul',
                 'SpatialRules':'.dsgspatrul',
                 'ValidationWorkspace':'.dsgworksp'}
     self.edgvVersion = edgvVersion
     self.createPropertyTable()
Пример #6
0
 def __init__(self, parent = None):
     """Constructor."""
     super(FMEManagerWidget, self).__init__(parent=parent)
     self.setupUi(self)
     self.workspaceList = []
     self.interfaceDict = {}
     self.server = ''
     self.proxy_dict, self.auth = Utils().get_proxy_config()
Пример #7
0
 def getProxyInfo(self):
     """
     Reads Proxy settings as registered on QGIS settings.
     :return: (tuple) the QGIS proxy mapping per schema and its
              authentication object.
     """
     if self.useProxy():
         return Utils().get_proxy_config()
     else:
         return (None, None)
Пример #8
0
    def __init__(self, iface, abstractDb, loadCentroids):
        """Constructor."""
        super(EDGVLayerLoader, self).__init__()

        self.abstractDb = abstractDb
        self.uri = QgsDataSourceUri()
        self.iface = iface
        self.utils = Utils()
        self.logErrorDict = dict()
        self.errorLog = ''
        self.geomTypeDict = self.abstractDb.getGeomTypeDict(loadCentroids)
        self.geomDict = self.abstractDb.getGeomDict(self.geomTypeDict)
        self.correspondenceDict = {
            'POINT': 'Point',
            'MULTIPOINT': 'Point',
            'LINESTRING': 'Line',
            'MULTILINESTRING': 'Line',
            'POLYGON': 'Area',
            'MULTIPOLYGON': 'Area'
        }
 def __init__(self,
              customizationName,
              abstractDb,
              edgvVersion,
              customizationManager,
              customJsonDict=None,
              parent=None):
     """Constructor."""
     super(self.__class__, self).__init__(parent)
     self.setupUi(self)
     self.customizationManager = customizationManager
     self.abstractDb = abstractDb
     self.edgvVersion = edgvVersion
     self.customizationName = customizationName
     self.contentsDict = dict()
     self.populateCustomizationCombo()
     self.setWidgetsEnabled(True)
     self.utils = Utils()
     if customJsonDict:
         self.createWidgetsFromCustomJsonDict(customJsonDict)
Пример #10
0
 def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
     """Constructor."""
     super(self.__class__, self).__init__(parent)
     self.abstractDb = abstractDb
     self.setupUi(self)
     self.jsonBuilder = CustomJSONBuilder()
     self.populateSchemaCombo()
     geomTypeDict = self.abstractDb.getGeomTypeDict()
     geomDict = self.abstractDb.getGeomDict(geomTypeDict)
     self.domainDict = self.abstractDb.getDbDomainDict(geomDict)
     self.utils = Utils()
     self.populateFromUiParameterJsonDict(uiParameterJsonDict)
Пример #11
0
 def __init__(self, parent=None):
     """Constructor."""
     super(self.__class__, self).__init__(parent)
     self.setupUi(self)
     self.utils = Utils()
     self.dbFactory = DbFactory()
     self.factory = SqlGeneratorFactory()
     self.showTabs(show=False)
     #setting the sql generator
     self.serverWidget.populateServersCombo()
     self.serverWidget.abstractDbLoaded.connect(self.checkSuperUser)
     self.serverWidget.abstractDbLoaded.connect(
         self.populateOtherInterfaces)
     self.dbsCustomSelector.setTitle(self.tr('Server Databases'))
     self.dbsCustomSelector.selectionChanged.connect(self.showTabs)
     self.dbsCustomSelector.selectionChanged.connect(
         self.populateStylesInterface)
     self.dbsCustomSelector.selectionChanged.connect(
         self.populateOtherInterfaces)
     self.previousTab = 0
     self.dbDict = {
         '2.1.3': [],
         '2.1.3 Pro': [],
         'FTer_2a_Ed': [],
         'Non_EDGV': [],
         '3.0': [],
         '3.0 Pro': []
     }
     self.correspondenceDict = {
         self.tr('Load Database Model EDGV Version 2.1.3'): '2.1.3',
         self.tr('Load Database Model EDGV Version 2.1.3 Pro'): '2.1.3 Pro',
         self.tr('Load Database Model EDGV Version 3.0'): '3.0',
         self.tr('Load Database Model EDGV Version 3.0 Pro'): '3.0 Pro',
         self.tr('Load Database Model EDGV Version FTer_2a_Ed'):
         'FTer_2a_Ed',
         self.tr('Load Other Database Models'): 'Non_EDGV'
     }
Пример #12
0
 def __init__(self, parent = None):
     """Constructor."""
     super(self.__class__, self).__init__(parent)
     # Set up the user interface from Designer.
     # After setupUI you can access any designer object by doing
     # self.<objectname>, and you can use autoconnect slots - see
     # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
     # #widgets-and-dialogs-with-auto-connect
     self.setupUi(self)
     self.utils = Utils()
     self.factory = SqlGeneratorFactory()
     #setting the sql generator
     self.gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS)
     self.serverWidget.populateServersCombo()
     self.serverWidget.abstractDbLoaded.connect(self.populateListWithDatabasesFromServer)
Пример #13
0
 def __init__(self, parent=None):
     """
     Constructor
     """
     super(self.__class__, self).__init__(parent)
     # Set up the user interface from Designer.
     # After setupUI you can access any designer object by doing
     # self.<objectname>, and you can use autoconnect slots - see
     # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
     # #widgets-and-dialogs-with-auto-connect
     self.setupUi(self)
     self.utils = Utils()
     self.dbFactory = DbFactory()
     self.localDb = None
     self.serverWidget.populateServersCombo()
     #signal connections
     self.serverWidget.abstractDbLoaded.connect(self.checkSuperUser)
     self.serverWidget.clearWidgets.connect(self.clearAll)
     self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
     self.treeWidget.customContextMenuRequested.connect(
         self.createMenuAssigned)
Пример #14
0
                                 QLineEdit,
                                 QCheckBox,
                                 QComboBox,
                                 QPushButton,
                                 QHBoxLayout,
                                 QMessageBox,
                                 QDoubleSpinBox)

from DsgTools.core.Utils.utils import Utils, MessageRaiser
from DsgTools.core.GeometricTools.layerHandler import LayerHandler
from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton

FORM_CLASS, _ = uic.loadUiType(os.path.join(
    os.path.dirname(__file__), 'buttonPropWidget.ui'))

utils = Utils()

class ButtonPropWidget(QWidget, FORM_CLASS):
    # col enum
    COL_COUNT = 5
    ATTR_COL, VAL_COL, PK_COL, EDIT_COL, IGNORED_COL = range(COL_COUNT)
    def __init__(self, parent=None, button=None):
        """
        Class constructor.
        :param parent: (QtWidgets.*) any widget that 'contains' this tool.
        :param buttonProps: (CustomFeatureButton) button to be managed.
        """
        super(ButtonPropWidget, self).__init__(parent)
        self.setupUi(self)
        self.mMapLayerComboBox.setFilters(
            QgsMapLayerProxyModel.HasGeometry|
Пример #15
0
class GenericManagerWidget(QtWidgets.QWidget, FORM_CLASS):
    Install, Delete, Uninstall, Update, Create = list(range(5))

    def __init__(self, genericDbManager=None, parent=None):
        """
        Constructor
        """
        super(GenericManagerWidget, self).__init__(parent)
        self.setupUi(self)
        self.genericDbManager = genericDbManager
        self.textDict = {
            'EarthCoverage': self.tr('Earth Coverage'),
            'Customization': self.tr('Customization'),
            'Style': self.tr('Style'),
            'ValidationConfig': self.tr('Validation'),
            'FieldToolBoxConfig': self.tr('Field Toolbox Configuration'),
            'Permission': self.tr('Permissions'),
            'AttributeRules': self.tr('Attribute Rule Configuration'),
            'SpatialRuleConfig': self.tr('Spatial Rule Configuration')
        }
        self.captionDict = {
            'EarthCoverage': self.tr('Earth Coverage'),
            'Customization': self.tr('Customization'),
            'Style': self.tr('Style'),
            'ValidationConfig': self.tr('Validation'),
            'FieldToolBoxConfig': self.tr('Reclassification Setup Files'),
            'Permission': self.tr('Select a dsgtools permission profile'),
            'AttributeRules': self.tr('Attribute Rule Configuration file'),
            'SpatialRuleConfig': self.tr('Spatial Rule Configuration file')
        }
        self.filterDict = {
            'EarthCoverage':
            self.tr('Earth Coverage Setup File (*.dsgearthcov)'),
            'Customization':
            self.tr('DsgTools Customization File (*.dsgcustom)'),
            'Style':
            self.tr('DsgTools Styles File (*.dsgstyle)'),
            'ValidationConfig':
            self.tr('DsgTools Validation Configuration File (*.dsgvalidcfg)'),
            'FieldToolBoxConfig':
            self.tr('Reclassification Setup Files (*.reclas)'),
            'Permission':
            self.tr('DsgTools Permission Profile File (*.dsgperm)'),
            'AttributeRules':
            self.tr('Attribute Rule Configuration file (*.dsgattrrul)'),
            'SpatialRuleConfig':
            self.tr('Spatial Rule Configuration file (*.dsgspatrul)')
        }
        self.widgetName = self.textDict[self.getWhoAmI()]
        self.genericDict = None
        self.setComponentsEnabled(False)
        self.utils = Utils()
        self.setHeaders()
        self.setButtons()
        self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeWidget.customContextMenuRequested.connect(
            self.createMenuAssigned)

    def setButtons(self):
        createText = self.createPushButton.text()
        self.createPushButton.setText(
            createText.replace(self.tr('Setting'), self.widgetName))
        deleteText = self.deletePushButton.text()
        self.deletePushButton.setText(
            deleteText.replace(self.tr('Setting'), self.widgetName))

    def setHeaders(self):
        viewType = self.getViewType()
        if viewType == DsgEnums.Database:
            self.treeWidget.setHeaderLabels(
                [self.tr('Database'), self.widgetName])
        else:
            self.treeWidget.setHeaderLabels(
                [self.widgetName, self.tr('Database')])
        return viewType

    def getWhoAmI(self):
        return str(self.__class__).split('.')[-1].replace('\'>', '').replace(
            'ManagerWidget', '')

    def setChildParameter(self):
        """
        Reimplement in each child
        """
        pass

    def setComponentsEnabled(self, enabled):
        """
        Changes states of all components of the widget, according to the boolean parameter enabled.
        """
        self.treeWidget.setEnabled(enabled)
        self.importPushButton.setEnabled(enabled)
        self.batchImportPushButton.setEnabled(enabled)
        self.exportPushButton.setEnabled(enabled)
        self.batchExportPushButton.setEnabled(enabled)
        self.databasePerspectivePushButton.setEnabled(enabled)
        self.propertyPerspectivePushButton.setEnabled(enabled)

    def populateConfigInterface(self, templateDb, jsonDict=None):
        """
        Must be reimplemented in each child
        """
        pass

    def readJsonFromDatabase(self, propertyName, edgvVersion):
        """
        Reads the profile file, gets a dictionary of it and builds the tree widget
        """
        self.genericDict = self.genericDbManager.getCustomization(
            propertyName, edgvVersion)

    @pyqtSlot(bool)
    def on_importPushButton_clicked(self):
        """
        Imports a property file into dsgtools_admindb
        """
        fd = QFileDialog()
        widgetType = self.getWhoAmI()
        filename = fd.getOpenFileName(caption=self.captionDict[widgetType],
                                      filter=self.filterDict[widgetType])[0]
        filename = filename[0] if isinstance(filename, tuple) else filename
        if filename == '':
            # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a file to import!'))
            return
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            self.genericDbManager.importSetting(filename)
            QApplication.restoreOverrideCursor()
            QMessageBox.information(
                self, self.tr('Success!'),
                self.widgetName + self.tr(' successfully imported.'))
        except Exception as e:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(
                self, self.tr('Error!'),
                self.tr('Error! Problem importing ') + self.widgetName + ': ' +
                ':'.join(e.args))
        self.refresh()

    @pyqtSlot(bool)
    def on_exportPushButton_clicked(self):
        """
        Export selected properties.
        """
        exportPropertyList = self.selectConfig()
        if exportPropertyList is None:
            # user cancelled
            return
        if exportPropertyList == []:
            QMessageBox.warning(
                self, self.tr('Warning!'),
                self.tr('Warning! Select a profile to export!'))
            return
        fd = QFileDialog()
        folder = fd.getExistingDirectory(
            caption=self.tr('Select a folder to output'))
        folder = folder[0] if isinstance(folder, tuple) else folder
        if folder == '':
            # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!'))
            return
        edgvVersion = self.genericDbManager.edgvVersion
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            for exportProperty in exportPropertyList:
                self.genericDbManager.exportSetting(exportProperty,
                                                    edgvVersion, folder)
            QApplication.restoreOverrideCursor()
            QMessageBox.information(
                self, self.tr('Success!'),
                self.widgetName + self.tr(' successfully exported.'))
        except Exception as e:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(
                self, self.tr('Error!'),
                self.tr('Error! Problem exporting ') + self.widgetName + ': ' +
                ':'.join(e.args))

    @pyqtSlot(bool)
    def on_batchExportPushButton_clicked(self):
        """
        Exports all configs from dsgtools_admindb.
        """
        fd = QFileDialog()
        folder = fd.getExistingDirectory(
            caption=self.tr('Select a folder to output'))
        folder = folder[0] if isinstance(folder, tuple) else folder
        if folder == '':
            # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!'))
            return
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            self.genericDbManager.batchExportSettings(folder)
            QApplication.restoreOverrideCursor()
            QMessageBox.information(
                self, self.tr('Success!'),
                self.widgetName + self.tr(' successfully exported.'))
        except Exception as e:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(
                self, self.tr('Error!'),
                self.tr('Error! Problem exporting ') + self.widgetName + ': ' +
                ':'.join(e.args))

    @pyqtSlot(bool)
    def on_batchImportPushButton_clicked(self):
        """
        Imports all config files from a folder into dsgtools_admindb. It only works for a single type of config per time.
        """
        fd = QFileDialog()
        folder = fd.getExistingDirectory(
            caption=self.tr('Select a folder with json files: '))
        if folder == '':
            # QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a input folder!'))
            return
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            self.genericDbManager.batchImportSettings(folder)
            QApplication.restoreOverrideCursor()
            QMessageBox.information(
                self, self.tr('Success!'),
                self.widgetName + self.tr(' successfully imported.'))
        except Exception as e:
            QApplication.restoreOverrideCursor()
            QMessageBox.critical(
                self, self.tr('Error!'),
                self.tr('Error! Problem importing ') + self.widgetName + ': ' +
                ':'.join(e.args))

    @pyqtSlot(bool)
    def on_applyPushButton_clicked(self):
        dbList = list(self.genericDbManager.dbDict.keys())
        successDict, exceptionDict = self.manageSettings(
            GenericManagerWidget.Install, dbList=dbList)
        if successDict == {} and exceptionDict == {}:
            return
        header, operation = self.getApplyHeader()
        self.outputMessage(operation, header, successDict, exceptionDict)

    @pyqtSlot(bool)
    def on_deletePushButton_clicked(self):
        successDict, exceptionDict = self.manageSettings(
            GenericManagerWidget.Delete)
        if successDict == {} and exceptionDict == {}:
            return
        header, operation = self.getDeleteHeader()
        self.outputMessage(operation, header, successDict, exceptionDict)

    @pyqtSlot(bool)
    def on_uninstallFromSelectedPushButton_clicked(self):
        dbList = []
        successDict, exceptionDict = self.manageSettings(
            GenericManagerWidget.Uninstall, dbList)
        if successDict == {} and exceptionDict == {}:
            return
        header, operation = self.getUninstallFromSelected()
        self.outputMessage(operation, header, successDict, exceptionDict)

    def getViewType(self):
        if self.databasePerspectivePushButton.isChecked():
            return DsgEnums.Database
        else:
            return DsgEnums.Property

    @pyqtSlot(bool, name='on_databasePerspectivePushButton_clicked')
    @pyqtSlot(bool, name='on_propertyPerspectivePushButton_clicked')
    def refresh(self):
        viewType = self.setHeaders()
        propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(
            viewType)
        self.treeWidget.clear()
        rootNode = self.treeWidget.invisibleRootItem()
        if viewType == DsgEnums.Database:
            propertyList = list(self.genericDbManager.dbDict.keys())
        else:
            propertyList = list(propertyPerspectiveDict.keys())
        for key in propertyList:
            parentCustomItem = self.utils.createWidgetItem(rootNode, key, 0)
            if key in list(propertyPerspectiveDict.keys()):
                for item in propertyPerspectiveDict[key]:
                    if item and item != '':
                        dbItem = self.utils.createWidgetItem(
                            parentCustomItem, item, 1)
        self.treeWidget.sortItems(0, Qt.AscendingOrder)
        self.treeWidget.expandAll()
        self.treeWidget.header().setSectionResizeMode(
            QtWidgets.QHeaderView.ResizeToContents)
        self.treeWidget.header().setStretchLastSection(False)

    def outputMessage(self, operation, header, successDict, exceptionDict):
        """
        successDict = {configName: [--list of successful databases--]}
        exceptionDict = {configName: {dbName: errorText}}
        """
        viewType = self.getViewType()
        msg = header
        for setting in list(successDict.keys()):
            successList = successDict[setting]
            if len(successDict[setting]) > 0:
                msg += self.tr('\nSuccessful ')
                msg += operation + ' : '
                msg += setting
                if successList:
                    if len(successList) > 0:
                        try:
                            msg += self.tr(' on databases ') + ', '.join(
                                successList)
                        except:  #none type case, just add .
                            msg += '.'
        msg += self.logInternalError(exceptionDict)
        QMessageBox.warning(self, self.tr('Operation Complete!'), msg)

    def logInternalError(self, exceptionDict):
        """
        exceptionDict = {configName: {dbName: errorText}}
        """
        msg = ''
        configList = list(exceptionDict.keys())
        if len(configList) > 0:
            msg += self.tr('\nConfig with error:') + ','.join(configList)
            msg += self.tr(
                '\nError messages for each config and database were output in qgis log.'
            )
            for config in configList:
                for dbName in list(exceptionDict[config].keys()):
                    if exceptionDict[config][dbName] != dict():
                        QgsMessageLog.logMessage(
                            self.tr('Error for config ') + config +
                            ' in database ' + dbName + ' : ' +
                            exceptionDict[config][dbName], "DSGTools Plugin",
                            Qgis.Critical)
        return msg

    def manageSetting(self,
                      config,
                      manageType,
                      dbList=[],
                      parameterDict=dict()):
        if manageType == GenericManagerWidget.Install:
            return self.genericDbManager.installSetting(config,
                                                        dbNameList=dbList)
        elif manageType == GenericManagerWidget.Delete:
            return self.genericDbManager.deleteSetting(config)
        elif manageType == GenericManagerWidget.Uninstall:
            return self.genericDbManager.uninstallSetting(config,
                                                          dbNameList=dbList)
        elif manageType == GenericManagerWidget.Update:
            return self.genericDbManager.updateSetting(
                config, parameterDict['newJsonDict'])
        elif manageType == GenericManagerWidget.Create:
            return self.genericDbManager.createSetting(
                config, parameterDict['newJsonDict'])

    def selectConfig(self):
        availableConfig = list(
            self.genericDbManager.getPropertyPerspectiveDict().keys())
        dlg = ListSelector(availableConfig, [])
        res = dlg.exec_()
        if res == 0:
            # to identify when user presses Cancel
            return None
        selectedConfig = dlg.getSelected()
        return selectedConfig

    def manageSettings(self,
                       manageType,
                       dbList=None,
                       selectedConfig=None,
                       parameterDict=dict()):
        """
        Executes the setting work according to manageType
        successDict = {configName: [--list of successful databases--]}
        exceptionDict = {configName: {dbName: errorText}}
        """

        if selectedConfig is None:
            selectedConfig = self.selectConfig()
            if selectedConfig is None:
                # user cancelled
                return dict(), dict()
            if selectedConfig == []:
                QMessageBox.warning(
                    self, self.tr('Warning!'),
                    self.tr('Select at least one configuration!'))
                return (dict(), dict())
        successDict = dict()
        exceptionDict = dict()
        dbList = [] if dbList is None else dbList
        if self.lookAndPromptForStructuralChanges(dbList=dbList):
            for config in selectedConfig:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                sucessList, errorDict = self.manageSetting(
                    config,
                    manageType,
                    dbList=dbList,
                    parameterDict=parameterDict)
                QApplication.restoreOverrideCursor()
                successDict[config] = sucessList
                if errorDict != dict():
                    exceptionDict[config] = errorDict
            self.refresh()
            return successDict, exceptionDict
        else:
            QMessageBox.warning(self, self.tr('Warning!'),
                                self.tr('Operation canceled by user!'))
            return (dict(), dict())

    def createMenuAssigned(self, position):
        """
        Creates a pop up menu
        """
        viewType = self.getViewType()
        if viewType == DsgEnums.Database:
            self.createDbPerspectiveContextMenu(position)
        if viewType == DsgEnums.Property:
            self.createPropertyPerspectiveContextMenu(position)

    def createDbPerspectiveContextMenu(self, position):
        menu = QMenu()
        item = self.treeWidget.itemAt(position)
        if item:
            if item.text(0) != '':
                menu.addAction(
                    self.tr('Uninstall all settings from selected database'),
                    self.uninstallSettings)
                menu.addAction(
                    self.tr('Manage settings from selected database'),
                    self.manageDbSettings)
            elif item.text(1) != '':
                menu.addAction(self.tr('Update selected setting'),
                               self.updateSelectedSetting)
                menu.addAction(self.tr('Clone selected setting'),
                               self.cloneSelectedSetting)
                menu.addAction(self.tr('Uninstall selected setting'),
                               self.uninstallSettings)
                menu.addAction(self.tr('Delete selected setting'),
                               self.deleteSelectedSetting)
        menu.exec_(self.treeWidget.viewport().mapToGlobal(position))

    def createPropertyPerspectiveContextMenu(self, position):
        menu = QMenu()
        item = self.treeWidget.itemAt(position)
        if item:
            if item.text(0) != '':
                menu.addAction(self.tr('Update selected setting'),
                               self.updateSelectedSetting)
                menu.addAction(self.tr('Clone selected setting'),
                               self.cloneSelectedSetting)
                menu.addAction(self.tr('Manage selected setting'),
                               self.manageSelectedSetting)
                menu.addAction(
                    self.tr('Uninstall selected setting on all databases'),
                    self.uninstallSettings)
                menu.addAction(self.tr('Delete selected setting'),
                               self.deleteSelectedSetting)
            elif item.text(1) != '':
                menu.addAction(self.tr('Manage Settings on database'),
                               self.manageDbSettings)
                menu.addAction(
                    self.tr('Uninstall selected setting on selected database'),
                    self.uninstallSettings)
        menu.exec_(self.treeWidget.viewport().mapToGlobal(position))

    def manageDbSettings(self):
        """
        1. get installed profiles and available profiles
        2. populate selection with items from #1
        3. get final lists and uninstall items and them install items
        """
        uiParameterDict = self.getParametersFromInterface()
        propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(
        )
        availableConfig = [
            i for i in list(propertyPerspectiveDict.keys())
            if i not in uiParameterDict['parameterList']
        ]
        dlg = ListSelector(availableConfig, uiParameterDict['parameterList'])
        dlg.exec_()
        fromLs, toLs = dlg.getInputAndOutputLists()
        #build install list: elements from toLs that were not in uiParameterDict['parameterList']
        installList = [
            i for i in toLs if i not in uiParameterDict['parameterList']
        ]
        #build uninstall list: : elements fromLs that were not in availableConfig
        uninstallList = [
            i for i in fromLs if i in uiParameterDict['parameterList']
        ]
        if (installList == [] and uninstallList == []):
            QMessageBox.warning(
                self, self.tr('Error!'),
                self.tr('Select at least one configuration to manage!'))
            return
        if installList != []:
            #install:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Install,
                selectedConfig=installList,
                dbList=uiParameterDict['databaseList'])
            header, operation = self.getApplyHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)
        if uninstallList != []:
            #uninstall:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Uninstall,
                selectedConfig=uninstallList,
                dbList=uiParameterDict['databaseList'])
            header, operation = self.getUninstallSelectedSettingHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)

    def manageSelectedSetting(self):
        """
        1. get installed profiles and available profiles
        2. populate selection with items from #1
        3. get final lists and uninstall items and them install items
        """
        uiParameterDict = self.getParametersFromInterface()
        propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(
            viewType=DsgEnums.Database)
        availableDb = [
            i for i in list(propertyPerspectiveDict.keys())
            if i not in uiParameterDict['databaseList']
        ]
        dlg = ListSelector(availableDb, uiParameterDict['databaseList'])
        dlg.exec_()
        fromLs, toLs = dlg.getInputAndOutputLists()
        #build install list: elements from toLs that were not in uiParameterDict['parameterList']
        installList = [
            i for i in toLs if i not in uiParameterDict['databaseList']
        ]
        #build uninstall list: : elements fromLs that were not in availableConfig
        uninstallList = [
            i for i in fromLs if i in uiParameterDict['databaseList']
        ]
        if (installList == [] and uninstallList == []):
            QMessageBox.warning(
                self, self.tr('Error!'),
                self.tr(
                    'Select at least one configuration database to manage!'))
            return
        if installList != []:
            #install:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Install,
                selectedConfig=uiParameterDict['parameterList'],
                dbList=installList)
            header, operation = self.getApplyHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)
        if uninstallList != []:
            #uninstall:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Uninstall,
                selectedConfig=uiParameterDict['parameterList'],
                dbList=uninstallList)
            header, operation = self.getUninstallSelectedSettingHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)

    def updateSelectedSetting(self):
        """
        1. get setting dict
        2. populate setting interface
        3. from new dict, update setting
        """
        currItem = self.treeWidget.currentItem()
        if self.getViewType() == DsgEnums.Database:
            settingName = currItem.text(1)
        else:
            settingName = currItem.text(0)
        edgvVersion = self.genericDbManager.edgvVersion
        templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion)
        originalDict = self.genericDbManager.getSetting(
            settingName, edgvVersion)
        newDict = self.populateConfigInterface(templateDb,
                                               jsonDict=originalDict)
        if newDict:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Update,
                selectedConfig=[settingName],
                parameterDict={'newJsonDict': newDict})
            header, operation = self.getUpdateSelectedSettingHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)

    def cloneSelectedSetting(self):
        currItem = self.treeWidget.currentItem()
        if self.getViewType() == DsgEnums.Database:
            settingName = currItem.text(1)
        else:
            settingName = currItem.text(0)
        edgvVersion = self.genericDbManager.edgvVersion
        templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion)
        originalDict = self.genericDbManager.getSetting(
            settingName, edgvVersion)
        newDict = self.populateConfigInterface(templateDb,
                                               jsonDict=originalDict)
        if newDict:
            successDict, exceptionDict = self.manageSettings(
                GenericManagerWidget.Create,
                selectedConfig=[settingName],
                parameterDict={'newJsonDict': newDict})
            header, operation = self.getUpdateSelectedSettingHeader()
            self.outputMessage(operation, header, successDict, exceptionDict)

    def getParametersFromInterface(self):
        """
        Gets selected database and selected property. 
        Returns {'databaseList':dbList, 'parameterList':parameterList}
        """
        currItem = self.treeWidget.currentItem()
        if self.getViewType() == DsgEnums.Database:
            #2 possibilities: leaf (if first column is '') or parent (if first column != '')
            if currItem.text(0) == '':
                #leaf -> must get
                parentNode = currItem.parent()
                dbName = parentNode.text(0)
                parameter = currItem.text(1)
                return {'databaseList': [dbName], 'parameterList': [parameter]}
            else:
                #parent
                dbName = currItem.text(0)
                childCount = currItem.childCount()
                parameterList = []
                for i in range(childCount):
                    childNode = currItem.child(i)
                    parameterName = childNode.text(1)
                    if parameterName not in parameterList:
                        parameterList.append(parameterName)
                return {
                    'databaseList': [dbName],
                    'parameterList': parameterList
                }
        else:
            if currItem.text(0) == '':
                #leaf
                parentNode = currItem.parent()
                parameter = parentNode.text(0)
                dbName = currItem.text(1)
                return {'databaseList': [dbName], 'parameterList': [parameter]}
            else:
                #parent
                parameter = currItem.text(0)
                childCount = currItem.childCount()
                dbList = []
                for i in range(childCount):
                    childNode = currItem.child(i)
                    dbName = childNode.text(1)
                    if dbName not in dbList:
                        dbList.append(dbName)
                return {'databaseList': dbList, 'parameterList': [parameter]}

    def uninstallSettings(self):
        edgvVersion = self.genericDbManager.edgvVersion
        uiParameterDict = self.getParametersFromInterface()
        successDict, exceptionDict = self.manageSettings(
            GenericManagerWidget.Uninstall,
            dbList=uiParameterDict['databaseList'],
            selectedConfig=uiParameterDict['parameterList'])
        header, operation = self.getUninstallSelectedSettingHeader()
        self.outputMessage(operation, header, successDict, exceptionDict)

    def deleteSelectedSetting(self):
        edgvVersion = self.genericDbManager.edgvVersion
        uiParameterDict = self.getParametersFromInterface()
        settingTextList = ', '.join(uiParameterDict['parameterList'])
        if QMessageBox.question(
                self, self.tr('Question'),
                self.tr('Do you really want to delete ') + settingTextList +
                '?',
                QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Cancel:
            return
        successDict, exceptionDict = self.manageSettings(
            GenericManagerWidget.Delete,
            selectedConfig=uiParameterDict['parameterList'])
        header, operation = self.getDeleteHeader()
        self.outputMessage(operation, header, successDict, exceptionDict)

    def lookAndPromptForStructuralChanges(self, dbList=[]):
        '''
        Returns True if user accepts the process
        '''
        structuralChanges = self.genericDbManager.hasStructuralChanges(dbList)
        if structuralChanges != []:
            dbChangeList = ', '.join(structuralChanges)
            if QMessageBox.question(
                    self, self.tr('Question'),
                    self.tr(
                        'Do you really want to apply selected operation on ') +
                    dbChangeList + '?' +
                    self.tr(' (Data may be lost in the process)'),
                    QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Cancel:
                return False
            else:
                return True
        else:
            return True
class CreateDatabaseCustomization(QtWidgets.QDialog, FORM_CLASS):
    def __init__(self,
                 customizationName,
                 abstractDb,
                 edgvVersion,
                 customizationManager,
                 customJsonDict=None,
                 parent=None):
        """Constructor."""
        super(self.__class__, self).__init__(parent)
        self.setupUi(self)
        self.customizationManager = customizationManager
        self.abstractDb = abstractDb
        self.edgvVersion = edgvVersion
        self.customizationName = customizationName
        self.contentsDict = dict()
        self.populateCustomizationCombo()
        self.setWidgetsEnabled(True)
        self.utils = Utils()
        if customJsonDict:
            self.createWidgetsFromCustomJsonDict(customJsonDict)

    def clearWidgets(self):
        rootItem = self.customizationTreeWidget.invisibleRootItem()
        childNodeCount = rootItem.childCount()
        #remove widgets
        for i in range(childNodeCount):
            typeChild = rootItem.child(i)
            childCount = typeChild.childCount()
            childTextList = []
            for j in range(childCount):
                childTextList.append(typeChild.child(i).text(0))
            for childText in childTextList:
                self.removeWidget(widgetText=childText)

    def setWidgetsEnabled(self, enabled):
        self.customizationSelectionComboBox.setEnabled(enabled)
        self.addAttributePushButton.setEnabled(enabled)
        self.customizationTreeWidget.setEnabled(enabled)
        self.removeSelectedPushButton.setEnabled(enabled)

    def populateCustomizationCombo(self):
        '''
        Populates the customization combo and also defines customDict.
        '''
        self.customDict = dict()
        self.customDict['attribute'] = self.tr('Attribute Customization')
        self.customDict['class'] = self.tr('Class Customization')
        self.customDict['codeName'] = self.tr('Code Name Customization')
        self.customDict['default'] = self.tr('Default Customization')
        self.customDict['domain'] = self.tr('Domain Customization')
        self.customDict['domainValue'] = self.tr('Domain Value Customization')
        self.customDict['nullity'] = self.tr('Attribute Nullity Customization')
        self.customDict['filter'] = self.tr('Attribute Filter Customization')
        rootNode = self.customizationTreeWidget.invisibleRootItem()
        for type in list(self.customDict.keys()):
            if self.customDict[type] not in list(self.contentsDict.keys()):
                self.contentsDict[self.customDict[type]] = dict()
            self.customizationSelectionComboBox.addItem(self.customDict[type])
            self.contentsDict[self.customDict[type]]['widgetList'] = []
            self.contentsDict[
                self.customDict[type]]['treeItem'] = self.createItem(
                    rootNode, self.customDict[type], 0)
        self.customizationTreeWidget.expandAll()

    @pyqtSlot(bool)
    def on_addAttributePushButton_clicked(self):
        if self.customizationSelectionComboBox.currentText() == self.tr(
                'Attribute Customization'):
            self.addAttributeWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Class Customization'):
            self.addClassWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Code Name Customization'):
            self.addCodeNameWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Default Customization'):
            self.addDefaultWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Domain Customization'):
            self.addDomainWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Domain Value Customization'):
            self.addDomainValueWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Attribute Nullity Customization'):
            self.addNullityWidget()
        elif self.customizationSelectionComboBox.currentText() == self.tr(
                'Attribute Filter Customization'):
            self.addFilterWidget()
        else:
            QMessageBox.warning(self, self.tr('Warning'),
                                self.tr('Select a custom operation!'))

    def addWidgetItem(self, contentsKey, widgetTitle, widget):
        widgetList = self.contentsDict[contentsKey]['widgetList']
        if len(widgetList) > 0:
            i = int(widgetList[-1].layout().itemAt(
                0).widget().getTitle().split('#')[-1])
        else:
            i = 0
        title = widgetTitle + ' #{0}'.format(i + 1)  #add number
        widget.setTitle(title)
        self.contentsDict[contentsKey]['widgetList'].append(
            self.addWidget(widget, title))
        self.createItem(self.contentsDict[contentsKey]['treeItem'], title, 0)

    def addAttributeWidget(self, uiParameterJsonDict=None):
        widget = NewAttributeWidget(self.abstractDb,
                                    uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Attribute Customization'),
                           self.tr('New Custom Attribute'), widget)

    def addClassWidget(self, uiParameterJsonDict=None):
        widget = NewClassWidget(self.abstractDb,
                                uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Class Customization'),
                           self.tr('New Custom Class'), widget)

    def addCodeNameWidget(self, uiParameterJsonDict=None):
        widget = CodeNameCustomizationWidget(
            self.abstractDb, uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Code Name Customization'),
                           self.tr('New Custom Code Name'), widget)

    def addDefaultWidget(self, uiParameterJsonDict=None):
        widget = AlterDefaultWidget(self.abstractDb,
                                    uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Default Customization'),
                           self.tr('New Custom Default'), widget)

    def addDomainWidget(self, uiParameterJsonDict=None):
        widget = NewDomainWidget(self.abstractDb,
                                 uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Domain Customization'),
                           self.tr('New Custom Domain'), widget)

    def addDomainValueWidget(self, uiParameterJsonDict=None):
        widget = NewDomainValueWidget(self.abstractDb,
                                      uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Domain Value Customization'),
                           self.tr('New Domain Value'), widget)

    def addNullityWidget(self, uiParameterJsonDict=None):
        widget = ChangeNullityWidget(self.abstractDb,
                                     uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Attribute Nullity Customization'),
                           self.tr('New Custom Attribute Nullity'), widget)

    def addFilterWidget(self, uiParameterJsonDict=None):
        widget = ChangeFilterWidget(self.abstractDb,
                                    uiParameterJsonDict=uiParameterJsonDict)
        self.addWidgetItem(self.tr('Attribute Filter Customization'),
                           self.tr('New Custom Attribute Filter'), widget)

    def addWidget(self, widget, title):
        layout = QtGui.QFormLayout()
        layout.addRow(widget)
        groupBox = QgsCollapsibleGroupBox(title)
        groupBox.setCollapsed(False)
        groupBox.setSaveCollapsedState(False)
        groupBox.setLayout(layout)
        self.scrollAreaLayout.addWidget(groupBox)
        return groupBox

    def createItem(self, parent, text, column):
        item = QtWidgets.QTreeWidgetItem(parent)
        item.setText(column, text)
        return item

    def getWidgetIndexFromTreeItem(self, treeItem):
        parent = treeItem.parent()
        widgetName = treeItem.text(0)
        if not parent:
            return
        if parent == self.customizationTreeWidget.invisibleRootItem():
            return None
        childCount = parent.childCount()
        for i in range(childCount):
            child = parent.child(i)
            if child.text(0) == widgetName:
                return i

    @pyqtSlot(bool, name='on_removeSelectedPushButton_clicked')
    def removeWidget(self, widgetText=None):
        if not widgetText:
            treeItemList = [self.customizationTreeWidget.currentItem()]
        else:
            treeItemList = self.customizationTreeWidget.findItems(
                widgetText, flags=Qt.MatchExactly)
        if len(treeItemList) > 0:
            for treeItem in treeItemList:
                parent = treeItem.parent()
                if parent == self.customizationTreeWidget.invisibleRootItem():
                    return
                idx = self.getWidgetIndexFromTreeItem(treeItem)
                itemToRemove = self.contentsDict[parent.text(
                    0)]['widgetList'].pop(idx)
                itemToRemove.setParent(None)
                self.contentsDict[parent.text(0)]['treeItem'].removeChild(
                    treeItem)

    @pyqtSlot()
    def on_buttonBox_accepted(self):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        exceptionList = []
        customJsonDict = dict()
        for i in list(self.customDict.keys()):
            customJsonDict[i] = []
        correspondenceDict = {
            self.customDict[i]: i
            for i in list(self.customDict.keys())
        }
        nCustom = 0
        for key in list(self.contentsDict.keys()):
            for widgetItem in self.contentsDict[key]['widgetList']:
                nCustom += 1
        progress = ProgressWidget(
            1,
            nCustom,
            self.tr('Preparing to export customizations... '),
            parent=self)
        progress.initBar()
        for key in list(self.contentsDict.keys()):
            jsonTagList = []
            for widget in self.contentsDict[key]['widgetList']:
                currJsonItem = {'jsonUi': None, 'dbJsonTagList': []}
                currentWidget = widget.layout().itemAt(0).widget()
                try:
                    jsonTagList = currentWidget.getJSONTag()
                    jsonUi = currentWidget.getUiParameterJsonDict()
                except Exception as e:
                    exceptionList.append(':'.join(e.args))
                if len(exceptionList) == 0:
                    currJsonItem['jsonUi'] = jsonUi
                    for jsonItem in jsonTagList:
                        if jsonItem not in currJsonItem['dbJsonTagList']:
                            currJsonItem['dbJsonTagList'].append(jsonItem)
                    if currJsonItem not in customJsonDict[
                            correspondenceDict[key]]:
                        customJsonDict[correspondenceDict[key]].append(
                            currJsonItem)
                progress.step()
        QApplication.restoreOverrideCursor()
        if self.validateJsonDict(customJsonDict) and len(exceptionList) == 0:
            versionText = 'database_' + self.edgvVersion
            finalJsonDict = {versionText: customJsonDict}
            self.customizationManager.createSetting(self.customizationName,
                                                    self.edgvVersion,
                                                    finalJsonDict)
            QMessageBox.information(
                self, self.tr('Success!'),
                self.tr('Database Customization ') + self.customizationName +
                self.tr(' created successfuly!'))
            #EMIT to reload?
            self.close()
        else:
            msg = ''
            if len(exceptionList) > 0:
                msg += self.tr(
                    '\Errors occured while trying to export customs built. Check qgis log for further details.'
                )
                for error in exceptionList:
                    QgsMessageLog.logMessage(
                        self.tr('Customization error: ') + error,
                        "DSGTools Plugin", Qgis.Critical)
                QMessageBox.warning(self, self.tr('Error!'), msg)

    def validateJsonDict(self, customJsonDict):
        """
        Method to apply validation to customJsonDict
        """
        #TODO
        return True

    def populateWidgetsFromSelectedFile(self):
        jsonFileName = self.selectFileWidget.fileNameList
        customJsonDict = self.utils.readJsonFile(jsonFileName)
        self.createWidgetsFromCustomJsonDict(customJsonDict)

    def createWidgetsFromCustomJsonDict(self, customJsonDict):
        for key in list(customJsonDict.keys()):
            for jsonTag in customJsonDict[key]:
                self.createWidgetFromKey(key, jsonTag['jsonUi'])

    def createWidgetFromKey(self, key, uiParameterJsonDict):
        if key == 'attribute':
            self.addAttributeWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'class':
            self.addClassWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'codeName':
            self.addCodeNameWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'default':
            self.addDefaultWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'domain':
            self.addDomainWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'domainValue':
            self.addDomainValueWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'nullity':
            self.addNullityWidget(uiParameterJsonDict=uiParameterJsonDict)
        elif key == 'filter':
            self.addFilterWidget(uiParameterJsonDict=uiParameterJsonDict)
        else:
            pass
Пример #17
0
class GenericDbManager(QObject):
    """
    This class manages the permissions on dsgtools databases.
    """
    def __init__(self,
                 serverAbstractDb,
                 dbDict,
                 edgvVersion,
                 parentWidget=None):
        super(GenericDbManager, self).__init__()
        self.parentWidget = parentWidget
        self.dbDict = dbDict
        self.serverAbstractDb = serverAbstractDb
        self.adminDb = self.instantiateAdminDb(serverAbstractDb)
        self.utils = Utils()
        self.extensionDict = {
            'EarthCoverage': '.dsgearthcov',
            'Customization': '.dsgcustom',
            'Style': '.dsgstyle',
            'ValidationConfig': '.dsgvalidcfg',
            'FieldToolBoxConfig': '.reclas',
            'Permission': '.dsgperm',
            'AttributeRules': '.dsgattrrul',
            'SpatialRules': '.dsgspatrul',
            'ValidationWorkspace': '.dsgworksp'
        }
        self.edgvVersion = edgvVersion
        self.createPropertyTable()

    def getManagerType(self):
        return str(self.__class__).split('.')[-1].replace('\'>', '').replace(
            'Manager', '')

    def instantiateAbstractDb(self, dbName):
        """
        Instantiates an abstractDb.
        """
        if dbName not in list(self.dbDict.keys()):
            (host, port, user,
             password) = self.serverAbstractDb.getParamsFromConectedDb()
            abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS)
            abstractDb.connectDatabaseWithParameters(host, port, dbName, user,
                                                     password)
        else:
            abstractDb = self.dbDict[dbName]
        return abstractDb

    def instantiateAdminDb(self, serverAbstractDb):
        """
        Instantiates dsgtools_admindb in the same server as serverAbstractDb. 
        If dsgtools_admindb does not exists, instantiateAdminDb calls createAdminDb
        """
        (host, port, user,
         password) = serverAbstractDb.getParamsFromConectedDb()
        adminDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS)
        if not serverAbstractDb.hasAdminDb():
            return self.createAdminDb(serverAbstractDb, adminDb, host, port,
                                      user, password)
        adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb',
                                              user, password)
        managerType = self.getManagerType()
        if not adminDb.checkIfExistsConfigTable(managerType):
            adminDb.createPropertyTable(managerType, isAdminDb=True)
        return adminDb

    def instantiateTemplateDb(self, edgvVersion):
        """
        Instantiates a templateDb in the same server as serverAbstractDb. 
        If template does not exists, instantiateAdminDb calls createTemplate
        """
        templateName = self.serverAbstractDb.getTemplateName(edgvVersion)
        hasTemplate = self.serverAbstractDb.checkTemplate(edgvVersion)
        if not hasTemplate:
            self.serverAbstractDb.createTemplateDatabase(edgvVersion)
            templateDb = self.instantiateAbstractDb(templateName)
            templateDb.setStructureFromSql(edgvVersion, 4674)
            templateDb.setDbAsTemplate(version=edgvVersion)
        else:
            templateDb = self.instantiateAbstractDb(templateName)
        return templateDb

    def createAdminDb(self, serverAbstractDb, adminDb, host, port, user,
                      password):
        """
        Creates dsgtools_admindb
        """
        serverAbstractDb.createAdminDb()
        adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb',
                                              user, password)
        sqlPath = adminDb.getCreationSqlPath('admin')
        adminDb.runSqlFromFile(sqlPath)
        return adminDb

    def getSettings(self):
        """
        Gets all profiles from public.permission_profile
        """
        settingType = self.getManagerType()
        return self.adminDb.getAllSettingsFromAdminDb(settingType)

    def getSetting(self, name, edgvVersion):
        """
        Get setting from corresponding table on dsgtools_admindb
        """
        settingType = self.getManagerType()
        settingDict = json.loads(
            self.adminDb.getSettingFromAdminDb(settingType, name, edgvVersion))
        if not settingDict:
            raise Exception(
                self.tr("Setting ") + settingType +
                self.tr(" not found on dsgtools_admindb!"))
        return settingDict

    def createSetting(self, settingName, edgvVersion, jsonDict):
        """
        Creates setting on dsgtools_admindb.
        """
        settingType = self.getManagerType()
        if isinstance(jsonDict, dict):
            jsonDict = json.dumps(jsonDict, sort_keys=True, indent=4)
        self.adminDb.insertSettingIntoAdminDb(settingType, settingName,
                                              jsonDict, edgvVersion)

    def updateSetting(self, settingName, newJsonDict, edgvVersion=None):
        """
        Generic update. Can be reimplenented in child methods.
        1. Get property dict from adminDb 
        """
        if not edgvVersion:
            edgvVersion = self.edgvVersion
        errorDict = dict()
        successList = []
        settingType = self.getManagerType()
        propertyDict = self.adminDb.getPropertyPerspectiveDict(
            settingType, DsgEnums.Property, versionFilter=edgvVersion)
        if settingName in list(propertyDict.keys()):
            rollbackList = []
            self.adminDb.db.transaction()
            try:
                for dbName in propertyDict[settingName]:
                    abstractDb = self.instantiateAbstractDb(dbName)
                    abstractDb.db.transaction()
                    rollbackList.append(abstractDb)
                    self.updateMaterializationFromDatabase(
                        abstractDb, propertyDict)
                    abstractDb.updateRecordFromPropertyTable(
                        settingType, settingName, edgvVersion, newJsonDict)
                self.adminDb.updateRecordFromPropertyTable(
                    settingType, settingName, edgvVersion, newJsonDict)
                for abstractDb in rollbackList:
                    abstractDb.db.commit()
                self.adminDb.db.commit()
                successList = [i for i in propertyDict[settingName]]
            except Exception as e:
                for abstractDb in rollbackList:
                    abstractDb.db.rollback()
                self.adminDb.db.rollback()
                errorDict[dbName] = ':'.join(e.args)
        return (successList, errorDict)

    def importSetting(self, fullFilePath):
        """
        Function to import profile into dsgtools_admindb. It has the following steps:
        1. Reads inputJsonFilePath and parses it into a python dict;
        2. Validates inputPermissionDict;
        3. Tries to insert into database, if there is an error, abstractDb raises an error which is also raised by importProfile
        """
        #getting profile name
        settingName = os.path.basename(fullFilePath).split('.')[0]
        #getting json
        inputJsonDict, inputJson = self.utils.readJsonFile(
            fullFilePath, returnFileAndDict=True)
        #error handling and json validation
        if inputJsonDict == dict():
            raise Exception(self.tr("Not valid DsgTools property file!"))
        if not self.validateJsonSetting(inputJsonDict):
            raise Exception(self.tr("Not valid DsgTools property file!"))
        if 'version' in list(inputJsonDict.keys()):
            edgvVersion = inputJsonDict['version']
        else:
            edgvVersion = list(inputJsonDict.keys())[0].split('_')[-1]
        try:
            self.createSetting(settingName, edgvVersion, inputJson)
        except Exception as e:
            raise Exception(
                self.tr("Error importing setting ") + settingName + ': ' +
                ':'.join(e.args))

    def batchImportSettings(self, profilesDir):
        """
        1. Get all properties in profilesDir;
        2. Import each using importSetting;
        """
        importList = []
        for profile in next(os.walk(profilesDir))[2]:
            if self.extensionDict[self.getManagerType()] in os.path.basename(
                    profile):
                importList.append(os.path.join(profilesDir, profile))
        for profileFile in importList:
            self.importSetting(profileFile)

    def exportSetting(self, profileName, edgvVersion, outputPath):
        """
        1. Get setting from dsgtools_admindb;
        2. Export it to outputPath.
        """
        jsonDict = self.getSetting(profileName, edgvVersion)
        if not os.path.exists(outputPath):
            os.makedirs(outputPath)
        outputFile = os.path.join(
            outputPath,
            profileName + self.extensionDict[self.getManagerType()])
        with open(outputFile, 'w') as outfile:
            json.dump(jsonDict, outfile, sort_keys=True, indent=4)

    def batchExportSettings(self, outputDir):
        """
        1. Get all settings from corresponding table in dsgtools_admindb;
        2. Export each using exportSetting.
        """
        settingDict = self.getSettings()
        for edgvVersion in list(settingDict.keys()):
            outputPath = os.path.join(outputDir, edgvVersion)
            if not os.path.exists(outputPath):
                os.makedirs(outputPath)
            for profileName in settingDict[edgvVersion]:
                self.exportSetting(profileName, edgvVersion, outputPath)

    def getPropertyPerspectiveDict(self,
                                   viewType=DsgEnums.Property,
                                   versionFilter=None):
        """
        Gets a dict in the format:
        if viewType == 'customization': {customizationName: ['-list of databases with customization']}
        if viewType == 'database': {databaseName: ['-list of customizations with customization']}
        """
        settingType = self.getManagerType()
        return self.adminDb.getPropertyPerspectiveDict(
            settingType, viewType, versionFilter=versionFilter)

    def getSettingVersion(self, settingName):
        settingType = self.getManagerType()
        return self.adminDb.getSettingVersion(settingType, settingName)

    def validateJsonSetting(self, inputJsonDict):
        """
        reimplemented in each child
        """
        return True

    def getRecordFromAdminDb(self, propertyName, edgvVersion):
        settingType = self.getManagerType()
        return self.adminDb.getRecordFromAdminDb(settingType, propertyName,
                                                 edgvVersion)

    def createAndInstall(self,
                         configName,
                         newJsonDict,
                         edgvVersion,
                         dbList=[]):
        self.createSetting(configName, edgvVersion, newJsonDict)
        return self.installSetting(configName, dbNameList=dbList)

    def installSetting(self, configName, dbNameList=[]):
        """
        Generic install. Can be reimplenented in child methods.
        """
        errorDict = dict()
        settingType = self.getManagerType()
        if dbNameList == []:
            dbNameList = list(self.dbDict.keys())
        successList = []
        configEdgvVersion = self.getSettingVersion(configName)
        for dbName in dbNameList:
            abstractDb = self.instantiateAbstractDb(dbName)
            edgvVersion = abstractDb.getDatabaseVersion()
            if edgvVersion != configEdgvVersion:
                errorDict[dbName] = self.tr('Database version missmatch.')
                continue
            recDict = self.adminDb.getRecordFromAdminDb(
                settingType, configName, edgvVersion)
            try:
                if not abstractDb.checkIfExistsConfigTable(settingType):
                    abstractDb.createPropertyTable(settingType,
                                                   useTransaction=True)
            except Exception as e:
                errorDict[dbName] = ':'.join(e.args)
                continue
            try:
                abstractDb.db.transaction()
                self.adminDb.db.transaction()
                self.materializeIntoDatabase(
                    abstractDb, recDict
                )  #step done when property management involves changing database structure
                abstractDb.insertRecordInsidePropertyTable(
                    settingType, recDict, edgvVersion)
                dbOid = abstractDb.getDbOID()
                self.adminDb.insertInstalledRecordIntoAdminDb(
                    settingType, recDict, dbOid)
                abstractDb.db.commit()
                self.adminDb.db.commit()
            except Exception as e:
                abstractDb.db.rollback()
                self.adminDb.db.rollback()
                errorDict[dbName] = ':'.join(e.args)
            successList.append(dbName)
        return (successList, errorDict)

    def deleteSetting(self, configName, dbNameList=[]):
        """
        Generic remove. Can be reimplenented in child methods.
        1. Get property dict from adminDb 
        """
        errorDict = dict()
        successList = []
        settingType = self.getManagerType()
        propertyDict = self.adminDb.getPropertyPerspectiveDict(
            settingType, DsgEnums.Property)
        if configName in list(propertyDict.keys()):
            for dbName in propertyDict[configName]:
                if not dbName:
                    try:
                        self.adminDb.db.transaction()
                        self.adminDb.removeRecordFromPropertyTable(
                            settingType, configName, None)
                        self.adminDb.db.commit()
                        successList.append(dbName)
                    except Exception as e:
                        self.adminDb.db.rollback()
                        errorDict[dbName] = ':'.join(e.args)
                else:
                    abstractDb = self.instantiateAbstractDb(dbName)
                    edgvVersion = abstractDb.getDatabaseVersion()
                    try:
                        abstractDb.db.transaction()
                        self.adminDb.db.transaction()
                        self.undoMaterializationFromDatabase(
                            abstractDb, configName, settingType, edgvVersion
                        )  #step done when property management involves changing database structure
                        abstractDb.removeRecordFromPropertyTable(
                            settingType, configName, edgvVersion)
                        self.adminDb.removeRecordFromPropertyTable(
                            settingType, configName, edgvVersion)
                        abstractDb.db.commit()
                        self.adminDb.db.commit()
                        successList.append(dbName)
                    except Exception as e:
                        abstractDb.db.rollback()
                        self.adminDb.db.rollback()
                        errorDict[dbName] = ':'.join(e.args)
        return (successList, errorDict)

    def uninstallSetting(self, configName, dbNameList=[]):
        """
        Generic uninstall. Can be reimplenented in child methods.
        This can uninstall setting on a list of databases or in all databases (if dbNameList == [])
        """
        errorDict = dict()
        successList = []
        settingType = self.getManagerType()
        propertyDict = self.adminDb.getPropertyPerspectiveDict(
            settingType, DsgEnums.Property)
        if configName in list(propertyDict.keys()):
            if dbNameList == []:  #builds filter dbList to uninstall in all installed databases
                dbList = propertyDict[configName]
            else:  #builds filter dbList to uninstall in databases in dbNameList
                dbList = [
                    i for i in propertyDict[configName] if i in dbNameList
                ]
            for dbName in dbList:
                abstractDb = self.instantiateAbstractDb(dbName)
                edgvVersion = abstractDb.getDatabaseVersion()
                try:
                    abstractDb.db.transaction()
                    self.adminDb.db.transaction()
                    self.undoMaterializationFromDatabase(
                        abstractDb, configName, settingType, edgvVersion
                    )  #step done when property management involves changing database structure
                    abstractDb.removeRecordFromPropertyTable(
                        settingType, configName, edgvVersion)
                    self.adminDb.uninstallPropertyOnAdminDb(settingType,
                                                            configName,
                                                            edgvVersion,
                                                            dbName=dbName)
                    abstractDb.db.commit()
                    self.adminDb.db.commit()
                except Exception as e:
                    abstractDb.db.rollback()
                    self.adminDb.db.rollback()
                    errorDict[dbName] = ':'.join(e.args)
                successList.append(dbName)
        return (successList, errorDict)

    def materializeIntoDatabase(self, abstractDb, propertyDict):
        """
        Method that is reimplemented in each child when installing a property involves changing any sort of database structure
        """
        pass

    def undoMaterializationFromDatabase(self, abstractDb, configName,
                                        settingType, edgvVersion):
        """
        Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure
        """
        pass

    def hasStructuralChanges(self, dbNameList):
        """
        Method that is reimplemented in each child
        """
        return []

    def createPropertyTable(self):
        settingType = self.getManagerType()
        for dbName in list(self.dbDict.keys()):
            abstractDb = self.instantiateAbstractDb(dbName)
            if not abstractDb.checkIfExistsConfigTable(settingType):
                abstractDb.createPropertyTable(settingType,
                                               useTransaction=True)

    def updateMaterializationFromDatabase(self, abstractDb, propertyDict):
        pass
Пример #18
0
class EDGVLayerLoader(QObject):
    def __init__(self, iface, abstractDb, loadCentroids):
        """Constructor."""
        super(EDGVLayerLoader, self).__init__()

        self.abstractDb = abstractDb
        self.uri = QgsDataSourceUri()
        self.iface = iface
        self.utils = Utils()
        self.logErrorDict = dict()
        self.errorLog = ''
        self.geomTypeDict = self.abstractDb.getGeomTypeDict(loadCentroids)
        self.geomDict = self.abstractDb.getGeomDict(self.geomTypeDict)
        self.correspondenceDict = {
            'POINT': 'Point',
            'MULTIPOINT': 'Point',
            'LINESTRING': 'Line',
            'MULTILINESTRING': 'Line',
            'POLYGON': 'Area',
            'MULTIPOLYGON': 'Area'
        }

    def preLoadStep(self, inputList):
        if len(inputList) == 0:
            return [], False
        else:
            if isinstance(inputList[0], dict):
                lyrList = [i['tableName'] for i in inputList]
                return lyrList, True
            else:
                return inputList, False

    def load(self,
             inputList,
             useQml=False,
             uniqueLoad=False,
             useInheritance=False,
             stylePath=None,
             onlyWithElements=False,
             geomFilterList=[],
             isEdgv=True,
             customForm=False,
             loadEditingStructure=False,
             parent=None):
        return None

    def getStyle(self, stylePath, className):
        if 'db:' in stylePath['style']:
            return self.abstractDb.getStyle(stylePath['style'].split(':')[-1],
                                            className)
        else:
            return self.getStyleFromFile(stylePath['style'], className)

    def getStyleFromFile(self, stylePath, className):
        styleName = "{0}.qml".format(className)
        if styleName.lower() in [f.lower() for f in os.listdir(stylePath)]:
            qml = self.utils.parseStyle(os.path.join(stylePath, styleName))
            # dsgtools have the right to write on its own directory
            # a temporary file "temp.qml"
            tempPath = os.path.join(stylePath, "temp.qml")
            with open(tempPath, "w", encoding='utf-8') as f:
                f.writelines(qml)
                f.close()
            return tempPath
        else:
            return None

    def prepareLoad(self):
        dbName = self.abstractDb.getDatabaseName()
        groupList = iface.legendInterface().groups()
        if dbName in groupList:
            return groupList.index(dbName)
        else:
            parentTreeNode = iface.legendInterface().addGroup(
                self.abstractDb.getDatabaseName(), -1)
            return parentTreeNode

    def createMeasureColumn(self, layer):
        if layer.geometryType() == QgsWkbTypes.PolygonGeometry:
            layer.addExpressionField(
                '$area', QgsField(self.tr('area_otf'), QVariant.Double))
        elif layer.geometryType() == QgsWkbTypes.LineGeometry:
            layer.addExpressionField(
                '$length', QgsField(self.tr('lenght_otf'), QVariant.Double))
        return layer

    def getDatabaseGroup(self, rootNode):
        dbName = self.abstractDb.getDatabaseName()
        return self.createGroup(dbName, rootNode)

    def getLyrDict(self, inputList, isEdgv=True):
        """
        Builds lyrDict in order to build loading tree
        lyrList: list of layers to be loaded
        isEdgv: optional parameter to indicate when db is not edgv. If db is not edgv, layers will be grouped by schema.
        """
        lyrDict = dict()
        if isinstance(inputList, list):
            if len(inputList) > 0:
                if isinstance(inputList[0], dict):
                    for elem in inputList:
                        if elem['geomType'] == 'GEOMETRY':
                            continue
                        if self.correspondenceDict[
                                elem['geomType']] not in list(lyrDict.keys()):
                            lyrDict[self.correspondenceDict[
                                elem['geomType']]] = dict()
                        if elem['cat'] not in list(
                                lyrDict[self.correspondenceDict[
                                    elem['geomType']]].keys()):
                            lyrDict[self.correspondenceDict[elem['geomType']]][
                                elem['cat']] = []
                        lyrDict[self.correspondenceDict[elem['geomType']]][
                            elem['cat']].append(elem)
                else:
                    for type in list(self.geomTypeDict.keys()):
                        # some tables are only registered as GEOMETRY and should not be considered
                        if type == 'GEOMETRY':
                            continue
                        if self.correspondenceDict[type] not in list(
                                lyrDict.keys()):
                            lyrDict[self.correspondenceDict[type]] = dict()
                        for lyr in self.geomTypeDict[type]:
                            if lyr in inputList:
                                if isEdgv:
                                    cat = lyr.split('_')[0]
                                else:
                                    cat = self.abstractDb.getTableSchemaFromDb(
                                        lyr)
                                if cat not in list(lyrDict[
                                        self.correspondenceDict[type]].keys()):
                                    lyrDict[self.correspondenceDict[type]][
                                        cat] = []
                                lyrDict[self.correspondenceDict[type]][
                                    cat].append(lyr)
                    for type in list(lyrDict.keys()):
                        if lyrDict[type] == dict():
                            lyrDict.pop(type)
        return lyrDict

    def prepareGroups(self, rootNode, lyrDict):
        aux = dict()
        groupDict = dict()
        groupNodeList = list(lyrDict.keys())
        groupNodeList.sort(reverse=True)
        for geomNodeName in groupNodeList:
            groupDict[geomNodeName] = dict()
            geomNode = self.createGroup(geomNodeName, rootNode)
            catList = list(lyrDict[geomNodeName].keys())
            catList.sort()
            for catNodeName in catList:
                groupDict[geomNodeName][catNodeName] = self.createGroup(
                    catNodeName, geomNode)
        return groupDict

    def createGroup(self, groupName, rootNode):
        groupNode = rootNode.findGroup(groupName)
        if groupNode:
            return groupNode
        else:
            return rootNode.addGroup(groupName)

    def loadDomains(self, layerList, dbRootNode, edgvVersion):
        if edgvVersion not in ('FTer_2a_Ed', '3.0'):
            return dict()
        domLayerDict = dict()
        try:
            qmlDict = self.abstractDb.getQmlDict(layerList)
        except:
            return dict()
        domainNode = self.createGroup(self.tr("Domains"), dbRootNode)
        loadedDomainsDict = {} if not domainNode.findLayers() else {
            i.layer().name(): i.layer()
            for i in domainNode.findLayers()
        }
        for lyr in layerList:
            if lyr in qmlDict:
                for attr in qmlDict[lyr]:
                    domain = qmlDict[lyr][attr]
                    domLyr = self.getDomainLyr(domain, loadedDomainsDict,
                                               domainNode)
                    if lyr not in list(domLayerDict.keys()):
                        domLayerDict[lyr] = dict()
                    if attr not in list(domLayerDict[lyr].keys()):
                        domLayerDict[lyr][attr] = domLyr
        return domLayerDict

    def getDomainLyr(self, domain, loadedDomainsDict, domainNode):
        if domain in loadedDomainsDict:
            return loadedDomainsDict[domain]
        domainLyr = self.loadDomain(domain, domainNode)
        loadedDomainsDict[domain] = domainLyr
        return domainLyr

    def logError(self):
        msg = ''
        for lyr in self.logErrorDict:
            msg += self.tr(
                'Error for lyr ') + lyr + ': ' + self.logErrorDict[lyr] + '\n'
        self.errorLog += msg

    def setDataSource(self, schema, layer, geomColumn, sql, pkColumn='id'):
        self.uri.setDataSource(schema, layer, geomColumn, sql, pkColumn)
        if sql == '':
            self.uri.disableSelectAtId(False)
        else:
            self.uri.disableSelectAtId(True)

    def setDomainsAndRestrictionsWithQml(self, vlayer):
        qmldir = ''
        try:
            qmldir, qmlType = self.abstractDb.getQml(vlayer.name())
        except Exception as e:
            QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin",
                                     Qgis.Critical)
            return None
        if qmlType == 'db':
            tempPath = os.path.join(os.path.dirname(__file__), "temp.qml")
            with open(tempPath, "w", encoding='utf-8') as f:
                f.writelines(qmldir)
                f.close()
            vlayer.loadNamedStyle(tempPath, True)
            os.remove(tempPath)
        else:
            vlayerQml = os.path.join(qmldir, vlayer.name() + '.qml')
            #treat case of qml with multi
            vlayer.loadNamedStyle(vlayerQml, True)
        return vlayer

    def removeEmptyNodes(self, dbNode):
        for geomNode in dbNode.children():
            if not geomNode.findLayers():
                dbNode.removeChildNode(geomNode)
                continue
            for catNode in geomNode.children():
                if not catNode.findLayers():
                    geomNode.removeChildNode(catNode)

    def getParams(self, inputParam):
        if isinstance(inputParam, dict):
            lyrName = inputParam['lyrName']
            schema = inputParam['tableSchema']
            geomColumn = inputParam['geom']
            tableName = inputParam['tableName']
            srid = self.geomDict['tablePerspective'][tableName]['srid']
        elif isinstance(inputParam, tuple):
            schema, tableName = inputParam
            lyrName = tableName
            geomColumn, srid = '', ''
        else:
            lyrName = inputParam
            tableName = self.geomDict['tablePerspective'][lyrName]['tableName']
            schema = self.geomDict['tablePerspective'][lyrName]['schema']
            geomColumn = self.geomDict['tablePerspective'][lyrName][
                'geometryColumn']
            srid = self.geomDict['tablePerspective'][lyrName]['srid']
        return lyrName, schema, geomColumn, tableName, srid

    def getLayerByName(self, layer):
        """
        Return the layer layer from a given layer name.
        :param layer: (str) layer name.
        :return: (QgsVectorLayer) vector layer. 
        """
        try:
            # self.provider is added on children classes
            return QgsVectorLayer(self.uri.uri(), layer, self.provider)
        except:
            return None

    def getComplexLayerByName(self, layer):
        """
        Return the layer layer from a given layer name.
        :param layer: (str) layer name.
        :return: (QgsVectorLayer) vector layer. 
        """
        try:
            # self.provider is added on children classes]
            schema, table = self.abstractDb.getTableSchema(layer)
            return QgsVectorLayer(self.uri.uri(), table, self.provider)
        except:
            return None

    def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr,
                  joinLyrFieldName):
        """
        Builds a join bewteen lyr and joinnedLyr.
        :param originalLyr: QgsVectorLayer original layer;
        :param originalLyrFieldName: (str) name of the field;
        :param joinnedLyr: QgsVectorLayer lyr to be joinned to originalLayer;
        :param joinLyrFieldName: (str) name of the join field name (usually primary key of joinnedLyr)
        """
        joinObject = QgsVectorLayerJoinInfo()
        joinObject.setJoinFieldName(joinLyrFieldName)
        joinObject.setTargetFieldName(originalLyrFieldName)
        joinObject.setJoinLayer(joinnedLyr)
        joinObject.setJoinFieldNamesSubset()
        joinObject.upsertOnEdit(True)  #set to enable edit on original lyr
        joinObject.setCascadedDelete(True)
        joinObject.setDynamicFormEnabled(True)
        joinObject.setEditable(True)
        joinObject.setUsingMemoryCache(True)
        originalLyr.addJoin(joinObject)
Пример #19
0
class BatchDbManager(QtWidgets.QDialog, FORM_CLASS):
    EDGV213, EDGV_FTer_2a_Ed, Non_EDGV = list(range(3))

    def __init__(self, parent=None):
        """Constructor."""
        super(self.__class__, self).__init__(parent)
        self.setupUi(self)
        self.utils = Utils()
        self.dbFactory = DbFactory()
        self.factory = SqlGeneratorFactory()
        self.showTabs(show=False)
        #setting the sql generator
        self.serverWidget.populateServersCombo()
        self.serverWidget.abstractDbLoaded.connect(self.checkSuperUser)
        self.serverWidget.abstractDbLoaded.connect(
            self.populateOtherInterfaces)
        self.dbsCustomSelector.setTitle(self.tr('Server Databases'))
        self.dbsCustomSelector.selectionChanged.connect(self.showTabs)
        self.dbsCustomSelector.selectionChanged.connect(
            self.populateStylesInterface)
        self.dbsCustomSelector.selectionChanged.connect(
            self.populateOtherInterfaces)
        self.previousTab = 0
        self.dbDict = {
            '2.1.3': [],
            '2.1.3 Pro': [],
            'FTer_2a_Ed': [],
            'Non_EDGV': [],
            '3.0': [],
            '3.0 Pro': []
        }
        self.correspondenceDict = {
            self.tr('Load Database Model EDGV Version 2.1.3'): '2.1.3',
            self.tr('Load Database Model EDGV Version 2.1.3 Pro'): '2.1.3 Pro',
            self.tr('Load Database Model EDGV Version 3.0'): '3.0',
            self.tr('Load Database Model EDGV Version 3.0 Pro'): '3.0 Pro',
            self.tr('Load Database Model EDGV Version FTer_2a_Ed'):
            'FTer_2a_Ed',
            self.tr('Load Other Database Models'): 'Non_EDGV'
        }

    @pyqtSlot(bool)
    def on_closePushButton_clicked(self):
        self.done(0)

    def showTabs(self, show=True):
        if show:
            self.tabWidget.show()
        else:
            self.tabWidget.hide()

    def populateListWithDatabasesFromServer(self):
        try:
            dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(
                parentWidget=self)
        except Exception as e:
            QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))

        dbList.sort()
        for (dbname, dbversion) in dbList:
            if dbversion not in list(self.dbDict.keys()):
                dbversion = 'Non_EDGV'
            if dbname not in self.dbDict[dbversion]:
                self.dbDict[dbversion].append(dbname)

    def setDatabases(self):
        self.populateListWithDatabasesFromServer()

    @pyqtSlot(int)
    def on_edgvComboFilter_currentIndexChanged(self, idx):
        if idx != -1 and idx != 0:
            self.dbsCustomSelector.setInitialState(self.dbDict[
                self.correspondenceDict[self.edgvComboFilter.currentText()]])

    def checkSuperUser(self):
        try:
            if self.serverWidget.abstractDb.checkSuperUser():
                self.setDatabases()
            else:
                QMessageBox.warning(
                    self, self.tr('Info!'),
                    self.
                    tr('Connection refused. Connect with a super user to inspect server.'
                       ))
        except Exception as e:
            QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))

    def getSelectedDbList(self):
        return self.dbsCustomSelector.toLs

    def instantiateAbstractDbs(self, instantiateTemplates=False):
        dbsDict = dict()
        selectedDbNameList = self.getSelectedDbList()
        selectedDbNameList = list(
            set(selectedDbNameList + [
                'template_edgv_213', 'template_edgv_fter_2a_ed',
                'template_edgv_3', 'dsgtools_admindb'
            ])) if instantiateTemplates else selectedDbNameList
        for dbName in selectedDbNameList:
            localDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
            localDb.connectDatabaseWithParameters(
                self.serverWidget.abstractDb.db.hostName(),
                self.serverWidget.abstractDb.db.port(), dbName,
                self.serverWidget.abstractDb.db.userName(),
                self.serverWidget.abstractDb.db.password())
            dbsDict[dbName] = localDb
        return dbsDict

    def closeAbstractDbs(self, dbsDict):
        exceptionDict = dict()
        for dbName in list(dbsDict.keys()):
            try:
                dbsDict[dbName].db.close()
            except Exception as e:
                exceptionDict[dbName] = ':'.join(e.args)
        return exceptionDict

    def outputMessage(self, header, successList, exceptionDict):
        msg = header
        if len(successList) > 0:
            msg += self.tr('\nSuccessful databases: ')
            msg += ', '.join(successList)
        if exceptionDict != []:
            msg += self.logInternalError(exceptionDict)
        if successList != [] and exceptionDict != []:
            QMessageBox.warning(self, self.tr('Operation Complete!'), msg)

    def logInternalError(self, exceptionDict):
        msg = ''
        errorDbList = list(exceptionDict.keys())
        if len(errorDbList) > 0:
            msg += self.tr('\nDatabases with error:')
            msg += ', '.join(errorDbList)
            msg += self.tr(
                '\nError messages for each database were output in qgis log.')
            for errorDb in errorDbList:
                msg = self.tr("Error for database {0}: ").format(
                    errorDb, exceptionDict[errorDb])
                QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical)
        return msg

    @pyqtSlot(bool)
    def on_dropDatabasePushButton_clicked(self):
        selectedDbNameList = self.getSelectedDbList()
        if len(selectedDbNameList) == 0:
            QMessageBox.warning(
                self, self.tr('Warning'),
                self.tr('Please select one or more databases to drop!'))
            return
        if QMessageBox.question(
                self, self.tr('Question'),
                self.tr('Do you really want to drop databases: ') +
                ', '.join(selectedDbNameList),
                QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Cancel:
            return
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        successList, exceptionDict = self.batchDropDbs(selectedDbNameList)
        QApplication.restoreOverrideCursor()
        self.setDatabases()
        header = self.tr('Drop operation complete. \n')
        self.outputMessage(header, successList, exceptionDict)
        self.dbsCustomSelector.setInitialState(self.dbsCustomSelector.fromLs)

    @pyqtSlot(bool)
    def on_upgradePostgisPushButton_clicked(self):
        selectedDbNameList = self.getSelectedDbList()
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        successList, exceptionDict = self.batchUpgradePostgis(
            selectedDbNameList)
        QApplication.restoreOverrideCursor()
        self.setDatabases()
        header = self.tr('Upgrade Posgtis operation complete. \n')
        self.outputMessage(header, successList, exceptionDict)

    def batchUpgradePostgis(self, dbList):
        exceptionDict = dict()
        successList = []
        if QMessageBox.question(
                self, self.tr('Question'),
                self.
                tr('This operation will upgrade PostGIS version for templates databases as well as the selected databases. Would you like to continue?'
                   ),
                QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Cancel:
            return successList, exceptionDict
        dbsDict = self.instantiateAbstractDbs(instantiateTemplates=True)
        self.closeAbstractDbs(dbsDict)
        for dbName in dbsDict:
            try:
                if self.serverWidget.abstractDb.checkIfTemplate(dbName):
                    self.serverWidget.abstractDb.setDbAsTemplate(
                        dbName=dbName, setTemplate=False)
                    dbsDict[dbName].upgradePostgis()
                    self.serverWidget.abstractDb.setDbAsTemplate(
                        dbName=dbName, setTemplate=True)
                    successList.append(dbName)
                else:
                    dbsDict[dbName].upgradePostgis()
                    successList.append(dbName)
            except Exception as e:
                exceptionDict[dbName] = ':'.join(e.args)
        return successList, exceptionDict

    def batchDropDbs(self, dbList):
        exceptionDict = dict()
        successList = []
        dbsDict = self.instantiateAbstractDbs()
        self.closeAbstractDbs(dbsDict)
        for dbName in dbList:
            try:
                self.serverWidget.abstractDb.dropDatabase(dbName)
                successList.append(dbName)
            except Exception as e:
                exceptionDict[dbName] = ':'.join(e.args)
        return successList, exceptionDict

    @pyqtSlot(bool)
    def on_importStylesPushButton_clicked(self):
        dbsDict = self.instantiateAbstractDbs()
        exceptionDict = dict()
        versionList = []
        if dbsDict != {}:
            for dbName in list(dbsDict.keys()):
                try:
                    version = dbsDict[dbName].getDatabaseVersion()
                    if version not in versionList:
                        versionList.append(version)
                except Exception as e:
                    exceptionDict[dbName] = ':'.join(e.args)
            if len(list(exceptionDict.keys())) > 0:
                self.logInternalError(exceptionDict)
            if len(versionList) > 1:
                QMessageBox.warning(
                    self, self.tr('Warning'),
                    self.tr('Multiple edgv versions are not allowed!'))
                return
            styleDir = self.getStyleDir(versionList)
            styleList = self.getStyleList(styleDir)
            dlg = SelectStyles(styleList)
            dlg.exec_()
            selectedStyles = dlg.selectedStyles
            if len(selectedStyles) == 0:
                return
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            successList, exceptionDict = self.batchImportStyles(
                dbsDict, styleDir, selectedStyles, versionList[0])
            QApplication.restoreOverrideCursor()
            header = self.tr('Import operation complete. \n')
            self.outputMessage(header, successList, exceptionDict)
            self.populateStylesInterface()
            closeExceptionDict = self.closeAbstractDbs(dbsDict)
            self.logInternalError(closeExceptionDict)

    def getStyleList(self, styleDir):
        #TODO: Reimplement
        styleList = []
        version = None
        if os.path.basename(styleDir) in [
                'edgv_213', 'edgv_FTer_2a_Ed', 'edgv_3'
        ]:
            version = os.path.basename(styleDir)
        else:
            parentFolder = os.path.dirname(styleDir)
            version = os.path.basename(parentFolder)
        styleWalkList = list(os.walk(styleDir))
        if styleWalkList == []:
            return []
        stylePath, styles, files = styleWalkList[0]
        for style in styles:
            if style == []:
                continue
            styleList.append('/'.join([version, style]))
        if len(styleList) == 0:
            styleList = [version + '/' + os.path.basename(styleDir)]
        return styleList

    def batchImportStyles(self, dbsDict, styleDir, styleList, version):
        exceptionDict = dict()
        successList = []
        for dbName in list(dbsDict.keys()):
            for style in styleList:
                try:
                    dbsDict[dbName].importStylesIntoDb(style)
                    successList.append(dbName)
                except Exception as e:
                    errors = []
                    for arg in e.args:
                        if isinstance(arg, str):
                            s = '{}'.format(arg.encode('utf-8'))
                        else:
                            s = str(arg)
                        errors.append(s)
                    exceptionDict[dbName] = ':'.join(errors)
        return successList, exceptionDict

    def getStyleDir(self, versionList):
        if versionList != [] and versionList[
                0] in self.serverWidget.abstractDb.versionFolderDict:
            return os.path.join(
                os.path.dirname(__file__), '..', '..', 'core', 'Styles',
                self.serverWidget.abstractDb.versionFolderDict[versionList[0]])
        elif versionList != []:
            return os.path.join(os.path.dirname(__file__), '..', '..', 'core',
                                'Styles', "Non_EDGV")
        return ""

    def getStylesFromDbs(self, perspective='style'):
        '''
        Returns a dict of styles in a form acording to perspective:
            if perspective = 'style'    : [styleName][dbName][tableName] = timestamp
            if perspective = 'database' : [dbName][styleName][tableName] = timestamp 
        '''
        dbsDict = self.instantiateAbstractDbs()
        allStylesDict = dict()
        exceptionDict = dict()
        for dbName in list(dbsDict.keys()):
            try:
                newDict = dbsDict[dbName].getAllStylesDict(perspective)
                allStylesDict = self.utils.mergeDict(newDict, allStylesDict)
            except Exception as e:
                exceptionDict[dbName] = ':'.join(e.args)
        if len(list(exceptionDict.keys())) > 0:
            self.logInternalError(exceptionDict)
        return allStylesDict

    def createItem(self, parent, text, column):
        item = QtWidgets.QTreeWidgetItem(parent)
        item.setText(column, text)
        return item

    def populateStylesInterface(self):
        self.stylesTreeWidget.clear()
        allStylesDict = self.getStylesFromDbs()
        rootNode = self.stylesTreeWidget.invisibleRootItem()
        for styleName in list(allStylesDict.keys()):
            parentStyleItem = self.createItem(rootNode, styleName, 0)
            dbList = list(allStylesDict[styleName].keys())
            parentTimeList = []
            for dbName in dbList:
                dbItem = self.createItem(parentStyleItem, dbName, 1)
                tableList = list(allStylesDict[styleName][dbName].keys())
                tableList.sort()
                timeList = []
                for table in tableList:
                    tableItem = self.createItem(dbItem, table, 2)
                    timeStamp = allStylesDict[styleName][dbName][
                        table].toString()
                    timeList.append(timeStamp)
                    tableItem.setText(
                        3, allStylesDict[styleName][dbName][table].toString())
                parentTimeList.append(max(timeList))
                dbItem.setText(3, max(timeList))

    @pyqtSlot(bool)
    def on_deleteStyles_clicked(self):
        dbsDict = self.instantiateAbstractDbs()
        styleDict = self.getStylesFromDbs()
        styleList = list(styleDict.keys())
        dlg = SelectStyles(styleList)
        execStatus = dlg.exec_()
        selectedStyles = dlg.selectedStyles
        if execStatus != 0 and selectedStyles != []:
            selectedStyleDict = {k: styleDict[k] for k in selectedStyles}
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            successList, exceptionDict = self.batchDeleteStyles(
                dbsDict, selectedStyleDict)
            QApplication.restoreOverrideCursor()
            header = self.tr('Delete operation complete. \n')
            self.outputMessage(header, successList, exceptionDict)
            self.populateStylesInterface()
            closeExceptionDict = self.closeAbstractDbs(dbsDict)
            self.logInternalError(closeExceptionDict)

    def batchDeleteStyles(self, dbsDict, styleDict):
        exceptionDict = dict()
        successList = []
        for style in list(styleDict.keys()):
            for dbName in list(styleDict[style].keys()):
                try:
                    dbsDict[dbName].deleteStyle(style)
                    successList.append(dbName)
                except Exception as e:
                    exceptionDict[dbName] = ':'.join(e.args)
        return successList, exceptionDict

    def getSQLFile(self):
        fd = QFileDialog()
        filename = fd.getOpenFileName(caption=self.tr('Select a SQL file'),
                                      filter=self.tr('sql file (*.sql)'))
        return filename

    @pyqtSlot(bool)
    def on_customizeFromSQLFilePushButton_clicked(self):
        dbsDict = self.instantiateAbstractDbs()
        sqlFilePath = self.getSQLFile()
        if sqlFilePath == '':
            return
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        successList, exceptionDict = self.batchCustomizeFromSQLFile(
            dbsDict, sqlFilePath)
        QApplication.restoreOverrideCursor()
        header = self.tr('Customize from SQL file operation complete. \n')
        self.outputMessage(header, successList, exceptionDict)
        closeExceptionDict = self.closeAbstractDbs(dbsDict)
        self.logInternalError(closeExceptionDict)

    def batchCustomizeFromSQLFile(self, dbsDict, sqlFilePath):
        exceptionDict = dict()
        successList = []
        for dbName in list(dbsDict.keys()):
            try:
                dbsDict[dbName].runSqlFromFile(sqlFilePath)
                successList.append(dbName)
            except Exception as e:
                exceptionDict[dbName] = ':'.join(e.args)
        return successList, exceptionDict

    def populateOtherInterfaces(self):
        dbsDict = self.instantiateAbstractDbs()
        if self.edgvComboFilter.currentIndex() != 0:
            edgvVersion = self.correspondenceDict[
                self.edgvComboFilter.currentText()]
            self.permissionWidget.setParameters(self.serverWidget.abstractDb,
                                                dbsDict, edgvVersion)
            # self.customizationManagerWidget.setParameters(self.serverWidget.abstractDb, edgvVersion, dbsDict = dbsDict)
            self.fieldToolBoxConfigManagerWidget.setParameters(
                self.serverWidget.abstractDb, edgvVersion, dbsDict=dbsDict)
            self.earthCoverageManagerWidget.setParameters(
                self.serverWidget.abstractDb, edgvVersion, dbsDict=dbsDict)
Пример #20
0
class ChangeFilterWidget(QtWidgets.QWidget, FORM_CLASS):
    populateSingleValue = pyqtSignal()
    populateListValue = pyqtSignal()

    def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
        """Constructor."""
        super(self.__class__, self).__init__(parent)
        self.abstractDb = abstractDb
        self.setupUi(self)
        self.jsonBuilder = CustomJSONBuilder()
        self.populateSchemaCombo()
        self.hideWidgetList([
            self.singleValueLabel, self.singleValueComboBox,
            self.actionComboBox
        ])
        self.singleAttribute = True
        self.filterCustomSelectorWidget.setTitle(
            self.tr('Select filter values'))
        self.populateSingleValue.connect(self.populateWidgetWithSingleValue)
        self.populateListValue.connect(self.populateWidgetWithListValue)
        geomTypeDict = self.abstractDb.getGeomTypeDict()
        geomDict = self.abstractDb.getGeomDict(geomTypeDict)
        self.domainDict = self.abstractDb.getDbDomainDict(geomDict)
        self.inhTree = self.abstractDb.getInheritanceTreeDict()
        self.utils = Utils()
        self.actionDict = {
            self.tr('Add to Filter (Leave empty if filter is empty)'):
            'addEmpty',
            self.tr('Add to Filter (Add value to empty filter)'): 'add',
            self.tr('Remove from Filter'): 'remove'
        }
        self.populateFromUiParameterJsonDict(uiParameterJsonDict)

    def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
        """
        {
            'schemaComboBox': --current text of schemaComboBox --
            'tableComboBox': ---current text of tableComboBox --
            'attributeComboBox': ---current text of attributeComboBox --
            'allAttributesCheckBox': --current state of allAttributesCheckBox--
            'allTablesCheckBox': --current state of allTablesCheckBox--
            'filterCustomSelectorWidgetToList': [--list of selected values on filterCustomSelectorWidget--]
            'singleValueComboBox': --current text of singleValueComboBox--
            'actionComboBoxIdx': --current index of actionComboBoxIdx--
        }
        """
        if uiParameterJsonDict:
            if uiParameterJsonDict['allTablesCheckBox']:
                self.allTablesCheckBox.setCheckState(Qt.Checked)
                singleValueIdx = self.singleValueComboBox.findText(
                    uiParameterJsonDict['singleValueComboBox'],
                    flags=Qt.MatchExactly)
                self.singleValueComboBox.setCurrentIndex(singleValueIdx)
                self.actionComboBox.setCurrentIndex(
                    uiParameterJsonDict['actionComboBoxIdx'])
            else:
                schemaIdx = self.schemaComboBox.findText(
                    uiParameterJsonDict['schemaComboBox'],
                    flags=Qt.MatchExactly)
                self.schemaComboBox.setCurrentIndex(schemaIdx)
                tableIdx = self.tableComboBox.findText(
                    uiParameterJsonDict['tableComboBox'],
                    flags=Qt.MatchExactly)
                self.tableComboBox.setCurrentIndex(tableIdx)
                if uiParameterJsonDict['allAttributesCheckBox']:
                    self.allAttributesCheckBox.setCheckState(Qt.Checked)
                    singleValueIdx = self.singleValueComboBox.findText(
                        uiParameterJsonDict['singleValueComboBox'],
                        flags=Qt.MatchExactly)
                    self.singleValueComboBox.setCurrentIndex(singleValueIdx)
                    self.actionComboBox.setCurrentIndex(
                        uiParameterJsonDict['actionComboBoxIdx'])
                else:
                    attributeIdx = self.attributeComboBox.findText(
                        uiParameterJsonDict['attributeComboBox'],
                        flags=Qt.MatchExactly)
                    self.attributeComboBox.setCurrentIndex(attributeIdx)
                    self.filterCustomSelectorWidget.selectItems(
                        True,
                        selectedItems=uiParameterJsonDict[
                            'filterCustomSelectorWidgetToList'])

    def populateInheritanceTree(self, nodeList):
        self.treeWidget.clear()
        rootNode = self.treeWidget.invisibleRootItem()
        for node in nodeList:
            firstNonRootNode = self.utils.find_all_paths(
                self.inhTree, 'root', node)[0][1]
            self.utils.createTreeWidgetFromDict(
                rootNode,
                {firstNonRootNode: self.inhTree['root'][firstNonRootNode]},
                self.treeWidget, 0)
        self.treeWidget.sortItems(0, Qt.AscendingOrder)
        self.treeWidget.expandAll()

    def populateSchemaCombo(self):
        self.schemaComboBox.clear()
        self.schemaComboBox.addItem(self.tr('Select a schema'))
        schemaList = self.abstractDb.getGeometricSchemaList()
        for schema in schemaList:
            if schema not in ['views', 'validation']:
                self.schemaComboBox.addItem(schema)

    def hideWidgetList(self, widgetList):
        for widget in widgetList:
            widget.hide()

    def showWidgetList(self, widgetList):
        for widget in widgetList:
            widget.show()

    @pyqtSlot(int)
    def on_schemaComboBox_currentIndexChanged(self, idx):
        if idx == 0:
            self.tableComboBox.clear()
            self.tableComboBox.setEnabled(False)
            self.attributeComboBox.clear()
            self.attributeComboBox.setEnabled(False)
        else:
            schema = self.schemaComboBox.currentText()
            self.tableComboBox.setEnabled(True)
            self.tableComboBox.clear()
            self.tableComboBox.addItem(self.tr('Select a table'))
            tableList = self.abstractDb.getGeometricTableListFromSchema(schema)
            for table in tableList:
                self.tableComboBox.addItem(table)

    @pyqtSlot(int)
    def on_tableComboBox_currentIndexChanged(self, idx):
        if idx == 0:
            self.attributeComboBox.clear()
            self.attributeComboBox.setEnabled(False)
        else:
            schema = self.schemaComboBox.currentText()
            tableName = self.tableComboBox.currentText()
            self.attributeComboBox.setEnabled(True)
            self.attributeComboBox.clear()
            self.attributeComboBox.addItem(self.tr('Select an attribute'))
            if tableName in list(self.domainDict.keys()):
                attributeList = list(
                    self.domainDict[tableName]['columns'].keys())
                for attribute in attributeList:
                    self.attributeComboBox.addItem(attribute)

    @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged')
    @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged')
    @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged')
    def populateWidgetWithSingleValue(self):
        if self.allTablesCheckBox.checkState() == 2 or (
                self.allAttributesCheckBox.checkState() == 2
                and self.schemaComboBox.currentIndex() != 0
                and self.tableComboBox.currentIndex() != 0):
            self.attributeComboBox.clear()
            self.attributeComboBox.setEnabled(False)
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            self.singleValueComboBox.clear()
            self.singleValueComboBox.addItem(
                self.tr('Select a value to alter'))
            if self.allAttributesCheckBox.checkState() == 2:
                tableList = [self.tableComboBox.currentText()]
            else:
                tableList = list(self.domainDict.keys())
            allValueList = []
            idxList = []
            for tableName in tableList:
                for attrName in list(
                        self.domainDict[tableName]['columns'].keys()):
                    for code in self.domainDict[tableName]['columns'][
                            attrName]['values']:
                        value = self.domainDict[tableName]['columns'][
                            attrName]['values'][code]
                        if value not in allValueList:
                            allValueList.append(value)

            for value in allValueList:
                for tableName in tableList:
                    for attrName in list(
                            self.domainDict[tableName]['columns'].keys()):
                        if value not in list(
                                self.domainDict[tableName]['columns'][attrName]
                            ['values'].values()):
                            idx = allValueList.index(value)
                            if idx not in idxList:
                                idxList.append(idx)
            idxList.sort(reverse=True)
            for idx in idxList:
                allValueList.pop(idx)
            for value in allValueList:
                self.singleValueComboBox.addItem(value)
            self.populateInheritanceTree(tableList)
            QApplication.restoreOverrideCursor()

    @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged')
    @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged')
    @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged')
    def populateWidgetWithListValue(self):
        self.filterCustomSelectorWidget.clearAll()
        if self.allTablesCheckBox.checkState(
        ) == 2 or self.allAttributesCheckBox.checkState() == 2:
            return
        if self.schemaComboBox.currentIndex() == 0:
            return
        if self.tableComboBox.currentIndex() == 0:
            self.treeWidget.clear()
            return
        tableName = self.tableComboBox.currentText()
        self.populateInheritanceTree([tableName])
        if self.attributeComboBox.currentIndex() == 0:
            return
        filterList = []
        attributeName = self.attributeComboBox.currentText()
        tableFilter = []
        filterToList = []
        if tableName in list(self.domainDict.keys()):
            if attributeName in list(
                    self.domainDict[tableName]['columns'].keys()):
                attrDomainDict = self.domainDict[tableName]['columns'][
                    attributeName]['values']
                tableFilter = self.domainDict[tableName]['columns'][
                    attributeName]['constraintList']
                filterToList = [attrDomainDict[i] for i in tableFilter]
                filterFromList = [
                    i for i in list(attrDomainDict.values())
                    if i not in filterToList
                ]
                self.filterCustomSelectorWidget.setFromList(filterFromList,
                                                            unique=True)
                self.filterCustomSelectorWidget.setToList(filterToList)

    @pyqtSlot(int)
    def on_allTablesCheckBox_stateChanged(self, state):
        self.hideOrShowWidgets()
        if state == 0:
            self.allAttributesCheckBox.setEnabled(True)
            self.schemaComboBox.setCurrentIndex(0)
            self.schemaComboBox.setEnabled(True)
        elif state == 2:
            self.allAttributesCheckBox.setEnabled(False)
            self.allAttributesCheckBox.setCheckState(0)
            self.schemaComboBox.setCurrentIndex(0)
            self.schemaComboBox.setEnabled(False)

    @pyqtSlot(int)
    def on_allAttributesCheckBox_stateChanged(self, state):
        if state == 2:
            self.allTablesCheckBox.setEnabled(False)
            self.allTablesCheckBox.setCheckState(0)
            self.attributeComboBox.setCurrentIndex(0)
            self.attributeComboBox.setEnabled(False)
        if state == 0:
            self.allTablesCheckBox.setEnabled(True)
            self.attributeComboBox.setEnabled(True)
        self.hideOrShowWidgets()

    def hideOrShowWidgets(self):
        if self.allAttributesCheckBox.checkState(
        ) == 2 or self.allTablesCheckBox.checkState() == 2:
            self.filterCustomSelectorWidget.hide()
            self.singleValueLabel.show()
            self.singleValueComboBox.show()
            self.actionComboBox.show()
            self.populateSingleValue.emit()
        else:
            self.filterCustomSelectorWidget.show()
            self.singleValueLabel.hide()
            self.singleValueComboBox.hide()
            self.actionComboBox.hide()
            self.tableComboBox.currentIndexChanged.emit(
                self.tableComboBox.currentIndex())
            self.populateListValue.emit()

    def getTitle(self):
        return self.title

    def setTitle(self, title):
        self.title = title

    def validate(self):
        if self.allTablesCheckBox.checkState() == 2:
            if self.singleValueComboBox.currentIndex() == 0:
                return False
            if self.actionComboBox.currentIndex() == 0:
                return False
        elif self.allAttributesCheckBox.checkState() == 2:
            if self.singleValueComboBox.currentIndex() == 0:
                return False
            if self.actionComboBox.currentIndex() == 0:
                return False
            if self.schemaComboBox.currentIndex() == 0:
                return False
            if self.tableComboBox.currentIndex() == 0:
                return False
        else:
            if self.schemaComboBox.currentIndex() == 0:
                return False
            if self.tableComboBox.currentIndex() == 0:
                return False
            if self.attributeComboBox.currentIndex() == 0:
                return False
        return True

    def validateDiagnosis(self):
        invalidatedReason = ''
        if self.allTablesCheckBox.checkState() == 2:
            if self.singleValueComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A value must be chosen.\n')
            if self.actionComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('An action must be chosen.\n')
        elif self.allAttributesCheckBox.checkState() == 2:
            if self.singleValueComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A value must be chosen.\n')
            if self.actionComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('An action must be chosen.\n')
            if self.schemaComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A schema must be chosen.\n')
            if self.tableComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A table must be chosen.\n')
        else:
            if self.schemaComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A schema must be chosen.\n')
            if self.tableComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('A table must be chosen.\n')
            if self.attributeComboBox.currentIndex() == 0:
                invalidatedReason += self.tr('An attribute must be chosen.\n')
        return invalidatedReason

    def getJSONTag(self):
        if not self.validate():
            raise Exception(
                self.tr('Error in change filter customization ') + self.title +
                ' : ' + self.validateDiagnosis())
        jsonList = []
        inhConstrDict = self.abstractDb.getInheritanceConstraintDict()
        if self.allAttributesCheckBox.checkState() == 2:
            tableName = self.tableComboBox.currentText()
            schema = self.schemaComboBox.currentText()
            self.batchGetJsonTag(schema, tableName, jsonList, inhConstrDict)
        elif self.allTablesCheckBox.checkState() == 2:
            tableList = list(self.inhTree['root'].keys())
            for tableName in tableList:
                schema = self.abstractDb.getTableSchemaFromDb(tableName)
                self.batchGetJsonTag(schema, tableName, jsonList,
                                     inhConstrDict)
        else:
            tableName = self.tableComboBox.currentText()
            schema = self.schemaComboBox.currentText()
            attrName = self.attributeComboBox.currentText()
            if tableName in list(self.domainDict.keys()):
                if attrName in list(
                        self.domainDict[tableName]['columns'].keys()):
                    attrDomainDict = self.domainDict[tableName]['columns'][
                        attrName]['values']
                    isMulti = self.domainDict[tableName]['columns'][attrName][
                        'isMulti']
            newFilter = [
                i for i in list(attrDomainDict.keys())
                if attrDomainDict[i] in self.filterCustomSelectorWidget.toLs
            ]
            self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList,
                                        inhConstrDict, newFilter, isMulti)
        return jsonList

    def batchGetJsonTag(self, schema, tableName, jsonList, inhConstrDict):
        if tableName in list(self.domainDict.keys()):
            for attrName in list(self.domainDict[tableName]['columns'].keys()):
                attrDomainDict = self.domainDict[tableName]['columns'][
                    attrName]['values']
                isMulti = self.domainDict[tableName]['columns'][attrName][
                    'isMulti']
                newFilter = self.domainDict[tableName]['columns'][attrName][
                    'constraintList']
                valueText = self.singleValueComboBox.currentText()
                code = [
                    i for i in list(attrDomainDict.keys())
                    if attrDomainDict[i] == valueText
                ][0]
                if self.actionDict[self.actionComboBox.currentText()] == 'add':
                    if code not in newFilter: newFilter.append(code)
                elif self.actionDict[
                        self.actionComboBox.currentText()] == 'addEmpty':
                    if newFilter == []:
                        continue
                else:
                    if code in newFilter: newFilter.pop(code)
                self.getJsonTagFromOneTable(schema, tableName, attrName,
                                            jsonList, inhConstrDict, newFilter,
                                            isMulti)

    def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList,
                               inhConstrDict, newFilter, isMulti):
        originalFilterList = []
        if tableName in list(inhConstrDict.keys()):
            if attrName in list(inhConstrDict[tableName].keys()):
                originalFilterList = inhConstrDict[tableName][attrName]
        if originalFilterList == newFilter: return
        elif originalFilterList != []:
            for item in originalFilterList:
                newElement = self.jsonBuilder.alterFilterElement(
                    item['schema'], item['tableName'], attrName,
                    item['constraintName'], item['filter'], newFilter, isMulti)
                if newElement not in jsonList:
                    jsonList.append(newElement)
        else:
            nodeLineage = self.utils.getNodeLineage(tableName, self.inhTree)
            firstInLineage = None
            for node in nodeLineage:
                if node in list(self.domainDict.keys()):
                    if attrName in list(
                            self.domainDict[node]['columns'].keys()):
                        firstInLineage = node
                        break
                else:
                    schema = self.abstractDb.getTableSchemaFromDb(node)
                    if node in self.abstractDb.getAttributeListFromTable(
                            schema, node):
                        firstInLineage = node
                        break
            newElement = self.jsonBuilder.alterFilterElement(
                schema, firstInLineage, attrName,
                '_'.join([firstInLineage, attrName,
                          'ks']), [], newFilter, isMulti)
            if newElement not in jsonList:
                jsonList.append(newElement)

    def getUiParameterJsonDict(self):
        """
        builds a dict with the following format:
        {
            'schemaComboBox': --current text of schemaComboBox --
            'tableComboBox': ---current text of tableComboBox --
            'attributeComboBox': ---current text of attributeComboBox --
            'allAttributesCheckBox': --current state of allAttributesCheckBox--
            'allTablesCheckBox': --current state of allTablesCheckBox--
            'filterCustomSelectorWidgetToList': [--list of selected values on filterCustomSelectorWidget--]
            'singleValueComboBox': --current text of singleValueComboBox--
            'actionComboBoxIdx': --current index of actionComboBox--
        }
        """
        uiParameterJsonDict = dict()
        uiParameterJsonDict[
            'schemaComboBox'] = self.schemaComboBox.currentText()
        uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText()
        uiParameterJsonDict[
            'attributeComboBox'] = self.attributeComboBox.currentText()
        uiParameterJsonDict[
            'allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked()
        uiParameterJsonDict[
            'allTablesCheckBox'] = self.allTablesCheckBox.isChecked()
        uiParameterJsonDict[
            'filterCustomSelectorWidgetToList'] = self.filterCustomSelectorWidget.toLs
        uiParameterJsonDict[
            'singleValueComboBox'] = self.singleValueComboBox.currentText()
        uiParameterJsonDict[
            'actionComboBoxIdx'] = self.actionComboBox.currentIndex()
        return uiParameterJsonDict
Пример #21
0
class SetupEarthCoverage(QtWidgets.QWizard, FORM_CLASS):
    coverageChanged = pyqtSignal()

    def __init__(self,
                 edgvVersion,
                 areas,
                 lines,
                 oldCoverage,
                 propertyList,
                 enableSetupFromFile=True,
                 onlySetup=False,
                 propertyName=None,
                 parent=None):
        """
        Constructor
        """
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.utils = Utils()
        self.areas = areas
        self.lines = lines
        self.propertyName = propertyName
        self.edgvVersion = edgvVersion
        self.areasCustomSelector.setTitle(self.tr('Areas'))
        self.linesCustomSelector.setTitle(self.tr('Lines'))
        self.propertyList = propertyList
        self.button(QtWidgets.QWizard.NextButton).clicked.connect(
            self.buildTree)
        self.button(QtWidgets.QWizard.FinishButton).clicked.connect(
            self.buildDict)
        self.setupWizard(oldCoverage, enableSetupFromFile)
        self.configDict = dict()

    def setupFromFile(self):
        """
        Opens a earth coverage file
        """
        if QMessageBox.question(
                self, self.tr('Question'),
                self.tr('Do you want to open an earth coverage file?'),
                QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Cancel:
            return
        filename, __ = QFileDialog.getOpenFileName(
            self, self.tr('Open Earth Coverage Setup configuration'), '',
            self.tr('Earth Coverage Files (*.json)'))
        return filename

    def setupWizard(self, oldCoverage, enableSetupFromFile):
        """
        Prepares the wizard
        oldCoverage: old configuration
        """
        if oldCoverage:
            # self.abstractDb.dropCentroids(oldCoverage.keys())
            self.setupUiFromDict(oldCoverage)
            return
        else:
            self.populateFrameListWidget(self.areas)
        if enableSetupFromFile:
            filename = self.setupFromFile()
        else:
            filename = None
        if filename:
            self.setupUiFromFile(filename)
        else:
            self.areasCustomSelector.setFromList(self.areas)
            self.linesCustomSelector.setFromList(self.lines)
        if self.propertyName:
            self.nameLineEdit.setText(self.propertyName)
            self.nameLineEdit.setEnabled(False)

    def setupUiFromFile(self, filename):
        """
        Populates ui from parameters of json
        """
        #read json
        jsonDict = self.utils.readJsonFile(filename)
        self.setupUiFromDict(jsonDict)

    def setupUiFromDict(self, jsonDict):
        """
        Populates ui from parameters of json
        """
        #set nameLineEdit
        self.nameLineEdit.setText(jsonDict['configName'])
        #populate listWidget
        self.populateFrameListWidget(self.areas, frame=jsonDict['frameLayer'])
        linesFromList, linesToList, areasFromList, areasToList = self.populateLists(
            jsonDict['earthCoverageDict'])
        self.areasCustomSelector.setToList(areasToList)
        self.areasCustomSelector.setFromList(areasFromList)
        self.linesCustomSelector.setToList(linesToList)
        self.linesCustomSelector.setFromList(linesFromList)
        self.buildTree()
        self.checkDelimiters(jsonDict['earthCoverageDict'])

    def populateFrameListWidget(self, areas, frame=None):
        areas.sort()
        self.listWidget.clear()
        self.listWidget.addItems(areas)
        if frame:
            try:
                frameItem = self.listWidget.findItems(frame,
                                                      Qt.MatchExactly)[0]
                self.listWidget.setCurrentItem(frameItem)
            except:
                pass

    def populateLists(self, setupDict):
        areasToList = list(setupDict.keys())
        linesToList = []
        for key in areasToList:
            lines = setupDict[key]
            for line in lines:
                if line not in linesToList:
                    linesToList.append(line)
        areasFromList = [
            area for area in self.areas if area not in areasToList
        ]
        linesFromList = [
            line for line in self.lines if line not in linesToList
        ]
        return linesFromList, linesToList, areasFromList, areasToList

    def checkDelimiters(self, setupDict):
        """
        Check delimiters
        """
        for i in range(self.treeWidget.invisibleRootItem().childCount()):
            areaItem = self.treeWidget.invisibleRootItem().child(i)
            for j in range(
                    self.treeWidget.invisibleRootItem().child(i).childCount()):
                delimiterItem = areaItem.child(j)
                if areaItem.text(0) in list(setupDict.keys()):
                    if delimiterItem.text(1) not in setupDict[areaItem.text(
                            0)]:
                        delimiterItem.setCheckState(1, Qt.Unchecked)

    def loadJson(self, filename):
        """
        Loads a json file
        """
        filename, __ = QFileDialog.getOpenFileName(
            self, self.tr('Open Field Setup configuration'), self.folder,
            self.tr('Earth Coverage Setup File (*.dsgearthcov)'))
        if not filename:
            return
        return self.readJsonFile(filename)

    def populateClasses(self):
        """
        Populates area classes
        """
        self.treeWidget.clear()
        selectedAreaClasses = self.areasCustomSelector.toLs
        for i in range(len(selectedAreaClasses)):
            treeItem = QtWidgets.QTreeWidgetItem()
            treeItem.setText(0, selectedAreaClasses[i])
            self.treeWidget.insertTopLevelItem(0, treeItem)

    def populateDelimiters(self):
        """
        Populates line classes (area delimiters)
        """
        delimiterList = []
        for i in range(self.linesCustomSelector.toList.__len__()):
            delimiterList.append(
                self.linesCustomSelector.toList.item(i).text())
        for i in range(self.treeWidget.invisibleRootItem().childCount()):
            for delimiter in delimiterList:
                treeItem = QtWidgets.QTreeWidgetItem(
                    self.treeWidget.invisibleRootItem().child(i))
                treeItem.setText(1, delimiter)
                treeItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                treeItem.setCheckState(1, Qt.Checked)
            self.treeWidget.invisibleRootItem().child(i).setExpanded(True)

    def getEarthCoverageDictFromTree(self):
        """
        Gets earth coverage configuration from the tree widget
        """
        invRootItem = self.treeWidget.invisibleRootItem()
        earthCoverageDict = dict()
        for i in range(invRootItem.childCount()):
            childClass = invRootItem.child(i)
            earthCoverageDict[childClass.text(0)] = []
            for j in range(childClass.childCount()):
                if childClass.child(j).checkState(1) == Qt.Checked:
                    earthCoverageDict[childClass.text(0)].append(
                        childClass.child(j).text(1))
        return earthCoverageDict

    def buildDict(self):
        '''
        Gets earth coverage dict from interface
        '''
        self.configDict['edgvVersion'] = self.edgvVersion
        self.configDict['configName'] = self.nameLineEdit.text()
        self.configDict['frameLayer'] = self.listWidget.currentItem().text()
        self.configDict[
            'earthCoverageDict'] = self.getEarthCoverageDictFromTree()

    def buildTree(self):
        """
        Builds the earth coverage tree using the selected areas and lines
        """
        self.populateClasses()
        self.populateDelimiters()
        self.treeWidget.expandAll()
        self.treeWidget.header().setSectionResizeMode(
            QtWidgets.QHeaderView.ResizeToContents)
        self.treeWidget.header().setStretchLastSection(False)

    def on_filterLineEdit_textChanged(self, text):
        """
        Filters the items to make it easier to spot and select them
        """
        classes = [edgvClass for edgvClass in self.areas if text in edgvClass]
        self.listWidget.clear()
        self.listWidget.addItems(classes)
        self.listWidget.sortItems()

    def validateEarthCoverageTreeWidget(self):
        rootNode = self.treeWidget.invisibleRootItem()
        childCount = rootNode.childCount()
        for i in range(childCount):
            areaItem = rootNode.child(i)
            lineChildCount = areaItem.childCount()
            hasSelected = False
            for j in range(lineChildCount):
                lineChild = areaItem.child(j)
                if lineChild.checkState(1) == Qt.Checked:
                    hasSelected = True
                    break
            if not hasSelected:
                return False
        return True

    def validateCurrentPage(self):
        if self.currentId() == 0:
            errorMsg = ''
            isValidated = True
            if self.nameLineEdit.text() == '':
                errorMsg += self.tr('An Earth Coverage name must be set.\n')
                isValidated = False
            if self.nameLineEdit.text() in self.propertyList:
                errorMsg += self.tr(
                    'An Earth Coverage with this name already exists.\n')
                isValidated = False
            if self.listWidget.currentRow() == -1:
                errorMsg += self.tr('A frame layer must be chosen.\n')
                isValidated = False
            if not isValidated:
                QMessageBox.warning(self, self.tr('Error!'), errorMsg)
            return isValidated
        elif self.currentId() == 1:
            if self.areasCustomSelector.toLs == []:
                errorMsg = self.tr(
                    'Areas must be chosen for Earth Coverage.\n')
                QMessageBox.warning(self, self.tr('Error!'), errorMsg)
                return False
            return True
        elif self.currentId() == 2:
            if self.linesCustomSelector.toLs == []:
                errorMsg = self.tr(
                    'Lines must be chosen for Earth Coverage.\n')
                QMessageBox.warning(self, self.tr('Error!'), errorMsg)
                return False
            return True
        elif self.currentId() == 3:
            #at least one line selected for each area
            if not self.validateEarthCoverageTreeWidget():
                errorMsg = self.tr(
                    'At least one line must be chosen for each Earth Coverage area.\n'
                )
                QMessageBox.warning(self, self.tr('Error!'), errorMsg)
                return False
            return True
        else:
            return True