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 __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 __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 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
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()
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()
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)
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)
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)
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' }
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)
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)
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|
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
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
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)
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)
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
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