def tableList(self,comboBox): tableModel=ConfigTableReader() model=tableModel.tableListModel(self.userProfile) comboBox.setModel(model) index=comboBox.findText(self.tableName,Qt.MatchExactly) if index!=-1: comboBox.setCurrentIndex(index-1)
def initControls(self): #perform initialization of controls self.profile = activeProfile() self.handler = ConfigTableReader() Lkupmodel = self.handler.lookupTableModel() self.cboTable.setModel(Lkupmodel) self.showDefinedLookupChoices()
def __init__(self, plugin): QMainWindow.__init__(self, plugin.iface.mainWindow()) self.setupUi(self) self._plugin = plugin self.tbPropertyPreview.set_iface(self._plugin.iface) # Center me self.move(QDesktopWidget().availableGeometry().center() - self.frameGeometry().center()) # set whether currently logged in user has permissions to edit existing STR records self._can_edit = self._plugin.STRCntGroup.canUpdate() """ Variable used to store a reference to the currently selected social tenure relationship when displaying documents in the supporting documents tab window. This ensures that there are no duplicates when the same item is selected over and over again. """ self._strID = None # Used to store the root hash of the currently selected node. self._curr_rootnode_hash = "" self._source_doc_manager = SourceDocumentManager() self._source_doc_manager.documentRemoved.connect(self.onSourceDocumentRemoved) self._source_doc_manager.setEditPermissions(self._can_edit) self._config_table_reader = ConfigTableReader() self.initGui()
def initControls(self): self.defaults = ['integer','date','boolean','time with time zone','serial','geometry','double precision','text'] tableHandler = ConfigTableReader() model = tableHandler.fulltableList() self.cboTabList.insertItems(0,model) index=self.cboTabList.findText(self.tableName,Qt.MatchExactly) if index!=-1: self.cboTabList.setCurrentIndex(index) setCollectiontypes(datatypes, self.cboDatatype) setCollectiontypes(nullable, self.cboNull) dIndex=self.cboDatatype.findText('Short text',Qt.MatchExactly) if dIndex!=-1: self.cboDatatype.setCurrentIndex(dIndex) self.cboNull.setCurrentIndex(1) self.reloadColumnValues() self.initializeValidator()
def initControls(self): self.defaults = postgres_defaults tableHandler = ConfigTableReader() model = tableHandler.on_main_table_selection() self.cboTabList.setModel(model) index = self.cboTabList.findText(self.tableName, Qt.MatchExactly) if index != -1: self.cboTabList.setCurrentIndex(index) setCollectiontypes(data_types, self.cboDatatype) setCollectiontypes(nullable, self.cboNull) setCollectiontypes(nullable, self.cboSearchable) dIndex = self.cboDatatype.findText("Short text", Qt.MatchExactly) if dIndex != -1: self.cboDatatype.setCurrentIndex(dIndex) self.txtAttrib.setText("50") self.cboNull.setCurrentIndex(1) self.reloadColumnValues() self.initializeValidator() self.txtCol.setFocus()
def __init__(self,usrProf,tableName,parent): QDialog.__init__(self,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.tableName=tableName self.userProfile=usrProf self.table_handler=ConfigTableReader() self.initControls() QObject.connect(self.cboTable, SIGNAL("currentIndexChanged(int)"), self.relationColumns)
def tableModel(self): tableHandler = ConfigTableReader() tableModel = tableHandler.tableListModel(self.profile) self.cboInheritTable.setModel(tableModel)
class LookupDialog(QDialog, Ui_Lookup): def __init__(self, parent): QDialog.__init__(self, 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.tableName = None self.initControls() self.btnNew.clicked.connect(self.addLookUp) self.cboTable.currentIndexChanged.connect(self.currentTableChanged) self.btnChoice.clicked.connect(self.addNewLookupChoice) def initControls(self): #perform initialization of controls self.profile = activeProfile() self.handler = ConfigTableReader() Lkupmodel = self.handler.lookupTableModel() self.cboTable.setModel(Lkupmodel) self.showDefinedLookupChoices() def showDefinedLookupChoices(self): ''' show preview of defined lookup choices when the lookup table is selected ''' lkChoices = self.handler.readLookupList(self.cboTable.currentText()) self.lklstView.setModel(lkChoices) def currentTableChanged(self,int): '''Load lookup choices based on the selected lookup table''' self.showDefinedLookupChoices() def addNewLookupChoice(self): '''Add new choice to lookup table''' lkDlg = ADDLookupValue(self) if lkDlg.exec_()== QDialog.Accepted: lkName = lkDlg.value self.handler.addLookupValue(self.cboTable.currentText(), lkName) self.showDefinedLookupChoices() def addLookUp(self): #add new lookup table" actionState = [self.profile, QApplication.translate("WorkspaceLoader","Add Lookup")] dlg = TableEditor(actionState, None, self) dlg.exec_() self.initControls() def acceptDlg(self): '''return user selected table''' self.tableName = self.cboTable.currentText() self.accept() def ErrorInfoMessage(self, Message): # Error Message Box msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setWindowTitle("STDM") msg.setText(Message) msg.exec_()
class TableProperty(QDialog,Ui_TableProperty): def __init__(self,usrProf,tableName,parent): QDialog.__init__(self,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.tableName=tableName self.userProfile=usrProf self.table_handler=ConfigTableReader() self.initControls() QObject.connect(self.cboTable, SIGNAL("currentIndexChanged(int)"), self.relationColumns) #QObject.connect(self.listView,SIGNAL('clicked(QModelIndex)'),self.selectedIndex) def initControls(self): '''Initialize defualt dialog properties''' self.tableList(self.cboTable) setCollectiontypes(actions,self.cboDelAct) setCollectiontypes(actions,self.cboUpAct) self.table_column_model(self.cboColumn,self.cboTable.currentText()) self.table_column_model(self.cboRefCol,self.tableName) self.table_column_model(self.cboType, self.cboTable.currentText()) def tableList(self,comboBox): model=self.table_handler.tableListModel(self.userProfile) comboBox.setModel(model) index=comboBox.findText(self.tableName,Qt.MatchExactly) if index!=-1: comboBox.setCurrentIndex(index-1) def table_column_model(self, combo, tableName): """ Return a list of column as QAbstractListModel :param combo: :param tableName: :return: """ col_list =tableCols(tableName) col_model = self.table_handler.column_labels(col_list) combo.setModel(col_model) def setCollectiontypes(self,collectionType,combo): #method to read defult to a sql relations and constraint type to combo box ordDict=collections.OrderedDict(collectionType) combo.clear() for k, v in ordDict.iteritems(): combo.addItem(k,v) combo.setInsertPolicy(QComboBox.InsertAlphabetically) combo.setMaxVisibleItems(len(collectionType)) def relationColumns(self): '''update columns set for the selected table''' referenceTable=self.cboTable.currentText() self.table_column_model(self.cboColumn,referenceTable) self.table_column_model(self.cboType,referenceTable) def localColumns(self): '''update columns set for the selected table''' self.table_column_model(self.cboRefCol,self.tableName) def selectedData(self,comboBox): #get the user data from the combo box display item text=comboBox.currentText() index=comboBox.findText(text, Qt.MatchExactly) if index!=-1: userData=comboBox.itemData(int(index)) return userData def setTableRelation(self): '''add new relation to the table in the config file''' delAct=UserData(self.cboDelAct) updateAct=UserData(self.cboUpAct) attribDict={} attribDict['name']=formatColumnName(self.txtName.text()) attribDict['table']=self.cboTable.currentText() attribDict['fk']=self.cboRefCol.currentText() attribDict['column']=self.cboColumn.currentText() attribDict['display_name']=self.cboType.currentText() attribDict['ondelete']=delAct attribDict['onupdate']=updateAct writeTableColumn(attribDict,self.userProfile,'table',self.tableName,'relations') def accept(self): if self.txtName.text()=='': self.ErrorInfoMessage(QApplication.translate("TableProperty","Relation Name is not given")) return if self.cboTable.currentText()=="": self.ErrorInfoMessage(QApplication.translate("TableProperty","Referenced Table is not selected")) return if self.cboTable.currentText()== self.tableName: self.ErrorInfoMessage(QApplication.translate("TableProperty","Table cannot draw a reference from itself")) return self.setTableRelation() self.close() def ErrorInfoMessage(self, Message): # Error Message Box msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setWindowTitle(QApplication.translate("AttributeEditor","STDM")) msg.setText(Message) msg.exec_()
def __init__(self, parent): #Initialize the Qwizard parent QWizard.__init__(self,parent) #inherit the GUI from Designer. self.setupUi(self) self.registerFields() #Initialize the xml filehandler self.tableHandler = ConfigTableReader() self.tableName=None self.party_table_list=[] self.spatial_table_list=[] self. str_column_mapping ={} self.profile='' self.geomEntity=None #if platform.system() =="Windows": # self.setWizardStyle(QWizard.AeroStyle) self.setWindowFlags(Qt.Dialog| Qt.WindowMaximizeButtonHint|Qt.WindowCloseButtonHint) QObject.connect(self.lstEntity,SIGNAL('clicked(QModelIndex)'),self.seletedTableAttrib) QObject.connect(self.pftableView,SIGNAL('clicked(QModelIndex)'),self.selectedTableName) QObject.connect(self.lstEntity_2,SIGNAL('clicked(QModelIndex)'),self.relationForTable) QObject.connect(self.tblEdit, SIGNAL('clicked(QModelIndex)'), self.selectedColumnIndex) QObject.connect(self.tblEdit_2, SIGNAL('clicked(QModelIndex)'), self.selectedColumnIndex) QObject.connect(self.tblLookupList, SIGNAL('clicked(QModelIndex)'), self.lookupColumns) #QObject.connect(self.lstParty, SIGNAL('clicked(QModelIndex)'), self.on_str_party_table_selection) #QObject.connect(self.lstParty, SIGNAL('clicked(QModelIndex)'), self.on_str_party_table_selection) self.btnAdd.clicked.connect(self.addTableColumn) self.btnEdit.clicked.connect(self.columnEditor) self.btnProperty.clicked.connect(self.tableRelationEditor) self.btnDelete.clicked.connect(self.deletedSelectedTable) self.btnSQL.clicked.connect(self.schemaPreview) #self.btnHTML.clicked.connect(self.HTMLFileView) self.btnBrowse.clicked.connect(self.defWorkDir) self.btnBrowse2.clicked.connect(self.setCertificatePath) self.btnTemplates.clicked.connect(self.setTemplatesPath) self.btnBrowse2_2.clicked.connect(self.settingsPath) #self.btnRunSchema.clicked.connect(self.setDatabaseSchema) self.cboProfile.currentIndexChanged.connect(self.selectionChanged) self.btnNew.clicked.connect(self.setTableName) self.btnNew_2.clicked.connect(self.editTableName) self.btnNewP.clicked.connect(self.addProfile) self.btnPDelete.clicked.connect(self.deleteProfile) self.txtHtml.textChanged.connect(self.updateSQLFile) self.btnDel.clicked.connect(self.deleteTableColumn) self.btnPropDel.clicked.connect(self.deleteTableRelation) self.btnLkDel.clicked.connect(self.deleteLookupChoice) self.btnGeomEdit.clicked.connect(self.geom_editor) self.btnAddLk.clicked.connect(self.addLookupValue) self.helpRequested.connect(self.HelpContents) self.rbSchema.clicked.connect(self.setSqlIsertDefinition) self.rbSchemaNew.clicked.connect(self.setSqlIsertDefinition) self.btnGeomDel.clicked.connect(self.delete_geom) self.cboParty.currentIndexChanged.connect(self.party_str_selection_changed) self.cboSPUnit.currentIndexChanged.connect(self.spatial_str_selection_changed) try: settings = self.tableHandler.pathSettings() if not settings[1].get('Config'): self.startId() == 1 elif settings[1].get('Config'): self.setStartId(2) except Exception as ex: QMessageBox.critical(self,QApplication.translate("WorkspaceLoader","Settings Retrieval"), QApplication.translate("WorkspaceLoader","Unable to detect previous settings"+ ex.message))
class WorkspaceLoader(QWizard,Ui_STDMWizard): def __init__(self, parent): #Initialize the Qwizard parent QWizard.__init__(self,parent) #inherit the GUI from Designer. self.setupUi(self) self.registerFields() #Initialize the xml filehandler self.tableHandler = ConfigTableReader() self.tableName=None self.party_table_list=[] self.spatial_table_list=[] self. str_column_mapping ={} self.profile='' self.geomEntity=None #if platform.system() =="Windows": # self.setWizardStyle(QWizard.AeroStyle) self.setWindowFlags(Qt.Dialog| Qt.WindowMaximizeButtonHint|Qt.WindowCloseButtonHint) QObject.connect(self.lstEntity,SIGNAL('clicked(QModelIndex)'),self.seletedTableAttrib) QObject.connect(self.pftableView,SIGNAL('clicked(QModelIndex)'),self.selectedTableName) QObject.connect(self.lstEntity_2,SIGNAL('clicked(QModelIndex)'),self.relationForTable) QObject.connect(self.tblEdit, SIGNAL('clicked(QModelIndex)'), self.selectedColumnIndex) QObject.connect(self.tblEdit_2, SIGNAL('clicked(QModelIndex)'), self.selectedColumnIndex) QObject.connect(self.tblLookupList, SIGNAL('clicked(QModelIndex)'), self.lookupColumns) #QObject.connect(self.lstParty, SIGNAL('clicked(QModelIndex)'), self.on_str_party_table_selection) #QObject.connect(self.lstParty, SIGNAL('clicked(QModelIndex)'), self.on_str_party_table_selection) self.btnAdd.clicked.connect(self.addTableColumn) self.btnEdit.clicked.connect(self.columnEditor) self.btnProperty.clicked.connect(self.tableRelationEditor) self.btnDelete.clicked.connect(self.deletedSelectedTable) self.btnSQL.clicked.connect(self.schemaPreview) #self.btnHTML.clicked.connect(self.HTMLFileView) self.btnBrowse.clicked.connect(self.defWorkDir) self.btnBrowse2.clicked.connect(self.setCertificatePath) self.btnTemplates.clicked.connect(self.setTemplatesPath) self.btnBrowse2_2.clicked.connect(self.settingsPath) #self.btnRunSchema.clicked.connect(self.setDatabaseSchema) self.cboProfile.currentIndexChanged.connect(self.selectionChanged) self.btnNew.clicked.connect(self.setTableName) self.btnNew_2.clicked.connect(self.editTableName) self.btnNewP.clicked.connect(self.addProfile) self.btnPDelete.clicked.connect(self.deleteProfile) self.txtHtml.textChanged.connect(self.updateSQLFile) self.btnDel.clicked.connect(self.deleteTableColumn) self.btnPropDel.clicked.connect(self.deleteTableRelation) self.btnLkDel.clicked.connect(self.deleteLookupChoice) self.btnGeomEdit.clicked.connect(self.geom_editor) self.btnAddLk.clicked.connect(self.addLookupValue) self.helpRequested.connect(self.HelpContents) self.rbSchema.clicked.connect(self.setSqlIsertDefinition) self.rbSchemaNew.clicked.connect(self.setSqlIsertDefinition) self.btnGeomDel.clicked.connect(self.delete_geom) self.cboParty.currentIndexChanged.connect(self.party_str_selection_changed) self.cboSPUnit.currentIndexChanged.connect(self.spatial_str_selection_changed) try: settings = self.tableHandler.pathSettings() if not settings[1].get('Config'): self.startId() == 1 elif settings[1].get('Config'): self.setStartId(2) except Exception as ex: QMessageBox.critical(self,QApplication.translate("WorkspaceLoader","Settings Retrieval"), QApplication.translate("WorkspaceLoader","Unable to detect previous settings"+ ex.message)) def registerFields(self): self.setOption(self.HaveHelpButton, True) pgCount = self.page(1) pgCount.registerField("Accept",self.rbAccpt) pgCount.registerField("Reject",self.rbReject) def validateCurrentPage (self): validPage = True if self.currentId()==1: if not self.rbAccpt.isChecked(): message = QApplication.translate("WorkspaceLoader"," You must agree to the disclaimer to continue") self.InfoMessage(message) validPage=False if self.rbReject.isChecked(): self.InfoMessage(QApplication.translate("WorkspaceLoader", u"Rejecting to comply with disclaimer policy will cause the wizard to exit.\ STDM will no to be accessible")) validPage=False if self.currentId()==2: if self.txtDefaultFolder.text()=='' or self.txtCertFolder.text()=='' or self.txtSetting.text()=='': self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Data directory paths are not given")) validPage=False if self.currentId()==3: if self.profile=='': if self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader",\ "You have not selected any default profile for your configuration. \n "\ "The current profile will be used as default instead"))==QMessageBox.No: validPage=False if self.currentId() == 4: """ """ if self.currentId() == 5: if self.cboParty.currentText()== "" or self.cboSPUnit.currentText() =="": message = QApplication.translate("WorkspaceLoader","Not all str tables are selected") self.ErrorInfoMessage(message) validPage = False if self.cboParty.currentText() == self.cboSPUnit.currentText(): msg = QApplication.translate("WorkspaceLoader","Party table cannot be same as " "spatial unit table") self.ErrorInfoMessage(msg) validPage =False str_table = 'social_tenure_relationship' if self.cboParty.currentText() ==str_table or self.cboSPUnit.currentText()==str_table: msg = QApplication.translate("WorkspaceLoader",str_table+" cannot be selected as STR table, " "select another table") self.ErrorInfoMessage(msg) validPage =False if self.currentId() == 6: if self.setDatabaseSchema() == 'success' or self.rbSkip.isChecked(): validPage = True else: validPage = False return validPage def initializePage(self, int): if self.currentId()==1: self.licenseFile() if self.currentId()==2: self.configPath() if self.currentId()==3: self.pathSettings() self.profileContent() if self.currentId()==4: #self.toolbtn.setPopupMode(QToolButton.InstantPopup) self.registerProfileSettings() self.readUserTable() try: if self.tableName: self.loadTableColumns(self.tableName) except Exception as ex: self.ErrorInfoMessage(ex.message) self.tblLookup.setAlternatingRowColors(True) if self.currentId() == 5: self.groupBox_3.setCollapsed(True) self.groupBox_4.setCollapsed(True) str_tables_class = SocialTenureRelation(self.tableHandler) str_tables_class.on_tab_focus(self.cboParty) str_tables_class.on_tab_focus(self.cboSPUnit) self.update_social_tenure_tables() self.str_tables_selected() if self.currentId()==6: self.selected_str_tables() self.txtHtml.hide() self.rbSchema.setChecked(True) self.setSqlIsertDefinition() if self.currentId()==7: try: self.setDatabaseSchema() except: return def load_str_tables(self): """ :return: """ #return party_str_list, sp_unit_str_lst def checkTablesExist(self,activeProfile): '''Method to check if the right config exist in the directory and then return the table names''' table_exist = self.tableHandler.tableListModel(activeProfile) return table_exist def on_table_selection(self): """ Method to read and return all the core table from the config for the profile :return: """ self.profile = self.cboProfile.currentText() model = self.tableHandler.tableListModel(self.profile) return model def readUserTable(self): '''Start the profile table list for editing attributes''' model = self.on_table_selection() self.lstEntity.setModel(model) self.lstEntity_2.setModel(model) self.lstEntity.setContextMenuPolicy(Qt.CustomContextMenu) self.lstEntity.customContextMenuRequested.connect(self.popup) self.lstEntity.setWrapping(True) self.populateLookup() def lookupTables(self): '''get the lookup tables''' return self.tableHandler.lookupTable() def populateLookup(self): lookupModel = self.tableHandler.lookupTableModel() self.tblLookupList.setModel(lookupModel) def loadTableData(self,profile,widget): '''method returns the model to the passed listview widget''' model = self.tableHandler.profile_tables(profile) #QMessageBox.information(self,"Test",str(type)) widget.setModel(model) widget.resizeColumnToContents(0) #return widget def profileContent(self): '''Loads all available content/table from the config for the selected profile''' profiles = self.tableHandler.STDMProfiles() #for pf in profiles: self.cboProfile.clear() self.cboProfile.insertItems(0,profiles) self.cboProfile.setCurrentIndex(0) self.loadTableData(self.profile, self.pftableView) def setDefualtProfile(self): ''' Check to see if user want to save a specific profile to settings ''' if self.cboProfile.currentText()!='': self.profile=self.cboProfile.currentText() else: self.profile=self.cboProfile.itemText(0) def selectionChanged(self): '''Listen to user selection for the profile to load the corresponding table''' self.tableName=None self.profile = str(self.cboProfile.currentText()) self.loadTableData(self.profile, self.pftableView) self.registerProfileSettings() self.lblDescprition.setText(profileFullDescription(self.profile)) def registerProfileSettings(self): profile = QApplication.translate("WorkspaceLoader","currentProfile") self.tableHandler.setProfileSettings({profile:self.profile}) def loadTableColumns(self, tableName): '''Get a list of all Columns defined for the given table name''' columnModel=None if tableName==None: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Table Not defined")) return columnModel=self.tableHandler.columns(self.profile,tableName) self.tblEdit.clearSpans() self.tblEdit.setModel(columnModel) self.loadTableRelations(tableName) self.tblEdit.resizeColumnsToContents() self.tblEdit.setColumnWidth(4,100) self.showGeometryColumns(tableName) def loadTableRelations(self, tableName): '''Method to load defined relations for the given table from the config''' self.tblEdit_2.clearSpans() if tableName==None: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","No Table selected")) return relationModel=self.tableHandler.tableRelation(tableName) self.tblEdit_2.setModel(relationModel) def showGeometryColumns(self,tableName): '''method to show defined geometry columns in a table model''' self.tblLookup_2.clearSpans() if tableName == None: return geometry_col_model = self.tableHandler.geometry_collection(tableName) self.tblLookup_2.setModel(geometry_col_model) def relationForTable(self): '''Load defined relations for the selected table''' self.tblEdit_2.clearSpans() selectIndex = self.lstEntity_2.selectedIndexes() if len(selectIndex)>0: tabName = selectIndex[0] self.loadTableRelations(tabName.data()) self.tableName = tabName.data() def EditTableNode(self): '''Select table for editing and adding new attributes''' selectIndex=self.lstEntity.selectionModel().selectedIndexes() if len(selectIndex)>0: tabName=selectIndex[0] self.tableName=tabName.data() self.loadTableColumns(self.tableName) def seletedTableAttrib(self): '''Modify table data including table name''' selectIndex=self.lstEntity.selectionModel().selectedIndexes() if len(selectIndex)>0: tabName=selectIndex[0] self.tableName=tabName.data() self.loadTableColumns(self.tableName) def selectedTableName(self): '''Modify table data including table name''' selectIndex=self.pftableView.selectionModel().selectedIndexes() if len(selectIndex)>0: tabName=selectIndex[0] self.loadTableColumns(tabName.data()) self.tableName=tabName.data() else: return None def on_str_tables_load(self, cbotype, text): """ Method to set default party and spatial unit table in STR table definition page :return: """ p_index = cbotype.findText(text,Qt.MatchExactly) if p_index != -1: cbotype.setCurrentIndex(p_index) profile = self.tableHandler.active_profile() if cbotype == self.cboParty: self.lblPartyDesc.setText(table_description(text)) else: self.lblSpDesc.setText(table_description(text)) else: cbotype.setCurrentIndex(0) def str_tables_selected(self): """ Method to read previous str tables from the config and return selected columns :return: """ party, spatial = self.tableHandler.social_tenure_table_types() self.on_str_tables_load(self.cboParty, party) self.on_str_tables_load(self.cboSPUnit, spatial) self.update_listveiw_cols(self.lstPartyCol, self.cboParty.currentText()) self.update_listveiw_cols(self.lstSPCol, self.cboSPUnit.currentText()) def party_str_selection_changed(self): """ Method to sync the table details when party table is selected :return: """ cur_text = self.cboParty.currentText() self.lblPartyDesc.setText(table_description(cur_text)) table_cols = self.tableHandler.selected_table_columns(cur_text) self.lstPartyCol.setModel(self.table_cols_to_model(table_cols,True)) self.update_listveiw_cols(self.lstPartyCol, cur_text) self.groupBox_3.setCollapsed(False) def spatial_str_selection_changed(self): """ Method to sync the table details when spatial table is selected :return: """ cur_text = self.cboSPUnit.currentText() self.lblSpDesc.setText(table_description(cur_text)) table_cols = self.tableHandler.selected_table_columns(cur_text) self.lstSPCol.setModel(self.table_cols_to_model(table_cols,True)) self.update_listveiw_cols(self.lstSPCol,cur_text) self.groupBox_4.setCollapsed(False) def update_listveiw_cols(self, col_view, table): """ Method to keep track of last checked items as str columns :param table: :return: """ col_list = self.tableHandler.social_tenure_col(table) c_rows = col_view.model().rowCount() for row in range(c_rows): col_item = col_view.model().item(row) if col_item.text() in col_list: col_item.setCheckState(Qt.Checked) def table_cols_to_model(self, list, bool): """ Method to return passed table list to a checkable list model :param bool, list: :return: QAbstractItemModel """ model = CheckableListModel(list) model.setCheckable(bool) return model def selected_str_tables(self): """ Method to write str selection tables and columns in the config :return: """ col_collection = self.selected_table_str_column() if len(col_collection.values()[0])>0: self.tableHandler.set_table_str_columns(self.cboParty.currentText(),col_collection.values()[0]) if len(col_collection.values()[1])>0: self.tableHandler.set_table_str_columns(self.cboSPUnit.currentText(), col_collection.values()[1]) old_str_tables = self.tableHandler.social_tenure_tables() str_tables = [self.cboParty.currentText(), self.cboSPUnit.currentText()] if set(old_str_tables).intersection(str_tables) == set(str_tables): return else: self.update_new_str_action() for table in str_tables: self.tableHandler.update_str_tables(table,'yes') self.tableHandler.set_str_type_collection(self.cboParty.currentText(),'party') self.tableHandler.set_str_type_collection(self.cboSPUnit.currentText(),'spatial unit') def update_new_str_action(self): """ Method to ensure there are no conflict in the current selection Scan through the tables and set unselected tables as non str tables :return: """ tables = self.tableHandler.current_profile_tables() for table in tables: self.tableHandler.update_str_tables(table,'no') def selected_table_str_column(self): """ Method to read the selected columns for str tables :param table: :return: """ colitems = {} plist=[] splist = [] p_rows = self.lstPartyCol.model().rowCount() for row in range(p_rows): col_item = self.lstPartyCol.model().item(row) if col_item.checkState()== Qt.Checked: plist.append(col_item.text()) sp_rows = self.lstSPCol.model().rowCount() for srow in range(sp_rows): scol_item = self.lstSPCol.model().item(srow) if scol_item.checkState()== Qt.Checked: splist.append(scol_item.text()) colitems[self.cboParty.currentText()] = plist colitems[self.cboSPUnit.currentText()] = splist return colitems def update_social_tenure_tables(self): """ Method reload previously selected str tables :return: """ str_tables = self.tableHandler.social_tenure_tables() if str_tables: p_index = self.cboParty.findText(str_tables[0],Qt.MatchExactly) if (p_index)!=-1: self.cboParty.setCurrentIndex(p_index) sp_index = self.cboSPUnit.findText(str_tables[1],Qt.MatchExactly) if (sp_index)!=-1: self.cboSPUnit.setCurrentIndex(sp_index) def addTableColumn(self): '''add new attribute for the table''' if self.tableName!=None: colDlg=AttributeEditor(str(self.cboProfile.currentText()),self.tableName,self) colDlg.exec_() self.loadTableColumns(self.tableName) else: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Please select table to add attributes")) return self.populateLookup() def columnEditor(self): '''Edit selected table column''' try: selCols=self.tblEdit.selectionModel().selectedIndexes() EditorSession=[] if len(selCols)>0 and self.tableName!=None: EditorSession.append(selCols[0].data()) EditorSession.append(selCols[1].data()) EditorSession.append(selCols[2].data()) EditorSession.append(selCols[3].data()) EditorSession.append(selCols[4].data()) EditorSession.append(selCols[5].data()) colDlg = AttributeEditor(str(self.cboProfile.currentText()),self.tableName,self,args=EditorSession) colDlg.exec_() else: self.InfoMessage(QApplication.translate("WorkspaceLoader","No table column is selected for editing")) return except: pass self.loadTableColumns(self.tableName) self.loadTableRelations(self.tableName) self.populateLookup() def geom_editor(self): '''Edit selected geom column from the geometry table''' #QMessageBox.information(self,"Editing geom", "Starting") try: selCols=self.tblLookup_2.selectionModel().selectedIndexes() EditorSession=[] if len(selCols)>0 and self.tableName!=None: EditorSession.append(selCols[1].data()) EditorSession.append(selCols[2].data()) EditorSession.append(selCols[3].data()) colDlg = GeometryEditor(self,str(self.cboProfile.currentText()), self.tableName,args=EditorSession) colDlg.exec_() else: self.InfoMessage(QApplication.translate("WorkspaceLoader","No table column is selected for editing")) return except Exception as ex: self.ErrorInfoMessage(ex.message) return self.showGeometryColumns(self.tableName) def tableRelationEditor(self): if self.tableName!=None: colDlg=TableProperty(str(self.cboProfile.currentText()),self.tableName,self) colDlg.exec_() self.loadTableRelations(self.tableName) else: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Please select table to add attributes")) return def selectedColumnIndex(self): '''Method to return selected table item in the list''' selCols=self.tblEdit.selectionModel().selectedIndexes() if len(selCols)>0: item=selCols[0].data() else: return def lookupColumns(self): selCols=self.tblLookupList.selectionModel().selectedIndexes() if len(selCols)>0: tableName=selCols[0].data() self.lookupColumnsTowidget(tableName) self.tableName=tableName self.lookupDefinedValues() else: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","No selections")) return def lookupColumnsTowidget(self, tableName): '''Get a list of all Columns defined for the given table name''' columnModel=None if tableName==None: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","lookup Not defined")) return columnModel=self.tableHandler.lookupColumns(tableName) self.tblEdit.clearSpans() self.tblEdit.setModel(columnModel) self.loadTableRelations(tableName) self.tblEdit.resizeColumnsToContents() def setTableName(self): actionState=[self.profile,QApplication.translate("WorkspaceLoader","Add Table")] self.addTable(actionState) self.loadTableData(self.profile, self.pftableView) def editTableName(self): if self.tableName==None: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","No table is selected")) return if self.tableName in stdm_core_tables: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader", "Sorry, the current table is a core table " "and cannot be changed")) return actionState=[self.profile,QApplication.translate("WorkspaceLoader","Edit Table")] self.addTable(actionState) self.loadTableData(self.profile, self.pftableView) def addTable(self,actionState): '''add new table''' if len(actionState)>1: dlg=TableEditor(actionState,self.tableName,self) dlg.exec_() def addProfile(self): '''add new profile''' profileDlg=ProfileEditor(self) profileDlg.exec_() self.profileContent() def deletedSelectedTable(self): #use the delete button to remove the selected table if self.tableName==None: self.ErrorInfoMessage(QApplication.translate('WorkspaceLoader',"No table is selected for this operation")) return if self.tableName in stdm_core_tables: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader", "Sorry, the current table is a core table " "and cannot be deleted")) return else: if self.warningInfo(QApplication.translate("WorkspaceLoader","You are about to delete %s table") %self.tableName)==QMessageBox.Yes: deleteTable(self.profile,self.tableName) self.loadTableData(self.profile, self.pftableView) base_name = self.tableName.title() from stdm.data.pg_utils import delete_table_keys delete_table_keys(self.tableName) #QMessageBox.information(None, "Keys",str(delete_table_keys(self.tableName))) #delete_table_keys('content_base',True) self.tableName=None else: return def deleteProfile(self): default_p = "basic" if self.cboProfile.currentIndex==-1: self.InfoMessage(QApplication.translate("WorkspaceLoader","No profile found")) return if self.cboProfile.currentText().lower() == default_p: self.InfoMessage(QApplication.translate("WorkspaceLoader", "Current profile cannot be deleted")) return else: if self.warningInfo(QApplication.translate("WorkspaceLoader","You are about to delete current profile"))==QMessageBox.Yes: deleteProfile(self.profile) else: return self.profileContent() def deleteTableColumn(self): '''ensure we deleted the selected table column only by matching name entry in the config''' #try: if self.warningInfo(QApplication.translate('WorkspaceLoader',\ "You are about to delete selected column from table (%s)" )%self.tableName) == QMessageBox.Yes: selCols=self.tblEdit.selectionModel().selectedIndexes() if len(selCols)>0: item = selCols[0].data() element = "columns" if str(self.tableName).startswith('check'): deleteColumn(self.profile,'lookup',self.tableName,element,'name',str(item)) self.lookupColumnsTowidget(self.tableName) else: deleteColumn(self.profile,'table',self.tableName,element,'name',str(item)) try: deleteColumn(self.profile,'table',self.tableName,'constraints','column',str(item)) except Exception as ex: self.ErrorInfoMessage(str(ex.message)) self.loadTableColumns(self.tableName) else: return #except: # self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Unable to delete table")) # return def deleteTableRelation(self): '''delete defined table relation from the config ''' if self.warningInfo(QApplication.translate('WorkspaceLoader',\ u"Are you sure you want to deleted selected relation from table (%s)") %self.tableName) == QMessageBox.Yes: selCols = self.tblEdit_2.selectionModel().selectedIndexes() if len(selCols)>0: item = selCols[0].data() element = "relations" deleteColumn(self.profile,'table',self.tableName,element,'name',str(item)) self.loadTableRelations(self.tableName) def delete_geom(self): '''delete defined table relation from the config ''' if self.warningInfo(QApplication.translate('WorkspaceLoader',\ u"Are you sure you want to deleted selected geometry column from table (%s)") %self.tableName) == QMessageBox.Yes: selCols=self.tblLookup_2.selectionModel().selectedIndexes() if len(selCols)>0: item=selCols[1].data() element="geometryz" deleteColumn(self.profile,'table',self.tableName,element,'column',str(item)) self.loadTableRelations(self.tableName) def deleteLookupChoice(self): '''remove a text from the lookup choices''' try: selIndx = self.tblLookup.selectionModel().selectedIndexes() if selIndx: selItem = selIndx[0] else: self.ErrorInfoMessage(QApplication.translate('WorkspaceLoader',\ "No text is selected from the lookup choices")) return if selItem!=None and not self.tableName.startswith('check'): self.ErrorInfoMessage(QApplication.translate('WorkspaceLoader',\ "selected table is not a lookup table")) return if self.warningInfo(QApplication.translate('WorkspaceLoader',\ "Are you sure you want to delete (%s) choice from the table (%s)")%(str(selItem.data()), self.tableName)) == QMessageBox.Yes: if str(self.tableName).startswith('check'): deleteLookupChoice(self.profile,'lookup',self.tableName,'data','value',str(selItem.data())) self.lookupDefinedValues() except: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader", "Unable to delete current record")) def addLookupValue(self): if self.tableName == None: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","No table is selected")) return if self.tableName!=None and self.tableName.startswith("check"): lkDlg = ADDLookupValue(self) if lkDlg.exec_() == QDialog.Accepted: lkName = lkDlg.value self.addLookupToWidget(lkName) else: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","Selected table is not a lookup")) def addLookupToWidget(self,lkText): '''Add lookup to config list and add it to view widget''' self.tableHandler.addLookupValue(self.tableName, str(lkText).capitalize()) self.lookupDefinedValues() def lookupDefinedValues(self): '''load all defined lookup choices for the selected table''' lookUpModel = self.tableHandler.readLookupList(self.tableName) self.tblLookup.clearFocus() self.tblLookup.setModel(lookUpModel) def schemaPreview(self): #Method to allow the user preview customized xml in SQL format if self.txtHtml.isVisible(): self.txtHtml.hide() self.txtHtml.clear() self.btnSQL.setText(QApplication.translate("WorkspaceLoader","Show Generated SQL")) else: self.rawSQLDefinition() self.txtHtml.setVisible(True) self.btnSQL.setText(QApplication.translate("WorkspaceLoader","Close SQL View")) def rawSQLDefinition(self): '''read sql definition on the UI''' self.txtHtml.clear() fileN = self.SQLFileView() color = QColor(192, 192, 192) self.txtHtml.setTextBackgroundColor(color) with open(fileN,'r')as f: self.txtHtml.insertPlainText(f.read()) f. close() def setSqlIsertDefinition(self): '''Add insert sql statement for the lookup defined values''' fileN = self.SQLFileView() if self.rbSchemaNew.isChecked(): if QMessageBox.warning(self, QApplication.translate("WorkspaceLoader","Create New data"), QApplication.translate("WorkspaceLoader","All existing data will be lost, " "do you want to proceed?"), QMessageBox.Yes | QMessageBox.No)== QMessageBox.No: self.rbSchema.setChecked(True) return self.tableHandler.saveXMLchanges() lookups = self.lookupTables() for lookup in lookups: lookupTextList = lookupData2List(self.profile, lookup) sqlInsert = SQLInsert(lookup, lookupTextList) SQLSt = sqlInsert.setInsertStatement() with open(fileN,'a')as f: for row in SQLSt: f.write(row) f.write("\n") f. close() self.setRelation(fileN,sqlInsert) if self.rbSchema.isChecked(): self.tableHandler.upDateSQLSchema() self.rawSQLDefinition() def SQLFileView(self): '''read the SQL in directory''' file = self.tableHandler.sqlTableDefinition() return file def setRelation(self,fileN,sql): with open(fileN,'a')as f: f.write(sql.spatialRelation()) f.write(sql.social_tenure_duplicate_enforce()) f.close() def setDatabaseSchema(self): '''run generated SQL to the database''' valid = 'success' if self.rbSkip.isChecked(): pass else: self.DropSchemaTables() fileName = self.SQLFileView() try: with open(fileName,'r')as f: sqlSt=text(f.read()) roleP=RoleProvider() roleP._execute(sqlSt) self.assignRoles() self.InfoMessage(QApplication.translate("WorkspaceLoader","Changes successfully saved in the STDM database")) flush_session_activity() self.tableHandler.trackXMLChanges() return valid except SQLAlchemyError as ex: self.ErrorInfoMessage(str(ex.message)) return except IOError as ex: self.ErrorInfoMessage(str(ex.message)) return def assignRoles(self): if self.rbSchemaNew.isChecked(): roleP = RoleProvider() roles = roleP.GetSysRoles() for role in roles: roleSql=text("GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO %s;"%(role)) _execute(roleSql) def DropSchemaTables(self): '''Check if table is already defined in pgtables and drop it''' if self.rbSchemaNew.isChecked(): #tables = pg_tables() tables = self.tableHandler.fulltableList() safely_delete_tables(tables) def updateSQLFile(self): '''Method to record and save changes whenever the document's content changes''' fileName = self.SQLFileView() if str(fileName).endswith(".sql"): doc = self.txtHtml.document() docText = str(doc.toPlainText()) if docText != "": try: with open(fileName,'w')as f: f.write(docText) f.close() except IOError as io: self.ErrorInfoMessage(io.message) else: return def popup(self, QAction): #A shortcut menu to allow the user to customize table details on the forms page menu=QMenu() #self.toolbtn.setMenu(menu) self.addAction = menu.addAction(QApplication.translate("WorkspaceLoader","Add Table")) menu.addSeparator() self.editAction = menu.addAction(QApplication.translate("WorkspaceLoader","Rename Table")) self.delAction=menu.addAction(QApplication.translate("WorkspaceLoader","Delete Table")) cursor=QCursor() pos=cursor.pos() action = menu.exec_(self.mapToGlobal(pos)) if action==self.addAction: self.setTableName() if action==self.editAction: if not self.tableName: self.ErrorInfoMessage(QApplication.translate("WorkspaceLoader","No selected table found")) return else: self.editTableName() if action==self.delAction: if self.tableName: if self.warningInfo(QApplication.translate("WorkspaceLoader","Delete (%s) table?")%self.tableName)\ == QMessageBox.Yes: self.deletedSelectedTable() del menu self.readUserTable() def licenseFile(self): self.txtLicense.clear() licenseDoc = LicenseDocument() self.txtLicense.setCurrentFont(licenseDoc.text_font()) self.txtLicense.setText(licenseDoc.read_license_info()) def configPath(self): try: pathKeys, configPath = self.tableHandler.pathSettings() if configPath: self.txtSetting.setText(configPath[pathKeys[0]]) self.txtDefaultFolder.setText(configPath[pathKeys[1]]) self.txtCertFolder.setText(configPath[pathKeys[2]]) self.txtTemplates.setText(configPath[pathKeys[3]]) else: userpath = self.tableHandler.userProfileDir() self.txtSetting.setText(userpath) self.setWorkingDataPath(userpath) self.certificatePath(userpath) self.templatePath() except IOError as io: QMessageBox.information(self, QApplication.translate("WorkspaceLoader",u"Directory Error ")+str(io.message)) def pathSettings(self): """ add user paths to the registry setting and update the new directory with base files :return: """ dataPath={} settings = self.tableHandler.settingsKeys() userPath = [self.txtSetting.text(), self.txtDefaultFolder.text(), self.txtCertFolder.text(), self.txtTemplates.text()] for i in range(len(settings)): dataPath[settings[i]] = userPath[i] self.tableHandler.setProfileSettings(dataPath) self.tableHandler.createDir(dataPath.values()) self.tableHandler.updateDir(self.txtSetting.text()) def settingsPath(self): try: dir_name = self.openDirectoryChooser(QApplication.translate("WorkspaceLoader",\ "Select a directory for configuration Settings")+ str(self.txtSetting.text())) dirPath=dir_name[0] self.tableHandler.check_config_version(dirPath) self.txtSetting.setText(dirPath) self.setWorkingDataPath(dirPath) self.certificatePath(dirPath) self.templatePath() except: pass def defWorkDir(self): dir_name = None try: dir_name=self.openDirectoryChooser(QApplication.translate("WorkspaceLoader", "Select a directory for STDM data"), str(self.txtDefaultFolder.text())) dirPath=dir_name[0] self.setWorkingDataPath(dirPath) self.certificatePath(dirPath) self.templatePath() except: pass def setWorkingDataPath(self, dir_name): self.txtDefaultFolder.setText(str(dir_name)+"/Data") def certificatePath(self,dirP): path = str(dirP)+"/Reports" self.txtCertFolder.setText(path) self.templatePath() def templatePath(self): path = self.txtCertFolder.text() path = path+"/Templates" self.txtTemplates.setText(path) def setCertificatePath(self): try: dir_name = self.openDirectoryChooser(QApplication.translate("WorkspaceLoader", "Select a directory for saving Reports "), str(self.txtCertFolder.text())) self.txtCertFolder.setText(str(dir_name[0])) except: pass def setTemplatesPath(self): try: dir_name=self.openDirectoryChooser(QApplication.translate("WorkspaceLoader", "Select a directory for saving templates"), str(self.txtCertFolder.text())) self.txtTemplates.setText(str(dir_name[0])) except: pass def openDirectoryChooser(self, message, dir=None): #Method to get the user selected directory dirDlg=QFileDialog(self,message,dir) dirDlg.setFileMode(QFileDialog.Directory) dirDlg.setOption(QFileDialog.ShowDirsOnly,True) if dirDlg.exec_()==QDialog.Accepted: selDir=dirDlg.selectedFiles() if len(selDir)>0: return selDir def HelpContents(self): normPath = self.tableHandler.setDocumentationPath() os.startfile(normPath,'open') def ErrorInfoMessage(self, message): # Error Message Box msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setWindowTitle(QApplication.translate("WorkspaceLoader","STDM")) msg.setText(QApplication.translate("WorkspaceLoader",message)) msg.exec_() def InfoMessage(self, message): #Information message box msg=QMessageBox() msg.setWindowTitle(unicode(self.windowTitle())) msg.setIcon(QMessageBox.Information) msg.setText(message) msg.exec_() def warningInfo(self, message): #Information message box msg=QMessageBox() msg.setWindowTitle(unicode(self.windowTitle())) msg.setIcon(QMessageBox.Warning) msg.setStandardButtons(QMessageBox.Yes|QMessageBox.No) msg.setDefaultButton(QMessageBox.No) msg.setText(message) return msg.exec_()
class ViewSTRWidget(QMainWindow, Ui_frmManageSTR): """ Search and browse the social tenure relationship of all participating entities. """ def __init__(self, plugin): QMainWindow.__init__(self, plugin.iface.mainWindow()) self.setupUi(self) self._plugin = plugin self.tbPropertyPreview.set_iface(self._plugin.iface) # Center me self.move(QDesktopWidget().availableGeometry().center() - self.frameGeometry().center()) # set whether currently logged in user has permissions to edit existing STR records self._can_edit = self._plugin.STRCntGroup.canUpdate() """ Variable used to store a reference to the currently selected social tenure relationship when displaying documents in the supporting documents tab window. This ensures that there are no duplicates when the same item is selected over and over again. """ self._strID = None # Used to store the root hash of the currently selected node. self._curr_rootnode_hash = "" self._source_doc_manager = SourceDocumentManager() self._source_doc_manager.documentRemoved.connect(self.onSourceDocumentRemoved) self._source_doc_manager.setEditPermissions(self._can_edit) self._config_table_reader = ConfigTableReader() self.initGui() def initGui(self): """ Initialize widget """ self.tb_actions.setVisible(False) self._load_entity_configurations() # self.gb_supporting_docs.setCollapsed(True) # Connect signals self.tbSTREntity.currentChanged.connect(self.entityTabIndexChanged) self.btnSearch.clicked.connect(self.searchEntityRelations) self.btnClearSearch.clicked.connect(self.clearSearch) self.tvSTRResults.expanded.connect(self.onTreeViewItemExpanded) # Configure notification bar self._notif_search_config = NotificationBar(self.vl_notification) # Set the results treeview to accept requests for context menus self.tvSTRResults.setContextMenuPolicy(Qt.CustomContextMenu) self.tvSTRResults.customContextMenuRequested.connect(self.onResultsContextMenuRequested) # Load async for the current widget self.entityTabIndexChanged(0) def _check_permissions(self): """ Enable/disable actions based on the permissions defined in the content group. """ if self._can_edit: self.tb_actions.addAction(self._new_str_action) else: self.tb_actions.removeAction(self._new_str_action) if len(self.tb_actions.actions()) == 0: self.tb_actions.setVisible(False) else: self.tb_actions.setVisible(True) def _load_entity_configurations(self): """ Specify the entity configurations. """ try: tables = self._config_table_reader.social_tenure_tables() for t in tables: # Ensure 'supporting_document' table is not in the list if t.find("supporting_document") == -1: entity_cfg = self._entity_config_from_table(t) if not entity_cfg is None: entity_widget = self.add_entity_config(entity_cfg) entity_widget.setNodeFormatter(EntityNodeFormatter(entity_cfg, self.tvSTRResults, self)) except ProfileException as pe: self._notif_bar.clear() self._notif_bar.insertErrorNotification(pe.message) def _entity_config_from_table(self, table_name): """ Creates an EntityConfig object from the table name. :param table_name: Name of the database table. :type table_name: str :return: Entity configuration object. :rtype: EntityConfig """ table_display_name = display_name(table_name) model = DeclareMapping.instance().tableMapping(table_name) if model is not None: # Entity configuration entity_cfg = EntityConfiguration() entity_cfg.Title = table_display_name entity_cfg.STRModel = model entity_cfg.data_source_name = table_name """ Load filter and display columns using only those which are of numeric/varchar type """ cols = numeric_varchar_columns(table_name) search_cols = self._config_table_reader.table_searchable_columns(table_name) disp_cols = self._config_table_reader.table_columns(table_name) for c in search_cols: # Ensure it is a numeric or text type column if c in cols: entity_cfg.filterColumns[c] = display_name(c) if len(disp_cols) == 0: entity_cfg.displayColumns = entity_cfg.displayColumns else: for dc in disp_cols: if dc in cols: entity_cfg.displayColumns[dc] = display_name(dc) return entity_cfg else: return None def add_entity_config(self, config): """ Set an entity configuration option and add it to the 'Search Entity' tab. """ entityWidg = STRViewEntityWidget(config) entityWidg.asyncStarted.connect(self._progressStart) entityWidg.asyncFinished.connect(self._progressFinish) tabIndex = self.tbSTREntity.addTab(entityWidg, config.Title) return entityWidg def entityTabIndexChanged(self, index): """ Raised when the tab index of the entity search tab widget changes. """ # Get the current widget in the tab container entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget, EntitySearchItem): entityWidget.loadAsync() def searchEntityRelations(self): """ Slot that searches for matching items for the specified entity and corresponding STR entities. """ self._reset_controls() entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget, EntitySearchItem): valid, msg = entityWidget.validate() if not valid: self._notif_search_config.clear() self._notif_search_config.insertErrorNotification(msg) return formattedNode, results, searchWord = entityWidget.executeSearch() # Show error message if len(results) == 0: noResultsMsg = QApplication.translate("ViewSTR", "No results found for '" + searchWord + "'") self._notif_search_config.clear() self._notif_search_config.insertErrorNotification(noResultsMsg) return if formattedNode is not None: self._load_root_node(formattedNode) def clearSearch(self): """ Clear search input parameters (for current widget) and results. """ entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget, EntitySearchItem): entityWidget.reset() self._reset_controls() def _reset_controls(self): # Clear tree view self._resetTreeView() # Clear document listings self._deleteSourceDocTabs() # Remove spatial unit memory layer self.tbPropertyPreview.remove_layer() def on_select_results(self, selected, deselected): """ Slot which is raised when the selection is changed in the tree view selection model. """ selIndexes = selected.indexes() # Check type of node and perform corresponding action for mi in selIndexes: if mi.isValid(): node = mi.internalPointer() if mi.column() == 0: # Assert if node represents another entity has been clicked self._on_node_reference_changed(node.rootHash()) if isinstance(node, SupportsDocumentsNode): src_docs = node.documents() str_id = node.id() if str_id != self._strID: self._strID = str_id self._load_source_documents(src_docs) if isinstance(node, SpatialUnitNode): self.draw_spatial_unit(node.model()) def onSourceDocumentRemoved(self, container_id): """ Slot raised when a source document is removed from the container. If there are no documents in the specified container then remove the tab. """ for i in range(self.tbSupportingDocs.count()): docwidget = self.tbSupportingDocs.widget(i) if docwidget.containerId() == container_id: docCount = docwidget.container().count() if docCount == 0: self.tbSupportingDocs.removeTab(i) del docwidget break def draw_spatial_unit(self, model): """ Render the geometry of the given spatial unit in the spatial view. :param row_id: Sqlalchemy oject representing a feature. """ self.tbPropertyPreview.draw_spatial_unit(model) def removeSourceDocumentWidget(self, container_id): """ Convenience method that removes the tab widget that lists the source documents with the given container id. """ for i in range(self.tbSupportingDocs.count()): docwidget = self.tbSupportingDocs.widget(i) if docwidget.containerId() == container_id: self.tbSupportingDocs.removeTab(i) self._source_doc_manager.removeContainer(container_id) del docwidget break def onTreeViewItemExpanded(self, modelindex): """ Raised when a tree view item is expanded. Reset the document listing and map view if the hash of the parent node is different. """ if modelindex.isValid(): node = modelindex.internalPointer() # Assert if node representing another entity has been clicked self._on_node_reference_changed(node.rootHash()) def onResultsContextMenuRequested(self, pnt): """ Slot raised when the user right-clicks on a node item to request the corresponding context menu. """ # Get the model index at the specified point mi = self.tvSTRResults.indexAt(pnt) if mi.isValid(): node = mi.internalPointer() rMenu = QMenu(self) # Load node actions items into the context menu node.manageActions(mi, rMenu) rMenu.exec_(QCursor.pos()) def showEvent(self, event): """ (Re)load map layers in the viewer canvas. :param event: Window event :type event: QShowEvent """ # Check if there are entity configurations defined if self.tbSTREntity.count() == 0: msg = QApplication.translate( "ViewSTR", "There are no configured " "entities to search against. Please " "check the social tenure relationship " "tables in the Form Designer.", ) QMessageBox.critical(self, QApplication.translate("ViewSTR", "Social Tenure Relationship"), msg) self.setEnabled(False) event.ignore() return QMainWindow.showEvent(self, event) if not self._check_str_table(): msg = QApplication.translate( "ViewSTR", "'social_tenure_relationship' " "table could not be found. Please " "recreate the table in the Form " "Designer and configure the related " "entities.", ) QMessageBox.critical(self, QApplication.translate("ViewSTR", "Social Tenure Relationship"), msg) self.setEnabled(False) event.ignore() return QMainWindow.showEvent(self, event) self.setEnabled(True) self._notify_no_base_layers() self.tbPropertyPreview.refresh_canvas_layers() self.tbPropertyPreview.load_web_map() return QMainWindow.showEvent(self, event) def _check_str_table(self): """ Checks whether a table explicitly named 'social_tenure_relationship' exists in th database. :return: True if the table exists.Otherwise False. :rtype: bool """ return pg_table_exists("social_tenure_relationship", False) def _notify_no_base_layers(self): """ Checks if there are any base layers that will be used when visualizing the spatial units. If there are no base layers then insert warning message. """ self._notif_search_config.clear() num_layers = len(self._plugin.iface.legendInterface().layers()) if num_layers == 0: msg = QApplication.translate( "ViewSTR", "No basemap layers are loaded in the current project. " "Basemap layers enhance the visualization of" " spatial units.", ) self._notif_search_config.insertWarningNotification(msg) def _deleteSourceDocTabs(self): """ Removes all source document tabs and deletes their references. """ tabCount = self.tbSupportingDocs.count() while tabCount != 0: srcDocWidget = self.tbSupportingDocs.widget(tabCount - 1) self.tbSupportingDocs.removeTab(tabCount - 1) del srcDocWidget tabCount -= 1 self._strID = None self._source_doc_manager.reset() def _resetTreeView(self): """ Clears the results tree view. """ # Reset tree view strModel = self.tvSTRResults.model() resultsSelModel = self.tvSTRResults.selectionModel() if strModel: strModel.clear() if resultsSelModel: self.disconnect( resultsSelModel, SIGNAL("selectionChanged(const QItemSelection&,const QItemSelection&)"), self.on_select_results, ) def _load_root_node(self, root): """ Load the search results (formatted into an object of type 'stdm.navigaion.STR') into the tree view. """ strTreeViewModel = STRTreeViewModel(root, view=self.tvSTRResults) self.tvSTRResults.setModel(strTreeViewModel) # Resize tree columns to fit contents self._resize_columns() # Capture selection changes signals when results are returned in the tree view resultsSelModel = self.tvSTRResults.selectionModel() resultsSelModel.selectionChanged.connect(self.on_select_results) def _resize_columns(self): """ Adjusts the column sizes to fit its contents """ qModel = self.tvSTRResults.model() columnCount = qModel.columnCount() for i in range(columnCount): self.tvSTRResults.resizeColumnToContents(i) # Once resized then slightly increase the width of the first column so that text for 'No STR Defined' visible. currColWidth = self.tvSTRResults.columnWidth(0) newColWidth = currColWidth + 100 self.tvSTRResults.setColumnWidth(0, newColWidth) def _load_source_documents(self, source_docs): """ Load source documents into document listing widget. """ # Configure progress dialog progressMsg = QApplication.translate("ViewSTR", "Loading supporting documents...") progressDialog = QProgressDialog(progressMsg, "", 0, len(source_docs), self) progressDialog.setWindowModality(Qt.WindowModal) for i, doc in enumerate(source_docs): progressDialog.setValue(i) type_id = doc.document_type container = self._source_doc_manager.container(type_id) # Check if a container has been defined and create if None is found if container is None: src_doc_widget = SourceDocumentContainerWidget(type_id) container = src_doc_widget.container() self._source_doc_manager.registerContainer(container, type_id) # Add widget to tab container for source documents tab_title = QApplication.translate("ViewSTR", "General") if type_id in DOC_TYPE_MAPPING: tab_title = DOC_TYPE_MAPPING[type_id] else: if type_id in STR_DOC_TYPE_MAPPING: tab_title = STR_DOC_TYPE_MAPPING[type_id] self.tbSupportingDocs.addTab(src_doc_widget, tab_title) self._source_doc_manager.insertDocFromModel(doc, type_id) progressDialog.setValue(len(source_docs)) def _on_node_reference_changed(self, rootHash): """ Method for resetting document listing and map preview if another root node and its children are selected then the documents are reset as well as the map preview control. """ if rootHash != self._curr_rootnode_hash: self._deleteSourceDocTabs() self._curr_rootnode_hash = rootHash def _progressStart(self): """ Load progress dialog window. For items whose durations is unknown, 'isindefinite' = True by default. If 'isindefinite' is False, then 'rangeitems' has to be specified. """ pass def _progressFinish(self): """ Hide progress dialog window. """ pass def _edit_permissions(self): """ Returns True/False whether the current logged in user has permissions to create new social tenure relationships. If true, then the system assumes that they can also edit STR records. """ canEdit = False userName = stdm.data.app_dbconn.User.UserName authorizer = Authorizer(userName) newSTRCode = "9576A88D-C434-40A6-A318-F830216CA15A" # Get the name of the content from the code cnt = Content() createSTRCnt = cnt.queryObject().filter(Content.code == newSTRCode).first() if createSTRCnt: name = createSTRCnt.name canEdit = authorizer.CheckAccess(name) return canEdit