Пример #1
0
 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) 
Пример #2
0
 def initControls(self):
     #perform initialization of controls
     self.profile = activeProfile()
     self.handler = ConfigTableReader()
     Lkupmodel = self.handler.lookupTableModel()
     self.cboTable.setModel(Lkupmodel)
     self.showDefinedLookupChoices()
Пример #3
0
    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()
Пример #4
0
 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()
Пример #5
0
    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()
Пример #6
0
    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)
Пример #7
0
 def tableModel(self):
     tableHandler = ConfigTableReader()
     tableModel = tableHandler.tableListModel(self.profile)
     self.cboInheritTable.setModel(tableModel)
Пример #8
0
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_()  
Пример #9
0
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_() 
Пример #10
0
    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))
Пример #11
0
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_()
Пример #12
0
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