def initGui(self): ''' Initialize widget ''' self.loadEntityConfig() #Hook up signals self.connect(self.tbSTREntity, SIGNAL("currentChanged(int)"), self.entityTabIndexChanged) self.connect(self.btnSearch, SIGNAL("clicked()"), self.searchEntityRelations) self.connect(self.btnClearSearch, SIGNAL("clicked()"), self.clearSearch) self.connect(self.tvSTRResults, SIGNAL("expanded(const QModelIndex&)"), self.onTreeViewItemExpanded) #Configure notification bars self.notifSearchConfig = NotificationBar(self.vlSearchEntity) #Set the results treeview to accept requests for context menus self.tvSTRResults.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tvSTRResults, SIGNAL("customContextMenuRequested(const QPoint&)"), self.onResultsContextMenuRequested) #Load async for the current widget self.entityTabIndexChanged(0)
def initConflict(self): ''' Initialize 'Conflict' GUI controls ''' loadComboSelections(self.cboConflictOccurrence, CheckConflictState) self.notifConflict = NotificationBar(self.vlConflictNotif,3000)
def initSourceDocument(self): ''' Initialize source document page ''' #Set currency regular expression and currency prefix rx = QRegExp("^\\d{1,12}(([.]\\d{2})*),(\\d{2})$") rxValidator = QRegExpValidator(rx,self) ''' self.txtCFBPAmount.setValidator(rxValidator) self.txtStateReceiptAmount.setValidator(rxValidator) self.dtLastYearCFBP.setMaximumDate(QDate.currentDate()) self.dtStateReceiptDate.setMaximumDate(QDate.currentDate()) self.dtStateLeaseYear.setMaximumDate(QDate.currentDate()) ''' self.notifSourceDoc = NotificationBar(self.vlSourceDocNotif) #Set source document manager self.sourceDocManager = SourceDocumentManager() #self.privateTaxDocManager = SourceDocumentManager() #self.stateTaxDocManager = SourceDocumentManager() self.sourceDocManager.registerContainer(self.vlDocTitleDeed, TITLE_DEED) ''' #Connect signals self.connect(self.rbPrivateProperty, SIGNAL("toggled(bool)"),self.onSelectPrivateProperty) self.connect(self.rbStateland, SIGNAL("toggled(bool)"),self.onSelectStateland) self.connect(self.btnPrivateReceiptScan, SIGNAL("clicked()"),self.onUploadPrivateReceiptScan) self.connect(self.btnPublicReceiptScan, SIGNAL("clicked()"),self.onUploadStateReceiptScan) self.connect(self.btnAddStatRefPaper, SIGNAL("clicked()"),self.onUploadStatutoryRefPaper) self.connect(self.btnAddSurveyorRef, SIGNAL("clicked()"),self.onUploadSurveyorRef) self.connect(self.btnAddNotaryRef, SIGNAL("clicked()"),self.onUploadNotaryRef) ''' self.connect(self.btnAddTitleDeed, SIGNAL("clicked()"),self.onUploadTitleDeed)
def initProperty(self): ''' Initialize property config ''' self.notifProp = NotificationBar(self.vlPropNotif) self.gpOLTitle = self.gpOpenLayers.title() #Flag for checking whether OpenLayers basemaps have been loaded self.olLoaded = False #Initialize lookup for properties propertyWorker = PropertyWorker(self) self.connect(propertyWorker, SIGNAL("retrieved(PyQt_PyObject)"), self._onPropertiesLoaded) #Connect signals QObject.connect(self.gpOpenLayers, SIGNAL("toggled(bool)"), self._onEnableOLGroupbox) QObject.connect(self.zoomSlider, SIGNAL("sliderReleased()"), self._onZoomChanged) QObject.connect(self.btnResetMap , SIGNAL("clicked()"), self._onResetMap) #Start background thread propertyWorker.start() self.propBrowser = PropertyBrowser(self.propWebView,self) self.connect(self.propBrowser,SIGNAL("loadError(QString)"),self._onPropertyBrowserError) self.connect(self.propBrowser,SIGNAL("loadProgress(int)"),self._onPropertyBrowserLoading) self.connect(self.propBrowser,SIGNAL("loadFinished(bool)"),self._onPropertyBrowserFinished) self.connect(self.propBrowser,SIGNAL("zoomChanged(int)"),self.onMapZoomLevelChanged) #Connect signals QObject.connect(self.rbGMaps, SIGNAL("toggled(bool)"),self.onLoadGMaps) QObject.connect(self.rbOSM, SIGNAL("toggled(bool)"),self.onLoadOSM)
def __init__(self, parent=None, selectMode=True): QDialog.__init__(self, parent) self.setupUi(self) self.notifBar = NotificationBar(self.vlNotification) if selectMode: self.buttonBox.setVisible(True) self.manageButtonBox.setVisible(False) currHeight = self.size().height() self.resize(200, currHeight) else: self.buttonBox.setVisible(False) self.manageButtonBox.setVisible(True) self.setWindowTitle( QApplication.translate("TemplateDocumentSelector", "Template Manager")) #Configure manage buttons btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok) btnEdit.setText( QApplication.translate("TemplateDocumentSelector", "Edit...")) btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png")) btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save) btnDelete.setText( QApplication.translate("TemplateDocumentSelector", "Delete")) btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png")) #Connect signals self.buttonBox.accepted.connect(self.onAccept) btnEdit.clicked.connect(self.onEditTemplate) btnDelete.clicked.connect(self.onDeleteTemplate) #Get saved document templates then add to the model templates = documentTemplates() self._docItemModel = QStandardItemModel(parent) self._docItemModel.setColumnCount(2) for name, path in templates.iteritems(): docNameItem = self._createDocNameItem(name) filePathItem = QStandardItem(path) self._docItemModel.appendRow([docNameItem, filePathItem]) self.lstDocs.setModel(self._docItemModel)
def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' loadComboSelections(self.cboSTRType, CheckSocialTenureRelationship) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType)
def initEnjoymentRight(self): ''' Initialize 'Right of Enjoyment' GUI controls ''' self.dtReceivingDate.setMaximumDate(QDate.currentDate()) loadComboSelections(self.cboInheritanceType, CheckInheritanceType) loadComboSelections(self.cboDeadAlive, CheckDeadAlive) self.notifEnjoyment = NotificationBar(self.vlEnjoymentNotif)
def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet(''' QLabel { font: bold; } ''')
def initSourceDocument(self): ''' Initialize source document page ''' #Set currency regular expression and currency prefix rx = QRegExp("^\\d{1,12}(([.]\\d{2})*),(\\d{2})$") rxValidator = QRegExpValidator(rx,self) ''' ''' self.notifSourceDoc = NotificationBar(self.vlSourceDocNotif) #Set source document manager self.sourceDocManager = SourceDocumentManager() self.sourceDocManager.registerContainer(self.vlDocTitleDeed, DEFAULT_DOCUMENT) self.connect(self.btnAddTitleDeed, SIGNAL("clicked()"),self.onUploadTitleDeed)
def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' person = self.mapping.tableMapping('check_social_tenure_type') Person = person() strTypeFormatter =Person.queryObject().all() strType=[ids.value for ids in strTypeFormatter] strType.insert(0, " ") self.cboSTRType.insertItems(0,strType) self.cboSTRType.setCurrentIndex(-1) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType)
def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' pty=Table('check_social_tenure_type',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) session=STDMDb.instance().session strTypeFormatter =session.query(pty.c.value).all() strType=[str(ids[0]) for ids in strTypeFormatter] self.cboSTRType.insertItems(0,strType) strType.insert(0, " ") self.cboSTRType.setCurrentIndex(-1) #loadComboSelections(self.cboSTRType, CheckSocialTenureRelationship) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType)
def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' # pty=Table('check_social_tenure_type',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) # session=STDMDb.instance().session person = self.mapping.tableMapping('check_social_tenure_type') Person = person() strTypeFormatter =Person.queryObject().all() strType=[ids.value for ids in strTypeFormatter] strType.insert(0, " ") self.cboSTRType.insertItems(0,strType) self.cboSTRType.setCurrentIndex(-1) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType)
def __init__(self,parent = None,selectMode=True): QDialog.__init__(self,parent) self.setupUi(self) self.notifBar = NotificationBar(self.vlNotification) if selectMode: self.buttonBox.setVisible(True) self.manageButtonBox.setVisible(False) currHeight = self.size().height() self.resize(200,currHeight) else: self.buttonBox.setVisible(False) self.manageButtonBox.setVisible(True) self.setWindowTitle(QApplication.translate("TemplateDocumentSelector","Template Manager")) #Configure manage buttons btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok) btnEdit.setText(QApplication.translate("TemplateDocumentSelector","Edit...")) btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png")) btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save) btnDelete.setText(QApplication.translate("TemplateDocumentSelector","Delete")) btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png")) #Connect signals self.buttonBox.accepted.connect(self.onAccept) btnEdit.clicked.connect(self.onEditTemplate) btnDelete.clicked.connect(self.onDeleteTemplate) #Get saved document templates then add to the model templates = documentTemplates() self._docItemModel = QStandardItemModel(parent) self._docItemModel.setColumnCount(2) for name,path in templates.iteritems(): docNameItem = self._createDocNameItem(name) filePathItem = QStandardItem(path) self._docItemModel.appendRow([docNameItem,filePathItem]) self.lstDocs.setModel(self._docItemModel)
def initPerson(self): ''' Initialize person config ''' self.notifPerson = NotificationBar(self.vlPersonNotif) self._initPersonFilter() #Initialize person worker thread for fetching person objects self.personWorker = PersonWorker(self) self.connect(self.personWorker, SIGNAL("retrieved(PyQt_PyObject)"),self._loadPersonInfo) #Init summary tree loaders self.personTreeLoader = TreeSummaryLoader(self.tvPersonInfo,QApplication.translate("newSTRWiz","Occupant Information")) #Connect signals QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self._updatePersonCompleter) #Start background thread self.personWorker.start()
def initGui(self): ''' Initialize widget ''' self.loadEntityConfig() #Hook up signals self.connect(self.tbSTREntity, SIGNAL("currentChanged(int)"),self.entityTabIndexChanged) self.connect(self.btnSearch, SIGNAL("clicked()"),self.searchEntityRelations) self.connect(self.btnClearSearch, SIGNAL("clicked()"),self.clearSearch) self.connect(self.tvSTRResults,SIGNAL("expanded(const QModelIndex&)"),self.onTreeViewItemExpanded) #Configure notification bars self.notifSearchConfig = NotificationBar(self.vlSearchEntity) #Set the results treeview to accept requests for context menus self.tvSTRResults.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tvSTRResults,SIGNAL("customContextMenuRequested(const QPoint&)"), self.onResultsContextMenuRequested) #Load async for the current widget self.entityTabIndexChanged(0)
def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet( ''' QLabel { font: bold; } ''' )
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)
class TemplateDocumentSelector(QDialog,Ui_frmDocumentSelector): """ Dialog for selecting a document template from the saved list. """ def __init__(self,parent = None,selectMode=True): QDialog.__init__(self,parent) self.setupUi(self) self.notifBar = NotificationBar(self.vlNotification) if selectMode: self.buttonBox.setVisible(True) self.manageButtonBox.setVisible(False) currHeight = self.size().height() self.resize(200,currHeight) else: self.buttonBox.setVisible(False) self.manageButtonBox.setVisible(True) self.setWindowTitle(QApplication.translate("TemplateDocumentSelector","Template Manager")) #Configure manage buttons btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok) btnEdit.setText(QApplication.translate("TemplateDocumentSelector","Edit...")) btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png")) btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save) btnDelete.setText(QApplication.translate("TemplateDocumentSelector","Delete")) btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png")) #Connect signals self.buttonBox.accepted.connect(self.onAccept) btnEdit.clicked.connect(self.onEditTemplate) btnDelete.clicked.connect(self.onDeleteTemplate) #Get saved document templates then add to the model templates = documentTemplates() self._docItemModel = QStandardItemModel(parent) self._docItemModel.setColumnCount(2) for name,path in templates.iteritems(): docNameItem = self._createDocNameItem(name) filePathItem = QStandardItem(path) self._docItemModel.appendRow([docNameItem,filePathItem]) self.lstDocs.setModel(self._docItemModel) def _createDocNameItem(self,docName): """ Create a template document standard item. """ #Set icon icon = QIcon() icon.addPixmap(QPixmap(":/plugins/stdm/images/icons/document.png"), QIcon.Normal, QIcon.Off) dnItem = QStandardItem(icon,docName) return dnItem def onEditTemplate(self): """ Slot raised to edit document template. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document template to edit")) return templateName,filePath = self.documentMapping() docName,ok = QInputDialog.getText(self, \ QApplication.translate("TemplateDocumentSelector","Edit Template"), \ QApplication.translate("TemplateDocumentSelector","Please enter the new template name below"), \ text = templateName) if ok and docName == "": self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Template name cannot be empty")) return elif docName == templateName: return elif ok and docName != "": result,newTemplatePath = self._editTemplate(filePath, docName) if result: #Update view mIndices = self._selectedMappings() docNameItem = self._docItemModel.itemFromIndex(mIndices[0]) filePathItem = self._docItemModel.itemFromIndex(mIndices[1]) docNameItem.setText(docName) filePathItem.setText(newTemplatePath) self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \ "'{0}' template has been successfully updated".format(docName))) else: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Error: '{0}' template could not be updated".format(templateName))) def onDeleteTemplate(self): """ Slot raised to delete document template. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document template to delete")) return templateName,filePath = self.documentMapping() result = QMessageBox.warning(self, QApplication.translate("TemplateDocumentSelector", \ "Confirm delete"), QApplication.translate("TemplateDocumentSelector", \ "Are you sure you want to delete '{0}' template?" \ "This action cannot be undone.\nClick Yes to proceed " \ "or No to cancel.".format(templateName)), QMessageBox.Yes|QMessageBox.No) if result == QMessageBox.No: return status = self._deleteDocument(filePath) if status: #Remove item from list using model index row number selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0) row = selectedDocNameIndices[0].row() self._docItemModel.removeRow(row) self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \ "'{0}' template has been successfully removed".format(templateName))) else: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Error: '{0}' template could not be removed".format(templateName))) def onAccept(self): """ Slot raised to close the dialog only when a selection has been made by the user. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document")) return self.accept() def _selectedMappings(self): """ Returns the model indices for the selected row. """ selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0) selectedFilePathIndices = self.lstDocs.selectionModel().selectedRows(1) if len(selectedDocNameIndices) == 0: return None docNameIndex = selectedDocNameIndices[0] filePathIndex = selectedFilePathIndices[0] return (docNameIndex,filePathIndex) def documentMapping(self): """ Returns a tuple containing the selected document name and the corresponding file name. """ mIndices = self._selectedMappings() if mIndices == None: return None docNameItem = self._docItemModel.itemFromIndex(mIndices[0]) filePathItem = self._docItemModel.itemFromIndex(mIndices[1]) return (docNameItem.text(),filePathItem.text()) def _editTemplate(self,templatePath,newName): """ Updates the template document to use the new name. """ templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Open Operation Error"), \ "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Cannot read template file."), \ templateFile.errorString() )) return (False,"") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerElement = templateDoc.documentElement() titleAttr = composerElement.attributeNode("title") if not titleAttr.isNull(): titleAttr.setValue(newName) #Try remove file status = templateFile.remove() if not status: return (False,"") #Create new file newTemplatePath = self._composerTemplatesPath() + "/" + newName + ".sdt" newTemplateFile = QFile(newTemplatePath) if not newTemplateFile.open(QIODevice.WriteOnly): QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Operation Error"), \ "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Could not save template file."), \ newTemplateFile.errorString() )) return (False,"") if newTemplateFile.write(templateDoc.toByteArray()) == -1: QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Error"), \ QApplication.translate("TemplateDocumentSelector","Could not save template file.")) return (False,"") newTemplateFile.close() return (True,newTemplatePath) def _deleteDocument(self,templatePath): """ Delete the document template from the file system. """ docFile = QFile(templatePath) return docFile.remove() def _composerTemplatesPath(self): """ Reads the path of composer templates in the registry. """ regConfig = RegistryConfig() keyName = "ComposerTemplates" valueCollection = regConfig.read([keyName]) if len(valueCollection) == 0: return None else: return valueCollection[keyName]
class TemplateDocumentSelector(QDialog, Ui_frmDocumentSelector): """ Dialog for selecting a document template from the saved list. """ def __init__(self, parent=None, selectMode=True): QDialog.__init__(self, parent) self.setupUi(self) self.notifBar = NotificationBar(self.vlNotification) if selectMode: self.buttonBox.setVisible(True) self.manageButtonBox.setVisible(False) currHeight = self.size().height() self.resize(200, currHeight) else: self.buttonBox.setVisible(False) self.manageButtonBox.setVisible(True) self.setWindowTitle( QApplication.translate("TemplateDocumentSelector", "Template Manager")) #Configure manage buttons btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok) btnEdit.setText( QApplication.translate("TemplateDocumentSelector", "Edit...")) btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png")) btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save) btnDelete.setText( QApplication.translate("TemplateDocumentSelector", "Delete")) btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png")) #Connect signals self.buttonBox.accepted.connect(self.onAccept) btnEdit.clicked.connect(self.onEditTemplate) btnDelete.clicked.connect(self.onDeleteTemplate) #Get saved document templates then add to the model templates = documentTemplates() self._docItemModel = QStandardItemModel(parent) self._docItemModel.setColumnCount(2) for name, path in templates.iteritems(): docNameItem = self._createDocNameItem(name) filePathItem = QStandardItem(path) self._docItemModel.appendRow([docNameItem, filePathItem]) self.lstDocs.setModel(self._docItemModel) def _createDocNameItem(self, docName): """ Create a template document standard item. """ #Set icon icon = QIcon() icon.addPixmap(QPixmap(":/plugins/stdm/images/icons/document.png"), QIcon.Normal, QIcon.Off) dnItem = QStandardItem(icon, docName) return dnItem def onEditTemplate(self): """ Slot raised to edit document template. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document template to edit")) return templateName, filePath = self.documentMapping() docName,ok = QInputDialog.getText(self, \ QApplication.translate("TemplateDocumentSelector","Edit Template"), \ QApplication.translate("TemplateDocumentSelector","Please enter the new template name below"), \ text = templateName) if ok and docName == "": self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Template name cannot be empty")) return elif docName == templateName: return elif ok and docName != "": result, newTemplatePath = self._editTemplate(filePath, docName) if result: #Update view mIndices = self._selectedMappings() docNameItem = self._docItemModel.itemFromIndex(mIndices[0]) filePathItem = self._docItemModel.itemFromIndex(mIndices[1]) docNameItem.setText(docName) filePathItem.setText(newTemplatePath) self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \ "'{0}' template has been successfully updated".format(docName))) else: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Error: '{0}' template could not be updated".format(templateName))) def onDeleteTemplate(self): """ Slot raised to delete document template. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document template to delete")) return templateName, filePath = self.documentMapping() result = QMessageBox.warning(self, QApplication.translate("TemplateDocumentSelector", \ "Confirm delete"), QApplication.translate("TemplateDocumentSelector", \ "Are you sure you want to delete '{0}' template?" \ "This action cannot be undone.\nClick Yes to proceed " \ "or No to cancel.".format(templateName)), QMessageBox.Yes|QMessageBox.No) if result == QMessageBox.No: return status = self._deleteDocument(filePath) if status: #Remove item from list using model index row number selectedDocNameIndices = self.lstDocs.selectionModel( ).selectedRows(0) row = selectedDocNameIndices[0].row() self._docItemModel.removeRow(row) self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \ "'{0}' template has been successfully removed".format(templateName))) else: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Error: '{0}' template could not be removed".format(templateName))) def onAccept(self): """ Slot raised to close the dialog only when a selection has been made by the user. """ self.notifBar.clear() if self.documentMapping() == None: self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \ "Please select a document")) return self.accept() def _selectedMappings(self): """ Returns the model indices for the selected row. """ selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0) selectedFilePathIndices = self.lstDocs.selectionModel().selectedRows(1) if len(selectedDocNameIndices) == 0: return None docNameIndex = selectedDocNameIndices[0] filePathIndex = selectedFilePathIndices[0] return (docNameIndex, filePathIndex) def documentMapping(self): """ Returns a tuple containing the selected document name and the corresponding file name. """ mIndices = self._selectedMappings() if mIndices == None: return None docNameItem = self._docItemModel.itemFromIndex(mIndices[0]) filePathItem = self._docItemModel.itemFromIndex(mIndices[1]) return (docNameItem.text(), filePathItem.text()) def _editTemplate(self, templatePath, newName): """ Updates the template document to use the new name. """ templateFile = QFile(templatePath) if not templateFile.open(QIODevice.ReadOnly): QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Open Operation Error"), \ "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Cannot read template file."), \ templateFile.errorString() )) return (False, "") templateDoc = QDomDocument() if templateDoc.setContent(templateFile): composerElement = templateDoc.documentElement() titleAttr = composerElement.attributeNode("title") if not titleAttr.isNull(): titleAttr.setValue(newName) #Try remove file status = templateFile.remove() if not status: return (False, "") #Create new file newTemplatePath = self._composerTemplatesPath( ) + "/" + newName + ".sdt" newTemplateFile = QFile(newTemplatePath) if not newTemplateFile.open(QIODevice.WriteOnly): QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Operation Error"), \ "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Could not save template file."), \ newTemplateFile.errorString() )) return (False, "") if newTemplateFile.write(templateDoc.toByteArray()) == -1: QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Error"), \ QApplication.translate("TemplateDocumentSelector","Could not save template file.")) return (False, "") newTemplateFile.close() return (True, newTemplatePath) def _deleteDocument(self, templatePath): """ Delete the document template from the file system. """ docFile = QFile(templatePath) return docFile.remove() def _composerTemplatesPath(self): """ Reads the path of composer templates in the registry. """ regConfig = RegistryConfig() keyName = "ComposerTemplates" valueCollection = regConfig.read([keyName]) if len(valueCollection) == 0: return None else: return valueCollection[keyName]
class LicenseAgreement(QDialog, Ui_LicenseAgreement): def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet( ''' QLabel { font: bold; } ''' ) def check_show_license(self): """ Checks if you need to show the license page. Checks if the flag in the registry has been set. Returns True to show license. If registry key is not yet set, show the license page. :rtype: boolean """ show_lic = 1 license_key = self.reg_config.read( [SHOW_LICENSE] ) if len(license_key) > 0: show_lic = license_key[SHOW_LICENSE] if show_lic == 1 or show_lic == unicode(1): return True elif show_lic == 0 or show_lic == unicode(0): self.accepted = True return False def show_license(self): """ Show STDM license window if the user have never accepted the license terms and conditions. :return: None :rtype: NoneType """ # validate if to show license show_lic = self.check_show_license() # THe user didn't accept license if show_lic: license = LicenseDocument() self.termsCondArea.setText( license.read_license_info() ) self.exec_() def accept_action(self): """ A slot raised when the user clicks on the Accept button. :return: None :rtype: NoneType """ if not self.checkBoxAgree.isChecked(): msg = QApplication.translate( 'LicenseAgreement', 'To use STDM, please accept the terms ' 'and conditions by selecting' ' the checkbox "I have read and agree ..."' ) self.notice_bar.clear() self.notice_bar.insertNotification(msg, ERROR) return else: self.reg_config.write({SHOW_LICENSE: 0}) self.accepted = True self.close() def decline_action(self): """ A slot raised when the user clicks on the decline button. :return: None :rtype: NoneType """ self.accepted = False self.close()
class newSTRWiz(QWizard, Ui_frmNewSTR): ''' This class handles the listing of locality information ''' def __init__(self,plugin): QWizard.__init__(self,plugin.iface.mainWindow()) self.setupUi(self) #STR Variables self.selPerson = None self.selProperty = None self.enjoymentRight = None self.conflict = None #Initialize GUI wizard pages self.initPerson() self.initProperty() self.initSTRType() self.initEnjoymentRight() self.initSourceDocument() self.initConflict() #Connect signal when the finish button is clicked btnFinish = self.button(QWizard.FinishButton) def initPerson(self): ''' Initialize person config ''' self.notifPerson = NotificationBar(self.vlPersonNotif) self._initPersonFilter() #Initialize person worker thread for fetching person objects self.personWorker = PersonWorker(self) self.connect(self.personWorker, SIGNAL("retrieved(PyQt_PyObject)"),self._loadPersonInfo) #Init summary tree loaders self.personTreeLoader = TreeSummaryLoader(self.tvPersonInfo,QApplication.translate("newSTRWiz","Occupant Information")) #Connect signals QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self._updatePersonCompleter) #Start background thread self.personWorker.start() def initProperty(self): ''' Initialize property config ''' self.notifProp = NotificationBar(self.vlPropNotif) self.gpOLTitle = self.gpOpenLayers.title() #Flag for checking whether OpenLayers basemaps have been loaded self.olLoaded = False #Initialize lookup for properties propertyWorker = PropertyWorker(self) self.connect(propertyWorker, SIGNAL("retrieved(PyQt_PyObject)"), self._onPropertiesLoaded) #Connect signals QObject.connect(self.gpOpenLayers, SIGNAL("toggled(bool)"), self._onEnableOLGroupbox) QObject.connect(self.zoomSlider, SIGNAL("sliderReleased()"), self._onZoomChanged) QObject.connect(self.btnResetMap , SIGNAL("clicked()"), self._onResetMap) #Start background thread propertyWorker.start() self.propBrowser = PropertyBrowser(self.propWebView,self) self.connect(self.propBrowser,SIGNAL("loadError(QString)"),self._onPropertyBrowserError) self.connect(self.propBrowser,SIGNAL("loadProgress(int)"),self._onPropertyBrowserLoading) self.connect(self.propBrowser,SIGNAL("loadFinished(bool)"),self._onPropertyBrowserFinished) self.connect(self.propBrowser,SIGNAL("zoomChanged(int)"),self.onMapZoomLevelChanged) #Connect signals QObject.connect(self.rbGMaps, SIGNAL("toggled(bool)"),self.onLoadGMaps) QObject.connect(self.rbOSM, SIGNAL("toggled(bool)"),self.onLoadOSM) def initializePage(self,id): ''' Initialize summary page based on user selections. ''' if id == 7: self.buildSummary() def nextId(self): ''' Filter subsequent pages based on user selections. If the user has specified 'Heir' as an STR type the load the 'Right of Enjoyment' wizard page. ''' currentId = self.currentId() #Validate STR type selection if currentId == 3: #Determine STR selection then return the appropriate page heir = QApplication.translate("Lookup","Heir") selIndex,ok = self.field("STR_Type").toInt() if ok: #Get index of heir selection heirIndex = self.cboSTRType.findText(heir) if selIndex == heirIndex: return 4 else: return 5 else: return 5 else: return QWizard.nextId(self) def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' loadComboSelections(self.cboSTRType, CheckSocialTenureRelationship) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType) def initEnjoymentRight(self): ''' Initialize 'Right of Enjoyment' GUI controls ''' self.dtReceivingDate.setMaximumDate(QDate.currentDate()) loadComboSelections(self.cboInheritanceType, CheckInheritanceType) loadComboSelections(self.cboDeadAlive, CheckDeadAlive) self.notifEnjoyment = NotificationBar(self.vlEnjoymentNotif) def initSourceDocument(self): ''' Initialize source document page ''' #Set currency regular expression and currency prefix rx = QRegExp("^\\d{1,12}(([.]\\d{2})*),(\\d{2})$") rxValidator = QRegExpValidator(rx,self) self.txtCFBPAmount.setValidator(rxValidator) self.txtStateReceiptAmount.setValidator(rxValidator) self.dtLastYearCFBP.setMaximumDate(QDate.currentDate()) self.dtStateReceiptDate.setMaximumDate(QDate.currentDate()) self.dtStateLeaseYear.setMaximumDate(QDate.currentDate()) self.notifSourceDoc = NotificationBar(self.vlSourceDocNotif) #Set source document manager self.sourceDocManager = SourceDocumentManager() self.privateTaxDocManager = SourceDocumentManager() self.stateTaxDocManager = SourceDocumentManager() self.sourceDocManager.registerContainer(self.vlDocTitleDeed, TITLE_DEED) self.sourceDocManager.registerContainer(self.vlDocStatRefPaper, STATUTORY_REF_PAPER) self.sourceDocManager.registerContainer(self.vlDocSurveyorRef, SURVEYOR_REF) self.sourceDocManager.registerContainer(self.vlDocNotaryRef, NOTARY_REF) #Receipt scan document managers self.privateTaxDocManager.registerContainer(self.vlPrivateReceiptScan, TAX_RECEIPT_PRIVATE) self.stateTaxDocManager.registerContainer(self.vlStateScanReceipt, TAX_RECEIPT_STATE) #Connect signals self.connect(self.rbPrivateProperty, SIGNAL("toggled(bool)"),self.onSelectPrivateProperty) self.connect(self.rbStateland, SIGNAL("toggled(bool)"),self.onSelectStateland) self.connect(self.btnAddTitleDeed, SIGNAL("clicked()"),self.onUploadTitleDeed) self.connect(self.btnPrivateReceiptScan, SIGNAL("clicked()"),self.onUploadPrivateReceiptScan) self.connect(self.btnPublicReceiptScan, SIGNAL("clicked()"),self.onUploadStateReceiptScan) self.connect(self.btnAddStatRefPaper, SIGNAL("clicked()"),self.onUploadStatutoryRefPaper) self.connect(self.btnAddSurveyorRef, SIGNAL("clicked()"),self.onUploadSurveyorRef) self.connect(self.btnAddNotaryRef, SIGNAL("clicked()"),self.onUploadNotaryRef) def initConflict(self): ''' Initialize 'Conflict' GUI controls ''' loadComboSelections(self.cboConflictOccurrence, CheckConflictState) self.notifConflict = NotificationBar(self.vlConflictNotif,3000) def buildSummary(self): ''' Display summary information. ''' personMapping = self._mapPersonAttributes(self.selPerson) propertyMapping = self._mapPropertyAttributes(self.selProperty) STRMapping = self._mapSTRTypeSelection() #Load summary information in the tree view summaryTreeLoader = TreeSummaryLoader(self.twSTRSummary) summaryTreeLoader.addCollection(personMapping, QApplication.translate("newSTRWiz","Occupant Information"), ":/plugins/stdm/images/icons/user.png") summaryTreeLoader.addCollection(propertyMapping, QApplication.translate("newSTRWiz","Property Information"), ":/plugins/stdm/images/icons/property.png") summaryTreeLoader.addCollection(STRMapping, QApplication.translate("newSTRWiz","Social Tenure Relationship Information"), ":/plugins/stdm/images/icons/social_tenure.png") #Check if enjoyment right is specified heir = QApplication.translate("Lookup","Heir") selIndex= self.cboSTRType.currentIndex() #Get index of heir item heirIndex = self.cboSTRType.findText(heir) if selIndex == heirIndex: if self.enjoymentRight != None: enjoyRightMapping = self._mapEnjoyRightSelection(self.enjoymentRight) summaryTreeLoader.addCollection(enjoyRightMapping, QApplication.translate("newSTRWiz","Right of Enjoyment Information"), ":/plugins/stdm/images/icons/inherit.png") #Check the source documents based on the type of property if self.rbPrivateProperty.isChecked(): srcDocMapping = self.sourceDocManager.attributeMapping() summaryTreeLoader.addCollection(srcDocMapping, QApplication.translate("newSTRWiz","Source Documents"), ":/plugins/stdm/images/icons/attachment.png") #Tax information if self.gpPrivateTaxInfo.isChecked(): privatePropTaxMapping = self._mapPrivatePropertyTax() taxDocMapping = self.privateTaxDocManager.attributeMapping() privatePropTaxMapping.update(taxDocMapping) summaryTreeLoader.addCollection(privatePropTaxMapping, QApplication.translate("newSTRWiz","Tax Information"), ":/plugins/stdm/images/icons/receipt.png") elif self.rbStateland.isChecked(): #Tax information only statePropTaxMapping = self._mapStatePropertyTax() taxDocMapping = self.stateTaxDocManager.attributeMapping() statePropTaxMapping.update(taxDocMapping) summaryTreeLoader.addCollection(statePropTaxMapping, QApplication.translate("newSTRWiz","Tax Information"), ":/plugins/stdm/images/icons/receipt.png") #Map conflict if self.cboConflictOccurrence.currentIndex() != 0: conflictMapping = self._mapConflict(self.conflict) summaryTreeLoader.addCollection(conflictMapping, QApplication.translate("newSTRWiz","Conflict Information"), ":/plugins/stdm/images/icons/conflict.png") summaryTreeLoader.display() def validateCurrentPage(self): ''' Validate the current page before proceeding to the next one ''' isValid = True currPageIndex = self.currentId() #Validate person information if currPageIndex == 1: if self.selPerson == None: msg = QApplication.translate("newSTRWiz", "Please choose a person for whom you are defining the social tenure relationship for.") self.notifPerson.clear() self.notifPerson.insertNotification(msg, ERROR) isValid = False #Validate property information if currPageIndex == 2: if self.selProperty == None: msg = QApplication.translate("newSTRWiz", "Please specify the property to reference. Use the filter capability below.") self.notifProp.clear() self.notifProp.insertNotification(msg, ERROR) isValid = False #Validate STR if currPageIndex == 3: #Get current selected index currIndex = self.cboSTRType.currentIndex() if currIndex == 0: msg = QApplication.translate("newSTRWiz", "Please specify the social tenure relationship type.") self.notifSTR.clear() self.notifSTR.insertErrorNotification(msg) isValid = False #Validate right of enjoyment details if currPageIndex == 4: isValid = self.validateEnjoymentRight() #Validate source document if currPageIndex == 5: isValid = self.validateSourceDocuments() #Validate conflict details if currPageIndex == 6: isValid = self.validateConflict() if currPageIndex == 7: isValid = self.onCreateSTR() return isValid def onCreateSTR(self): ''' Slot raised when the user clicks on Finish button in order to create a new STR entry. ''' isValid = True #Create a progress dialog progDialog = QProgressDialog(self) progDialog.setWindowTitle(QApplication.translate("newSTRWiz", "Creating New STR")) progDialog.setRange(0,7) progDialog.show() try: progDialog.setValue(1) socialTenure = SocialTenureRelationship() socialTenure.PersonID = self.selPerson.id progDialog.setValue(2) socialTenure.PropertyID = self.selProperty.id progDialog.setValue(3) if self.rbPrivateProperty.isChecked(): progDialog.setValue(4) socialTenure.SourceDocuments = self.sourceDocManager.sourceDocuments() if self.gpPrivateTaxInfo.isChecked(): taxInfo = Taxation() taxInfo.Amount = Decimal(str(self.txtCFBPAmount.text())) taxInfo.ReferenceDate = self.dtLastYearCFBP.date().toPyDate() taxDocs = self.privateTaxDocManager.sourceDocuments(TAX_RECEIPT_PRIVATE) if len(taxDocs) > 0: taxInfo.Document = taxDocs[0] socialTenure.Taxation = taxInfo elif self.rbStateland.isChecked(): progDialog.setValue(4) taxInfo = Taxation() taxInfo.Amount = Decimal(str(self.txtStateReceiptAmount.text())) taxInfo.ReferenceDate = self.dtStateReceiptDate.date().toPyDate() taxInfo.LeaseDate = self.dtStateLeaseYear.date().toPyDate() taxInfo.TaxOffice = str(self.txtStateTaxOffice.text()) taxDocs = self.stateTaxDocManager.sourceDocuments(TAX_RECEIPT_STATE) if len(taxDocs) > 0: taxInfo.Document = taxDocs[0] socialTenure.Taxation = taxInfo progDialog.setValue(5) socialTenure.AgreementAvailable = self.chkSTRAgreement.isChecked() socialTenure.SocialTenureType,ok = self.cboSTRType.itemData(self.cboSTRType.currentIndex()).toInt() if self.enjoymentRight != None: socialTenure.EnjoymentRight = self.enjoymentRight if self.conflict != None: socialTenure.Conflict = self.conflict progDialog.setValue(6) socialTenure.save() progDialog.setValue(7) strPerson = "%s %s"%(self.selPerson.firstname,self.selPerson.lastname) strMsg = str(QApplication.translate("newSTRWiz", "The social tenure relationship for %s has been successfully created!")) QMessageBox.information(self, QApplication.translate("newSTRWiz", "STR Creation"),strMsg%(strPerson)) except sqlalchemy.exc.OperationalError as oe: errMsg = oe.message QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) progDialog.hide() isValid = False except Exception as e: errMsg = str(e) QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) progDialog.hide() isValid = False return isValid def _loadPersonInfo(self,persons): ''' Load person objects ''' self.persons = persons self._updatePersonCompleter(0) def _onPropertiesLoaded(self,propids): ''' Slot raised once the property worker has finished retrieving the property IDs. Creates a completer and populates it with the property IDs. ''' #Get the items in a tuple and put them in a list propertyIds = [pid[0] for pid in propids] #Configure completer propCompleter = QCompleter(propertyIds,self) propCompleter.setCaseSensitivity(Qt.CaseInsensitive) propCompleter.setCompletionMode(QCompleter.PopupCompletion) self.txtPropID.setCompleter(propCompleter) #Connect 'activated' slot for the completer to load property information self.connect(propCompleter, SIGNAL("activated(const QString&)"),self._updatePropertySummary) def _onPropertyBrowserError(self,err): ''' Slot raised when an error occurs when loading items in the property browser ''' self.notifProp.clear() self.notifProp.insertNotification(err, ERROR) def _onPropertyBrowserLoading(self,progress): ''' Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. ''' if progress <= 0 or progress >= 100: self.gpOpenLayers.setTitle(self.gpOLTitle) else: self.gpOpenLayers.setTitle("%s (Loading...%s%%)"%(str(self.gpOLTitle),str(progress))) def _onPropertyBrowserFinished(self,status): ''' Slot raised when the property browser finishes loading the content ''' if status: self.olLoaded = True self.overlayProperty() else: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "Error - The property map cannot be loaded.") self.notifProp.insertErrorNotification(msg) def _onEnableOLGroupbox(self,state): ''' Slot raised when a user chooses to select the group box for enabling/disabling to view the property in OpenLayers. ''' if state: if self.selProperty is None: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "You need to specify a property in order to be able to preview it.") self.notifProp.insertWarningNotification(msg) self.gpOpenLayers.setChecked(False) return #Load property overlay if not self.olLoaded: self.propBrowser.load() else: #Remove overlay self.propBrowser.removeOverlay() def _onZoomChanged(self): ''' Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. ''' zoom = self.zoomSlider.value() self.propBrowser.zoomTo(zoom) def _initPersonFilter(self): ''' Initializes person filter settings ''' self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz","First Name")), "firstname") self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz","Last Name")), "lastname") self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz","Nick Name")), "nickname") self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz","Identification Number")), "identification_number") def _updatePersonCompleter(self,index): ''' Updates the person completer based on the person attribute item that the user has selected ''' #Clear dependent controls self.txtFilterPattern.clear() self.tvPersonInfo.clear() self.currPersonAttr = str(self.cboPersonFilterCols.itemData(index).toString()) #Create standard model which will always contain the id of the person row then the attribute for use in the completer self.personStandardModel = QStandardItemModel(self) self.personStandardModel.setColumnCount(2) self.personStandardModel.clear() for p in self.persons: pVal = getattr(p,self.currPersonAttr) if pVal != "" or pVal != None: idItem = QStandardItem() idItem.setData(p.id,Qt.EditRole) attrItem = QStandardItem() attrItem.setData(pVal,Qt.EditRole) self.personStandardModel.appendRow([idItem,attrItem]) #Configure completer personCompleter = QCompleter(self) personCompleter.setModel(self.personStandardModel) personCompleter.setCompletionColumn(1) personCompleter.setCaseSensitivity(Qt.CaseInsensitive) personCompleter.setCompletionMode(QCompleter.PopupCompletion) self.txtFilterPattern.setCompleter(personCompleter) #Connect 'activated' slot for the completer to load person information self.connect(personCompleter, SIGNAL("activated(const QModelIndex&)"),self._updatePersonSummary) def _updatePersonSummary(self,index): ''' Slot for updating the person information into the tree widget based on the user-selected value ''' #Get the id from the model then the value of the ID model index row = index.row() idIndex = self.personStandardModel.index(row, 0) personId,ok = idIndex.data().toInt() #Get person info person = Person() p = person.queryObject().filter(Person.id == personId).first() if p: self.selPerson = p personInfoMapping = self._mapPersonAttributes(p) personTreeLoader = TreeSummaryLoader(self.tvPersonInfo) personTreeLoader.addCollection(personInfoMapping, QApplication.translate("newSTRWiz","Occupant Information"), ":/plugins/stdm/images/icons/user.png") personTreeLoader.display() def _mapPersonAttributes(self,person): ''' Maps the attributes of a person to a more friendly user representation ''' #Setup formatters genderFormatter = LookupFormatter(CheckGender) dobFormatter = DoBFormatter() maritalStatFormatter = LookupFormatter(CheckMaritalStatus) pMapping = OrderedDict() pMapping["First Name"] = person.firstname pMapping["Last Name"] = person.lastname pMapping["Nick Name"] = person.nickname pMapping["Position"] = person.firstname pMapping["Gender"] = str(genderFormatter.setDisplay(person.gender_id).toString()) pMapping["Age"] = str(dobFormatter.setDisplay(person.date_of_birth)) pMapping["Marital Status"] = str(maritalStatFormatter.setDisplay(person.marital_status_id).toString()) pMapping["National Identification Number"] = str(person.identification_number) pMapping["Telephone Number"] = person.telephone pMapping["Address"] = person.address return pMapping def _updatePropertySummary(self,propid): ''' Update the summary information for the selected property ''' propty = Property() prop = propty.queryObject().filter(Property.PropertyID == str(propid)).first() if prop: propMapping = self._mapPropertyAttributes(prop) #Load information in the tree view propertyTreeLoader = TreeSummaryLoader(self.tvPropInfo) propertyTreeLoader.addCollection(propMapping, QApplication.translate("newSTRWiz","Property Information"), ":/plugins/stdm/images/icons/property.png") propertyTreeLoader.display() self.selProperty = prop #Show property in OpenLayers if self.gpOpenLayers.isChecked(): if self.olLoaded: self.overlayProperty() def _mapPropertyAttributes(self,prop): #Configure formatters useTypeFormatter = LookupFormatter(CheckBuildingUseType) descFormatter = LookupFormatter(CheckBuildingDescription) roofTypeFormatter = LookupFormatter(CheckRoofType) wallNatureFormatter = LookupFormatter(CheckWallNature) boundTypeFormatter = LookupFormatter(CheckBoundaryType) accessionFormatter = LookupFormatter(CheckAccessionMode) #Check for nulls if prop.locality: locArea = prop.locality.area locStreetNum = prop.locality.street_number else: locArea = "" locStreetNum = "" propMapping = OrderedDict() propMapping[str(QApplication.translate("newSTRWiz","Identifier"))] = prop.PropertyID propMapping[str(QApplication.translate("newSTRWiz","Locality"))] = { unicode(QApplication.translate("newSTRWiz","Area")):locArea, unicode(QApplication.translate("newSTRWiz","Street Number")):locStreetNum } propMapping[str(QApplication.translate("newSTRWiz","Property Use Type"))] = unicode(useTypeFormatter.setDisplay(prop.UseTypeID).toString()) propMapping[str(QApplication.translate("newSTRWiz","Description"))] = unicode(descFormatter.setDisplay(prop.DescriptionID).toString()) propMapping[str(QApplication.translate("newSTRWiz","Number of Floors"))] = unicode(prop.NumFloors) propMapping[str(QApplication.translate("newSTRWiz","Type of Building Roof"))] = unicode(roofTypeFormatter.setDisplay(prop.RoofTypeID).toString()) propMapping[str(QApplication.translate("newSTRWiz","Nature of Walls"))] = unicode(wallNatureFormatter.setDisplay(prop.NatureWalls).toString()) propMapping[str(QApplication.translate("newSTRWiz","Type of Boundary"))] = unicode(boundTypeFormatter.setDisplay(prop.BoundaryType).toString()) propMapping[str(QApplication.translate("newSTRWiz","Number of Rooms"))] = unicode(prop.NumRooms) propMapping[str(QApplication.translate("newSTRWiz","Land Value"))] = unicode(prop.LandValue) propMapping[str(QApplication.translate("newSTRWiz","Building Value"))] = unicode(prop.BuildingValue) propMapping[str(QApplication.translate("newSTRWiz","Combined Value"))] = unicode(prop.CombinedValue) propMapping[str(QApplication.translate("newSTRWiz","Type of Land Accession"))] = unicode(accessionFormatter.setDisplay(prop.LandAccessionID).toString()) propMapping[str(QApplication.translate("newSTRWiz","Land Accession Year"))] = unicode(prop.LandAccessionYear) propMapping[str(QApplication.translate("newSTRWiz","Type of Building Accession"))] = unicode(accessionFormatter.setDisplay(prop.BuildingAccessionID).toString()) propMapping[str(QApplication.translate("newSTRWiz","Building Accession Year"))] = unicode(prop.BuildingAccessionYear) return propMapping def _mapSTRTypeSelection(self): strTypeFormatter = LookupFormatter(CheckSocialTenureRelationship) strTypeSelection,ok = self.cboSTRType.itemData(self.cboSTRType.currentIndex()).toInt() strMapping = OrderedDict() strMapping[str(QApplication.translate("newSTRWiz","STR Type"))] = str(strTypeFormatter.setDisplay(strTypeSelection).toString()) if self.chkSTRAgreement.isChecked(): agreementText = str(QApplication.translate("newSTRWiz","Yes")) else: agreementText = str(QApplication.translate("newSTRWiz","No")) strMapping[str(QApplication.translate("newSTRWiz","Written Agreement Available"))] = agreementText return strMapping def _mapEnjoyRightSelection(self,enjoyRight): deadAliveFormatter = LookupFormatter(CheckDeadAlive) inheritanceFormatter = LookupFormatter(CheckInheritanceType) enjoyRightMapping = OrderedDict() enjoyRightMapping[str(QApplication.translate("newSTRWiz","Inheritance From"))] = str(inheritanceFormatter.setDisplay(enjoyRight.InheritanceType).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","State"))] = str(deadAliveFormatter.setDisplay(enjoyRight.State).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","Receiving Date"))] = str(enjoyRight.ReceivingDate.year) return enjoyRightMapping def _mapPrivatePropertyTax(self): privateTaxMapping = OrderedDict() privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Payment Year"))] = str(self.dtLastYearCFBP.date().toPyDate().year) taxDec = Decimal(str(self.txtCFBPAmount.text())) taxFormatted = moneyfmt(taxDec,curr=CURRENCY_CODE) privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Amount"))] = taxFormatted return privateTaxMapping def _mapStatePropertyTax(self): stateTaxMapping = OrderedDict() stateTaxMapping[str(QApplication.translate("newSTRWiz","Latest Receipt Date"))] = str(self.dtStateReceiptDate.date().toPyDate()) taxDec = Decimal(str(self.txtStateReceiptAmount.text())) taxFormatted = moneyfmt(taxDec,curr=CURRENCY_CODE) stateTaxMapping[str(QApplication.translate("newSTRWiz","Amount"))] = taxFormatted stateTaxMapping[str(QApplication.translate("newSTRWiz","Lease Starting Year"))] = str(self.dtStateLeaseYear.date().toPyDate().year) stateTaxMapping[str(QApplication.translate("newSTRWiz","Tax Office"))] = str(self.txtStateTaxOffice.text()) return stateTaxMapping def _mapConflict(self,conflict): conflictFormatter = LookupFormatter(CheckConflictState) conflictMapping = OrderedDict() if conflict == None: return conflictMapping conflictMapping[str(QApplication.translate("newSTRWiz","Status"))] = str(conflictFormatter.setDisplay(conflict.StateID).toString()) if conflict.Description: conflictMapping[str(QApplication.translate("newSTRWiz","Description"))] = conflict.Description if conflict.Solution: conflictMapping[str(QApplication.translate("newSTRWiz","Solution"))] = conflict.Solution return conflictMapping def onLoadGMaps(self,state): ''' Slot raised when a user clicks to set Google Maps Satellite as the base layer ''' if state: self.propBrowser.setBaseLayer(GMAP_SATELLITE) def onLoadOSM(self,state): ''' Slot raised when a user clicks to set OSM as the base layer ''' if state: self.propBrowser.setBaseLayer(OSM) def onMapZoomLevelChanged(self,level): ''' Slot which is raised when the zoom level of the map changes. ''' self.zoomSlider.setValue(level) def _onResetMap(self): ''' Slot raised when the user clicks to reset the property location in the map. ''' self.propBrowser.zoomToPropertyExtents() def overlayProperty(self): ''' Overlay property boundaries on the basemap imagery ''' self.propBrowser.addOverlay(self.selProperty,"PropertyID") def validateEnjoymentRight(self): ''' Validate whether the user has specified all the required information ''' self.notifEnjoyment.clear() if self.cboDeadAlive.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify whether the person is 'Dead' or 'Alive'.") self.notifEnjoyment.insertErrorNotification(msg) return False if self.cboInheritanceType.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify the Inheritance Type.") self.notifEnjoyment.insertErrorNotification(msg) return False #Set the right of enjoyment details if both inheritance type and state have been defined if self.cboInheritanceType.currentIndex() != 0 and self.cboDeadAlive.currentIndex() != 0: eRight = EnjoymentRight() #Set the properties setModelAttrFromCombo(eRight,"InheritanceType",self.cboInheritanceType) setModelAttrFromCombo(eRight,"State",self.cboDeadAlive) eRight.ReceivingDate = self.dtReceivingDate.date().toPyDate() self.enjoymentRight = eRight return True def validateSourceDocuments(self): ''' Basically validates the entry of tax information. ''' isValid = True if self.rbPrivateProperty.isChecked(): if self.gpPrivateTaxInfo.isChecked(): self.notifSourceDoc.clear() if str(self.txtCFBPAmount.text()) == "": self.txtCFBPAmount.setFocus() msg1 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg1) isValid = False elif self.rbStateland.isChecked(): self.notifSourceDoc.clear() if str(self.txtStateReceiptAmount.text()) == "": self.txtStateReceiptAmount.setFocus() msg2 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg2) isValid = False if str(self.txtStateTaxOffice.text()) == "": self.txtStateTaxOffice.setFocus() msg3 = QApplication.translate("newSTRWiz", "Please specify the tax office.") self.notifSourceDoc.insertErrorNotification(msg3) isValid = False return isValid def validateConflict(self): ''' Check if the user has selected that there is a conflict and validate whether the description and solution have been specified. ''' isValid = True nonConflict = QApplication.translate("Lookup","No Conflict") nonConflictIndex = self.cboConflictOccurrence.findText(nonConflict) conflictOccurrence = QApplication.translate("Lookup","Conflict Present") occIndex = self.cboConflictOccurrence.findText(conflictOccurrence) if self.cboConflictOccurrence.currentIndex() == occIndex: self.notifConflict.clear() if str(self.txtConflictDescription.toPlainText()) == "": msg1 = QApplication.translate("newSTRWiz", "Please provide a brief description of the conflict.") self.notifConflict.insertErrorNotification(msg1) isValid = False if str(self.txtConflictSolution.toPlainText()) == "": msg2 = QApplication.translate("newSTRWiz", "Please provide a proposed solution for the specified conflict.") self.notifConflict.insertErrorNotification(msg2) isValid = False if str(self.txtConflictSolution.toPlainText()) != "" and str(self.txtConflictDescription.toPlainText()) != "": self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(occIndex).toInt() self.conflict.StateID = stateId self.conflict.Description = str(self.txtConflictDescription.toPlainText()) self.conflict.Solution = str(self.txtConflictSolution.toPlainText()) #Set conflict object properties if self.cboConflictOccurrence.currentIndex() == nonConflictIndex: self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(nonConflictIndex).toInt() self.conflict.StateID = stateId return isValid def onSelectPrivateProperty(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(0) def onSelectStateland(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(1) def onUploadTitleDeed(self): ''' Slot raised when the user clicks to upload a title deed ''' titleStr = QApplication.translate("newSTRWiz", "Specify Title Deed File Location") titles = self.selectSourceDocumentDialog(titleStr) for title in titles: self.sourceDocManager.insertDocumentFromFile(title,TITLE_DEED) def onUploadStatutoryRefPaper(self): ''' Slot raised when the user clicks to upload a statutory reference paper ''' statStr = QApplication.translate("newSTRWiz", "Specify Statutory Reference Paper File Location") stats = self.selectSourceDocumentDialog(statStr) for stat in stats: self.sourceDocManager.insertDocumentFromFile(stat,STATUTORY_REF_PAPER) def onUploadSurveyorRef(self): ''' Slot raised when the user clicks to upload a surveyor reference ''' surveyorStr = QApplication.translate("newSTRWiz", "Specify Surveyor Reference File Location") surveyorRefs = self.selectSourceDocumentDialog(surveyorStr) for surveyorRef in surveyorRefs: self.sourceDocManager.insertDocumentFromFile(surveyorRef,SURVEYOR_REF) def onUploadNotaryRef(self): ''' Slot raised when the user clicks to upload a notary reference ''' notaryStr = QApplication.translate("newSTRWiz", "Specify Notary Reference File Location") notaryRefs = self.selectSourceDocumentDialog(notaryStr) for notaryRef in notaryRefs: self.sourceDocManager.insertDocumentFromFile(notaryRef,NOTARY_REF) def onUploadPrivateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for private property ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.privateTaxDocManager, scan, TAX_RECEIPT_PRIVATE) def onUploadStateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for stateland ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.stateTaxDocManager, scan, TAX_RECEIPT_STATE) def validateReceiptScanInsertion(self,documentmanager,scan,containerid): ''' Checks and ensures that only one document exists in the specified container. ''' container = documentmanager.container(containerid) if container.count() > 0: msg = QApplication.translate("newSTRWiz", "Only one receipt scan can be uploaded.\nWould you like to replace " \ "the existing one?") result = QMessageBox.warning(self,QApplication.translate("newSTRWiz","Replace Receipt Scan"),msg, QMessageBox.Yes| QMessageBox.No) if result == QMessageBox.Yes: docWidget = container.itemAt(0).widget() docWidget.removeDocument() documentmanager.insertDocumentFromFile(scan,containerid) else: return else: documentmanager.insertDocumentFromFile(scan,containerid) def selectSourceDocumentDialog(self,title): ''' Displays a file dialog for a user to specify a source document ''' files = QFileDialog.getOpenFileNames(self,title,"/home","Source Documents (*.pdf)") return files def selectReceiptScanDialog(self,title): ''' Displays a file dialog for a user to specify a file location of a receipt scan ''' file = QFileDialog.getOpenFileName(self,title,"/home","Tax Receipt Scan (*.pdf)") return file def uploadDocument(self,path,containerid): ''' Upload source document ''' self.sourceDocManager.insertDocumentFromFile(path, containerid)
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
class LicenseAgreement(QDialog, Ui_LicenseAgreement): def __init__(self, parent=None): """ This class checks if the user has accepted the license terms and conditions or not . It shows the terms and conditions if not. :param parent: The container of the dialog :type parent: QMainWindow or None :return: None :rtype: NoneType """ QDialog.__init__(self, parent) self.setupUi(self) self.reg_config = RegistryConfig() self.notice_bar = NotificationBar(self.notifBar) self.accepted = False self.btnAccept.clicked.connect(self.accept_action) self.btnDecline.clicked.connect(self.decline_action) self.label.setStyleSheet(''' QLabel { font: bold; } ''') def check_show_license(self): """ Checks if you need to show the license page. Checks if the flag in the registry has been set. Returns True to show license. If registry key is not yet set, show the license page. :rtype: boolean """ show_lic = 1 license_key = self.reg_config.read([SHOW_LICENSE]) if len(license_key) > 0: show_lic = license_key[SHOW_LICENSE] if show_lic == 1 or show_lic == unicode(1): return True elif show_lic == 0 or show_lic == unicode(0): self.accepted = True return False def show_license(self): """ Show STDM license window if the user have never accepted the license terms and conditions. :return: None :rtype: NoneType """ # validate if to show license show_lic = self.check_show_license() # THe user didn't accept license if show_lic: license = LicenseDocument() self.termsCondArea.setText(license.read_license_info()) self.exec_() def accept_action(self): """ A slot raised when the user clicks on the Accept button. :return: None :rtype: NoneType """ if not self.checkBoxAgree.isChecked(): msg = QApplication.translate( 'LicenseAgreement', 'To use STDM, please accept the terms ' 'and conditions by selecting' ' the checkbox "I have read and agree ..."') self.notice_bar.clear() self.notice_bar.insertNotification(msg, ERROR) return else: self.reg_config.write({SHOW_LICENSE: 0}) self.accepted = True self.close() def decline_action(self): """ A slot raised when the user clicks on the decline button. :return: None :rtype: NoneType """ self.accepted = False self.close()
class ViewSTRWidget(QWidget, Ui_frmViewSTR): ''' Search and browse the social tenure relationship of all participating entities. ''' def __init__(self, plugin): QWidget.__init__(self, plugin.iface.mainWindow(), Qt.Window) self.setupUi(self) #Center me self.move(QDesktopWidget().availableGeometry().center() - self.frameGeometry().center()) #set whether currently logged in user has permissions to edit existing STR records self._canEdit = self._getEditPermissions() ''' 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._currRootNodeHash = "" self._sourceDocManager = SourceDocumentManager() self.connect(self._sourceDocManager, SIGNAL("documentRemoved(int)"), self.onSourceDocumentRemoved) self._sourceDocManager.setEditPermissions(self._canEdit) self.initGui() def initGui(self): ''' Initialize widget ''' self.loadEntityConfig() #Hook up signals self.connect(self.tbSTREntity, SIGNAL("currentChanged(int)"), self.entityTabIndexChanged) self.connect(self.btnSearch, SIGNAL("clicked()"), self.searchEntityRelations) self.connect(self.btnClearSearch, SIGNAL("clicked()"), self.clearSearch) self.connect(self.tvSTRResults, SIGNAL("expanded(const QModelIndex&)"), self.onTreeViewItemExpanded) #Configure notification bars self.notifSearchConfig = NotificationBar(self.vlSearchEntity) #Set the results treeview to accept requests for context menus self.tvSTRResults.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tvSTRResults, SIGNAL("customContextMenuRequested(const QPoint&)"), self.onResultsContextMenuRequested) #Load async for the current widget self.entityTabIndexChanged(0) def loadEntityConfig(self): ''' Specify the entity configurations. ''' #Person configuration personCfg = EntityConfiguration() personCfg.Title = str(QApplication.translate("ViewSTR", "Person")) personCfg.filterColumns["firstname"] = str( QApplication.translate("ViewSTR", "First Name")) personCfg.filterColumns["lastname"] = str( QApplication.translate("ViewSTR", "Last Name")) personCfg.filterColumns["identification_number"] = str( QApplication.translate("ViewSTR", "Identification Number")) personCfg.STRModel = Person personWidget = self.setEntityConfigWidget(personCfg) personWidget.setNodeFormatter( PersonNodeFormatter(self.tvSTRResults, self)) #Property configuration propertyCfg = EntityConfiguration() propertyCfg.Title = str(QApplication.translate("ViewSTR", "Property")) propertyCfg.filterColumns["PropertyID"] = str( QApplication.translate("ViewSTR", "Property Identifier")) propertyCfg.STRModel = Property self.setEntityConfigWidget(propertyCfg) def setEntityConfigWidget(self, config): ''' Set an entity configuration option and add it to the 'Search Entity' tab. ''' entityWidg = STRViewEntityWidget(config) self.connect(entityWidg, SIGNAL("asyncStarted()"), self._progressStart) self.connect(entityWidg, SIGNAL("asyncFinished()"), 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._resetTreeView() entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget, EntitySearchItem): valid, msg = entityWidget.validate() if not valid: self.notifSearchConfig.clear() self.notifSearchConfig.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.notifSearchConfig.clear() self.notifSearchConfig.insertErrorNotification(noResultsMsg) return if formattedNode is not None: self._loadRootNodeinTree(formattedNode) def clearSearch(self): ''' Clear search input parameters (for current widget) and results. ''' entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget, EntitySearchItem): entityWidget.reset() #Clear tree view self._resetTreeView() #Clear document listings self._deleteSourceDocTabs() def onSelectResults(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() #Assert if node representing another entity has been clicked self._onNodeReferenceChanged(node.rootHash()) if isinstance(node, STRNode): srcDocs = node.sourceDocuments() strId = node.id() if strId != self._strID: self._strID = strId self._loadSourceDocuments(srcDocs) break def onSourceDocumentRemoved(self, containerid): ''' 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() == containerid: docCount = docwidget.container().count() if docCount == 0: self.tbSupportingDocs.removeTab(i) del docwidget break def removeSourceDocumentWidget(self, containerid): ''' 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() == containerid: self.tbSupportingDocs.removeTab(i) self._sourceDocManager.removeContainer(containerid) 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._onNodeReferenceChanged(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 _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._sourceDocManager.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.onSelectResults) def _loadRootNodeinTree(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._resizeTreeColumns() #Capture selection changes signals when results are returned in the tree view resultsSelModel = self.tvSTRResults.selectionModel() self.connect( resultsSelModel, SIGNAL( "selectionChanged(const QItemSelection&,const QItemSelection&)" ), self.onSelectResults) def _resizeTreeColumns(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 _loadSourceDocuments(self, sourcedocs): ''' Load source documents into document listing widget. ''' #Check the #Configure progress dialog progressMsg = QApplication.translate( "ViewSTR", "Loading supporting documents...") progressDialog = QProgressDialog(progressMsg, QString(), 0, len(sourcedocs), self) progressDialog.setWindowModality(Qt.WindowModal) for i, doc in enumerate(sourcedocs): progressDialog.setValue(i) typeId = doc.DocumentType container = self._sourceDocManager.container(typeId) #Check if a container has been defined and create if none is found if container is None: srcDocWidget = SourceDocumentContainerWidget(typeId) container = srcDocWidget.container() self._sourceDocManager.registerContainer(container, typeId) #Add widget to tab container for source documents self.tbSupportingDocs.addTab(srcDocWidget, docTypeMapping[typeId]) self._sourceDocManager.InsertDocFromModel(doc, typeId) progressDialog.setValue(len(sourcedocs)) def _onNodeReferenceChanged(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._currRootNodeHash: self._deleteSourceDocTabs() self._currRootNodeHash = 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 _getEditPermissions(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
class ViewSTRWidget(QWidget, Ui_frmViewSTR): ''' Search and browse the social tenure relationship of all participating entities. ''' def __init__(self,plugin): QWidget.__init__(self,plugin.iface.mainWindow(),Qt.Window) self.setupUi(self) #Center me self.move(QDesktopWidget().availableGeometry().center() - self.frameGeometry().center()) #set whether currently logged in user has permissions to edit existing STR records self._canEdit = self._getEditPermissions() ''' 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._currRootNodeHash = "" self._sourceDocManager = SourceDocumentManager() self.connect(self._sourceDocManager,SIGNAL("documentRemoved(int)"),self.onSourceDocumentRemoved) self._sourceDocManager.setEditPermissions(self._canEdit) self.initGui() def initGui(self): ''' Initialize widget ''' self.loadEntityConfig() #Hook up signals self.connect(self.tbSTREntity, SIGNAL("currentChanged(int)"),self.entityTabIndexChanged) self.connect(self.btnSearch, SIGNAL("clicked()"),self.searchEntityRelations) self.connect(self.btnClearSearch, SIGNAL("clicked()"),self.clearSearch) self.connect(self.tvSTRResults,SIGNAL("expanded(const QModelIndex&)"),self.onTreeViewItemExpanded) #Configure notification bars self.notifSearchConfig = NotificationBar(self.vlSearchEntity) #Set the results treeview to accept requests for context menus self.tvSTRResults.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.tvSTRResults,SIGNAL("customContextMenuRequested(const QPoint&)"), self.onResultsContextMenuRequested) #Load async for the current widget self.entityTabIndexChanged(0) def loadEntityConfig(self): ''' Specify the entity configurations. ''' #Person configuration personCfg = EntityConfiguration() personCfg.Title = str(QApplication.translate("ViewSTR", "Person")) personCfg.filterColumns["firstname"] = str(QApplication.translate("ViewSTR", "First Name")) personCfg.filterColumns["lastname"] = str(QApplication.translate("ViewSTR", "Last Name")) personCfg.filterColumns["identification_number"] = str(QApplication.translate("ViewSTR", "Identification Number")) personCfg.STRModel = Person personWidget = self.setEntityConfigWidget(personCfg) personWidget.setNodeFormatter(PersonNodeFormatter(self.tvSTRResults,self)) #Property configuration propertyCfg = EntityConfiguration() propertyCfg.Title = str(QApplication.translate("ViewSTR", "Property")) propertyCfg.filterColumns["PropertyID"] = str(QApplication.translate("ViewSTR", "Property Identifier")) propertyCfg.STRModel = Property self.setEntityConfigWidget(propertyCfg) def setEntityConfigWidget(self,config): ''' Set an entity configuration option and add it to the 'Search Entity' tab. ''' entityWidg = STRViewEntityWidget(config) self.connect(entityWidg, SIGNAL("asyncStarted()"),self._progressStart) self.connect(entityWidg, SIGNAL("asyncFinished()"),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._resetTreeView() entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget,EntitySearchItem): valid,msg = entityWidget.validate() if not valid: self.notifSearchConfig.clear() self.notifSearchConfig.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.notifSearchConfig.clear() self.notifSearchConfig.insertErrorNotification(noResultsMsg) return if formattedNode is not None: self._loadRootNodeinTree(formattedNode) def clearSearch(self): ''' Clear search input parameters (for current widget) and results. ''' entityWidget = self.tbSTREntity.currentWidget() if isinstance(entityWidget,EntitySearchItem): entityWidget.reset() #Clear tree view self._resetTreeView() #Clear document listings self._deleteSourceDocTabs() def onSelectResults(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() #Assert if node representing another entity has been clicked self._onNodeReferenceChanged(node.rootHash()) if isinstance(node,STRNode): srcDocs = node.sourceDocuments() strId = node.id() if strId != self._strID: self._strID = strId self._loadSourceDocuments(srcDocs) break def onSourceDocumentRemoved(self,containerid): ''' 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() == containerid: docCount = docwidget.container().count() if docCount == 0: self.tbSupportingDocs.removeTab(i) del docwidget break def removeSourceDocumentWidget(self,containerid): ''' 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() == containerid: self.tbSupportingDocs.removeTab(i) self._sourceDocManager.removeContainer(containerid) 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._onNodeReferenceChanged(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 _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._sourceDocManager.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.onSelectResults) def _loadRootNodeinTree(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._resizeTreeColumns() #Capture selection changes signals when results are returned in the tree view resultsSelModel = self.tvSTRResults.selectionModel() self.connect(resultsSelModel, SIGNAL("selectionChanged(const QItemSelection&,const QItemSelection&)"), self.onSelectResults) def _resizeTreeColumns(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 _loadSourceDocuments(self,sourcedocs): ''' Load source documents into document listing widget. ''' #Check the #Configure progress dialog progressMsg = QApplication.translate("ViewSTR", "Loading supporting documents...") progressDialog = QProgressDialog(progressMsg,QString(),0,len(sourcedocs),self) progressDialog.setWindowModality(Qt.WindowModal) for i,doc in enumerate(sourcedocs): progressDialog.setValue(i) typeId = doc.DocumentType container = self._sourceDocManager.container(typeId) #Check if a container has been defined and create if none is found if container is None: srcDocWidget = SourceDocumentContainerWidget(typeId) container = srcDocWidget.container() self._sourceDocManager.registerContainer(container, typeId) #Add widget to tab container for source documents self.tbSupportingDocs.addTab(srcDocWidget, docTypeMapping[typeId]) self._sourceDocManager.InsertDocFromModel(doc, typeId) progressDialog.setValue(len(sourcedocs)) def _onNodeReferenceChanged(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._currRootNodeHash: self._deleteSourceDocTabs() self._currRootNodeHash = 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 _getEditPermissions(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
class newSTRWiz(QWizard, Ui_frmNewSTR): ''' This class handles the listing of locality information ''' def __init__(self,plugin): QWizard.__init__(self,plugin.iface.mainWindow()) self.setupUi(self) #STR Variables self.selPerson = None self.selProperty = None self.enjoymentRight = None self.conflict = None #Initialize GUI wizard pages self.mapping=DeclareMapping.instance() self.initPerson() self.initProperty() self.initSTRType() self.init_document_type() self.initSourceDocument() #self.initConflict() #Connect signal when the finish button is clicked btnFinish = self.button(QWizard.FinishButton) def initPerson(self): ''' Initialize person config ''' self.notifPerson = NotificationBar(self.vlPersonNotif) self._initPersonFilter() #Initialize person worker thread for fetching person objects self.personWorker = PersonWorker(self) self.connect(self.personWorker, SIGNAL("retrieved(PyQt_PyObject)"),self._loadPersonInfo) #Init summary tree loaders self.personTreeLoader = TreeSummaryLoader(self.tvPersonInfo,QApplication.translate("newSTRWiz","Party Information")) #Connect signals QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self._updatePersonCompleter) #QObject.connect(self.cboPersonFilterCols, SIGNAL("currentIndexChanged(int)"),self.dataReceieved) #Start background thread self.personWorker.start() def initProperty(self): ''' Initialize property config ''' self.notifProp = NotificationBar(self.vlPropNotif) self.gpOLTitle = self.gpOpenLayers.title() #Flag for checking whether OpenLayers basemaps have been loaded self.olLoaded = False #Initialize lookup for properties propertyWorker = PropertyWorker(self) self.connect(propertyWorker, SIGNAL("retrieved(PyQt_PyObject)"), self._onPropertiesLoaded) #Connect signals QObject.connect(self.gpOpenLayers, SIGNAL("toggled(bool)"), self._onEnableOLGroupbox) QObject.connect(self.zoomSlider, SIGNAL("sliderReleased()"), self._onZoomChanged) QObject.connect(self.btnResetMap , SIGNAL("clicked()"), self._onResetMap) #Start background thread propertyWorker.start() self.propBrowser = WebSpatialLoader(self.propWebView,self) self.connect(self.propBrowser,SIGNAL("loadError(QString)"),self._onPropertyBrowserError) self.connect(self.propBrowser,SIGNAL("loadProgress(int)"),self._onPropertyBrowserLoading) self.connect(self.propBrowser,SIGNAL("loadFinished(bool)"),self._onPropertyBrowserFinished) self.connect(self.propBrowser,SIGNAL("zoomChanged(int)"),self.onMapZoomLevelChanged) #Connect signals QObject.connect(self.rbGMaps, SIGNAL("toggled(bool)"),self.onLoadGMaps) QObject.connect(self.rbOSM, SIGNAL("toggled(bool)"),self.onLoadOSM) def initializePage(self,id): ''' Initialize summary page based on user selections. ''' if id == 5: self.buildSummary() def initSTRType(self): ''' Initialize 'Social Tenure Relationship' GUI controls ''' # pty=Table('check_social_tenure_type',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) # session=STDMDb.instance().session person = self.mapping.tableMapping('check_social_tenure_type') Person = person() strTypeFormatter =Person.queryObject().all() strType=[ids.value for ids in strTypeFormatter] strType.insert(0, " ") self.cboSTRType.insertItems(0,strType) self.cboSTRType.setCurrentIndex(-1) self.notifSTR = NotificationBar(self.vlSTRTypeNotif) #Register STR selection field self.frmWizSTRType.registerField("STR_Type",self.cboSTRType) def init_document_type(self): ''' Initialize 'Right of Enjoyment' GUI controls ''' doc_type_model = self.mapping.tableMapping('check_document_type') Docs = doc_type_model() doc_type_list = Docs.queryObject().all() doc_types = [doc.value for doc in doc_type_list] doc_types.insert(0," ") self.cboDocType.insertItems(0,doc_types) self.cboDocType.setCurrentIndex(-1) self.vlSourceDocNotif = NotificationBar(self.vlSourceDocNotif) def initSourceDocument(self): ''' Initialize source document page ''' #Set currency regular expression and currency prefix rx = QRegExp("^\\d{1,12}(([.]\\d{2})*),(\\d{2})$") rxValidator = QRegExpValidator(rx,self) ''' ''' self.notifSourceDoc = NotificationBar(self.vlSourceDocNotif) #Set source document manager self.sourceDocManager = SourceDocumentManager() #self.privateTaxDocManager = SourceDocumentManager() #self.stateTaxDocManager = SourceDocumentManager() self.sourceDocManager.registerContainer(self.vlDocTitleDeed, DEFAULT_DOCUMENT) ''' #Connect signals ''' self.connect(self.btnAddTitleDeed, SIGNAL("clicked()"),self.onUploadTitleDeed) def initConflict(self): ''' Initialize 'Conflict' GUI controls ''' #loadComboSelections(self.cboConflictOccurrence, CheckConflictState) self.notifConflict = NotificationBar(self.vlConflictNotif,3000) def buildSummary(self): ''' Display summary information. ''' personMapping = self._mapPersonAttributes(self.selPerson) propertyMapping = self._mapPropertyAttributes(self.selProperty) STRMapping = self._mapSTRTypeSelection() #Load summary information in the tree view summaryTreeLoader = TreeSummaryLoader(self.twSTRSummary) summaryTreeLoader.addCollection(personMapping, QApplication.translate("newSTRWiz","Party Information"), ":/plugins/stdm/images/icons/user.png") summaryTreeLoader.addCollection(propertyMapping, QApplication.translate("newSTRWiz","Spatial Unit Information"), ":/plugins/stdm/images/icons/property.png") summaryTreeLoader.addCollection(STRMapping, QApplication.translate("newSTRWiz","Social Tenure Relationship Information"), ":/plugins/stdm/images/icons/social_tenure.png") #Check the source documents based on the type of property srcDocMapping = self.sourceDocManager.attributeMapping() summaryTreeLoader.addCollection(srcDocMapping, QApplication.translate("newSTRWiz","Source Documents"), ":/plugins/stdm/images/icons/attachment.png") summaryTreeLoader.display() def validateCurrentPage(self): ''' Validate the current page before proceeding to the next one ''' isValid = True currPageIndex = self.currentId() #Validate person information if currPageIndex == 1: if self.selPerson == None: msg = QApplication.translate("newSTRWiz", "Please choose a person for whom you are defining the social tenure relationship for.") self.notifPerson.clear() self.notifPerson.insertNotification(msg, ERROR) isValid = False #Validate property information if currPageIndex == 2: if self.selProperty == None: msg = QApplication.translate("newSTRWiz", "Please specify the property to reference. Use the filter capability below.") self.notifProp.clear() self.notifProp.insertNotification(msg, ERROR) isValid = False #Validate STR if currPageIndex == 3: #Get current selected index currIndex = self.cboSTRType.currentIndex() if currIndex ==-1: msg = QApplication.translate("newSTRWiz", "Please specify the social tenure relationship type.") self.notifSTR.clear() self.notifSTR.insertErrorNotification(msg) isValid = False #Validate source document if currPageIndex == 4: currIndex = self.cboDocType.currentIndex() if currIndex ==-1: msg = QApplication.translate("newSTRWiz", "Please select document type from the list") self.notifSourceDoc.clear() self.notifSourceDoc.insertErrorNotification(msg) if currPageIndex == 5: isValid = self.onCreateSTR() return isValid def onCreateSTR(self): ''' Slot raised when the user clicks on Finish button in order to create a new STR entry. ''' isValid = True #Create a progress dialog progDialog = QProgressDialog(self) progDialog.setWindowTitle(QApplication.translate("newSTRWiz", "Creating New STR")) progDialog.setRange(0,7) progDialog.show() socialTenureRel=self.mapping.tableMapping('social_tenure_relationship') str_relation_table =self.mapping.tableMapping('str_relations') STR_relation = str_relation_table() try: progDialog.setValue(1) socialTenure = socialTenureRel() socialTenure.party = self.selPerson.id progDialog.setValue(2) socialTenure.spatial_unit = self.selProperty.id progDialog.setValue(3) socialTenure.social_tenure_type=str(self.cboSTRType.currentText()) progDialog.setValue(6) """ Save new STR relations and supporting documentation """ socialTenure.save() model_objs = self.sourceDocManager.model_objects() if model_objs is not None: if len(model_objs)>0: for model_obj in model_objs: model_obj.save() STR_relation.social_tenure_id = socialTenure.id STR_relation.source_doc_id = model_obj.id STR_relation.save() progDialog.setValue(7) #source_doc_model = self.sourceDocManager.sourceDocuments(dtype ="TITLE DEED") #strPerson = "%s %s"%(str(self.selPerson.family_name),str(self.selPerson.other_names)) strMsg = str(QApplication.translate("newSTRWiz", "The social tenure relationship for has been successfully created!")) QMessageBox.information(self, QApplication.translate("newSTRWiz", "STR Creation"),strMsg) except sqlalchemy.exc.OperationalError as oe: errMsg = oe.message QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) progDialog.hide() isValid = False except sqlalchemy.exc.IntegrityError as ie: errMsg = ie.message QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Dublicate Relationship Error"),errMsg) progDialog.hide() isValid = False except Exception as e: errMsg = str(e) QMessageBox.critical(self, QApplication.translate("newSTRWiz", "Unexpected Error"),errMsg) isValid = False finally: STDMDb.instance().session.rollback() progDialog.hide() return isValid def _loadPersonInfo(self,persons): ''' Load person objects ''' self.persons = persons self._updatePersonCompleter(0) def _onPropertiesLoaded(self,propids): ''' Slot raised once the property worker has finished retrieving the property IDs. Creates a completer and populates it with the property IDs. ''' #Get the items in a tuple and put them in a list propertyIds = [str(pid[0]) for pid in propids] #Configure completer propCompleter = QCompleter(propertyIds,self) propCompleter.setCaseSensitivity(Qt.CaseInsensitive) propCompleter.setCompletionMode(QCompleter.PopupCompletion) self.txtPropID.setCompleter(propCompleter) #Connect 'activated' slot for the completer to load property information self.connect(propCompleter, SIGNAL("activated(const QString&)"),self._updatePropertySummary) def _onPropertyBrowserError(self,err): ''' Slot raised when an error occurs when loading items in the property browser ''' self.notifProp.clear() self.notifProp.insertNotification(err, ERROR) def _onPropertyBrowserLoading(self,progress): ''' Slot raised when the property browser is loading. Displays the progress of the page loading as a percentage. ''' if progress <= 0 or progress >= 100: self.gpOpenLayers.setTitle(self.gpOLTitle) else: self.gpOpenLayers.setTitle("%s (Loading...%s%%)"%(str(self.gpOLTitle),str(progress))) def _onPropertyBrowserFinished(self,status): ''' Slot raised when the property browser finishes loading the content ''' if status: self.olLoaded = True self.overlayProperty() else: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "Error - The property map cannot be loaded.") self.notifProp.insertErrorNotification(msg) def _onEnableOLGroupbox(self,state): ''' Slot raised when a user chooses to select the group box for enabling/disabling to view the property in OpenLayers. ''' if state: if self.selProperty is None: self.notifProp.clear() msg = QApplication.translate("newSTRWiz", "You need to specify a property in order to be able to preview it.") self.notifProp.insertWarningNotification(msg) self.gpOpenLayers.setChecked(False) return #Load property overlay if not self.olLoaded: self.propBrowser.load() else: #Remove overlay self.propBrowser.removeOverlay() def _onZoomChanged(self): ''' Slot raised when the zoom value in the slider changes. This is only raised once the user releases the slider with the mouse. ''' zoom = self.zoomSlider.value() self.propBrowser.zoom_to_level(zoom) def _initPersonFilter(self): ''' Initializes person filter settings ''' cols=table_searchable_cols('party') if len(cols)>0: for col in cols: self.cboPersonFilterCols.addItem(str(QApplication.translate("newSTRWiz",col.replace('_',' ').title())), col) def _updatePersonCompleter(self,index): ''' Updates the person completer based on the person attribute item that the user has selected ''' #Clear dependent controls #self.txtFilterPattern.clear() self.cboFilterPattern.clear() self.tvPersonInfo.clear() try: field_name = self.cboPersonFilterCols.currentText().replace(" ","_").lower() data_list =[getattr(array,field_name) for array in self.persons if getattr(array,field_name)!=None] model =QCompleter(data_list) model.setCompletionMode(QCompleter.PopupCompletion) model.setCaseSensitivity(Qt.CaseInsensitive) self.cboFilterPattern.setCompleter(model) self.cboFilterPattern.showPopup() except Exception as ex: msg =ex.message QMessageBox.critical(self,QApplication.translate("SocialTenureRelationship", u"Error Loading values"), QApplication.translate("SocialTenureRelationship", u"The was an error in sorting the data with the given column, try another %s"%msg)) return self.currPersonAttr = str(self.cboPersonFilterCols.itemData(index)) #Create standard model which will always contain the id of the person row then the attribute for use in the completer self.cboFilterPattern.addItem("") for p in self.persons: pVal = getattr(p,self.currPersonAttr) if pVal != "" or pVal != None: self.cboFilterPattern.addItem(pVal,p.id) self.cboFilterPattern.activated.connect(self._updatePersonSummary) #self.connect(self.cboFilterPattern, SIGNAL("currentIndexChanged(int)"),self._updatePersonSummary) def _updatePersonSummary(self,index): ''' Slot for updating the person information into the tree widget based on the user-selected value ''' Person=self.mapping.tableMapping('party') person=Person() #Get the id from the model then the value of the ID model index index =self.cboFilterPattern.currentIndex() personId = self.cboFilterPattern.itemData(index) #QMessageBox.information(None,'index',str(data)) # personId = pData if personId is not None: #Get person info p = person.queryObject().filter(Person.id == str(personId)).first() if p: self.selPerson = p personInfoMapping = self._mapPersonAttributes(p) personTreeLoader = TreeSummaryLoader(self.tvPersonInfo) personTreeLoader.addCollection(personInfoMapping, QApplication.translate("newSTRWiz","Party Information"), ":/plugins/stdm/images/icons/user.png") personTreeLoader.display() def _mapPersonAttributes(self,person): ''' Maps the attributes of a person to a more friendly user representation ''' #Setup formatters pmapper=self.mapping.tableMapping('party') colMapping = pmapper.displayMapping() colMapping.pop('id') pMapping=OrderedDict() try: for attrib,label in colMapping.iteritems(): pMapping[label] = getattr(person,attrib) except: pass # return pMapping def _updatePropertySummary(self,propid): ''' Update the summary information for the selected property ''' property = self.mapping.tableMapping('spatial_unit') Property =property() #propty=Table('spatial_unit',Base.metadata,autoload=True,autoload_with=STDMDb.instance().engine) #session=STDMDb.instance().session prop =Property.queryObject().filter(property.code == unicode(propid)).first() if prop: propMapping = self._mapPropertyAttributes(prop) #Load information in the tree view propertyTreeLoader = TreeSummaryLoader(self.tvPropInfo) propertyTreeLoader.addCollection(propMapping, QApplication.translate("newSTRWiz","Spatial Unit Information"), ":/plugins/stdm/images/icons/property.png") propertyTreeLoader.display() self.selProperty = prop #Show property in OpenLayers if self.gpOpenLayers.isChecked(): if self.olLoaded: self.overlayProperty() def _mapPropertyAttributes(self,prop): #Configure formatters spMapper = self.mapping.tableMapping('spatial_unit') colMapping = spMapper.displayMapping() colMapping.pop('id') propMapping=OrderedDict() for attrib,label in colMapping.iteritems(): propMapping[label] = getattr(prop,attrib) return propMapping def _mapSTRTypeSelection(self): #strTypeFormatter = LookupFormatter(CheckSocialTenureRelationship) #self.cboSTRType.clear() strTypeSelection=self.cboSTRType.currentText() strMapping = OrderedDict() strMapping[str(QApplication.translate("newSTRWiz","STR Type"))] = str(strTypeSelection) return strMapping def _mapEnjoyRightSelection(self,enjoyRight): deadAliveFormatter = LookupFormatter(CheckDeadAlive) inheritanceFormatter = LookupFormatter(CheckInheritanceType) enjoyRightMapping = OrderedDict() enjoyRightMapping[str(QApplication.translate("newSTRWiz","Inheritance From"))] = str(inheritanceFormatter.setDisplay(enjoyRight.InheritanceType).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","State"))] = str(deadAliveFormatter.setDisplay(enjoyRight.State).toString()) enjoyRightMapping[str(QApplication.translate("newSTRWiz","Receiving Date"))] = str(enjoyRight.ReceivingDate.year) return enjoyRightMapping def _mapPrivatePropertyTax(self): privateTaxMapping = OrderedDict() privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Payment Year"))] = str(self.dtLastYearCFBP.date().toPyDate().year) taxDec = Decimal(str(self.txtCFBPAmount.text())) taxFormatted = moneyfmt(taxDec,curr = CURRENCY_CODE) privateTaxMapping[str(QApplication.translate("newSTRWiz","CFPB Amount"))] = taxFormatted return privateTaxMapping def _mapStatePropertyTax(self): stateTaxMapping = OrderedDict() stateTaxMapping[str(QApplication.translate("newSTRWiz","Latest Receipt Date"))] = str(self.dtStateReceiptDate.date().toPyDate()) taxDec = Decimal(str(self.txtStateReceiptAmount.text())) taxFormatted = moneyfmt(taxDec,curr = CURRENCY_CODE) stateTaxMapping[str(QApplication.translate("newSTRWiz","Amount"))] = taxFormatted stateTaxMapping[str(QApplication.translate("newSTRWiz","Lease Starting Year"))] = str(self.dtStateLeaseYear.date().toPyDate().year) stateTaxMapping[str(QApplication.translate("newSTRWiz","Tax Office"))] = str(self.txtStateTaxOffice.text()) return stateTaxMapping def _mapConflict(self,conflict): conflictFormatter = LookupFormatter(CheckConflictState) conflictMapping = OrderedDict() if conflict == None: return conflictMapping conflictMapping[str(QApplication.translate("newSTRWiz","Status"))] = str(conflictFormatter.setDisplay(conflict.StateID).toString()) if conflict.Description: conflictMapping[str(QApplication.translate("newSTRWiz","Description"))] = conflict.Description if conflict.Solution: conflictMapping[str(QApplication.translate("newSTRWiz","Solution"))] = conflict.Solution return conflictMapping def onLoadGMaps(self,state): ''' Slot raised when a user clicks to set Google Maps Satellite as the base layer ''' if state: self.propBrowser.setBaseLayer(GMAP_SATELLITE) def onLoadOSM(self,state): ''' Slot raised when a user clicks to set OSM as the base layer ''' if state: self.propBrowser.setBaseLayer(OSM) def onMapZoomLevelChanged(self,level): ''' Slot which is raised when the zoom level of the map changes. ''' self.zoomSlider.setValue(level) def _onResetMap(self): ''' Slot raised when the user clicks to reset the property location in the map. ''' self.propBrowser.zoom_to_extents() def overlayProperty(self): ''' Overlay property boundaries on the basemap imagery ''' self.propBrowser.add_overlay(self.selProperty,'geom_polygon') def validateEnjoymentRight(self): ''' Validate whether the user has specified all the required information ''' self.notifEnjoyment.clear() if self.cboDeadAlive.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify whether the person is 'Dead' or 'Alive'.") self.notifEnjoyment.insertErrorNotification(msg) return False if self.cboInheritanceType.currentIndex() == 0: msg = QApplication.translate("newSTRWiz", "Please specify the Inheritance Type.") self.notifEnjoyment.insertErrorNotification(msg) return False #Set the right of enjoyment details if both inheritance type and state have been defined if self.cboInheritanceType.currentIndex() != 0 and self.cboDeadAlive.currentIndex() != 0: eRight = EnjoymentRight() #Set the properties setModelAttrFromCombo(eRight,"InheritanceType",self.cboInheritanceType) setModelAttrFromCombo(eRight,"State",self.cboDeadAlive) eRight.ReceivingDate = self.dtReceivingDate.date().toPyDate() self.enjoymentRight = eRight return True def validateSourceDocuments(self): ''' Basically validates the entry of tax information. ''' isValid = True if self.rbPrivateProperty.isChecked(): if self.gpPrivateTaxInfo.isChecked(): self.notifSourceDoc.clear() if str(self.txtCFBPAmount.text()) == "": self.txtCFBPAmount.setFocus() msg1 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg1) isValid = False elif self.rbStateland.isChecked(): self.notifSourceDoc.clear() if str(self.txtStateReceiptAmount.text()) == "": self.txtStateReceiptAmount.setFocus() msg2 = QApplication.translate("newSTRWiz", "Please enter the tax amount.") self.notifSourceDoc.insertErrorNotification(msg2) isValid = False if str(self.txtStateTaxOffice.text()) == "": self.txtStateTaxOffice.setFocus() msg3 = QApplication.translate("newSTRWiz", "Please specify the tax office.") self.notifSourceDoc.insertErrorNotification(msg3) isValid = False return isValid def validateConflict(self): ''' Check if the user has selected that there is a conflict and validate whether the description and solution have been specified. ''' isValid = True nonConflict = QApplication.translate("Lookup","No Conflict") nonConflictIndex = self.cboConflictOccurrence.findText(nonConflict) conflictOccurrence = QApplication.translate("Lookup","Conflict Present") occIndex = self.cboConflictOccurrence.findText(conflictOccurrence) if self.cboConflictOccurrence.currentIndex() == occIndex: self.notifConflict.clear() if str(self.txtConflictDescription.toPlainText()) == "": msg1 = QApplication.translate("newSTRWiz", "Please provide a brief description of the conflict.") self.notifConflict.insertErrorNotification(msg1) isValid = False if str(self.txtConflictSolution.toPlainText()) == "": msg2 = QApplication.translate("newSTRWiz", "Please provide a proposed solution for the specified conflict.") self.notifConflict.insertErrorNotification(msg2) isValid = False if str(self.txtConflictSolution.toPlainText()) != "" and str(self.txtConflictDescription.toPlainText()) != "": self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(occIndex).toInt() self.conflict.StateID = stateId self.conflict.Description = str(self.txtConflictDescription.toPlainText()) self.conflict.Solution = str(self.txtConflictSolution.toPlainText()) #Set conflict object properties if self.cboConflictOccurrence.currentIndex() == nonConflictIndex: self.conflict = Conflict() stateId,ok = self.cboConflictOccurrence.itemData(nonConflictIndex).toInt() self.conflict.StateID = stateId return isValid def onSelectPrivateProperty(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(0) def onSelectStateland(self,state): ''' Slot raised when the user clicks to load source document page for private property ''' if state: self.stkSrcDocList.setCurrentIndex(1) def onUploadTitleDeed(self): ''' Slot raised when the user clicks to upload a title deed ''' titleStr = QApplication.translate("newSTRWiz", "Specify the Document File Location") titles = self.selectSourceDocumentDialog(titleStr) for title in titles: self.sourceDocManager.insertDocumentFromFile(title,DEFAULT_DOCUMENT) def onUploadStatutoryRefPaper(self): ''' Slot raised when the user clicks to upload a statutory reference paper ''' statStr = QApplication.translate("newSTRWiz", "Specify Statutory Reference Paper File Location") stats = self.selectSourceDocumentDialog(statStr) for stat in stats: self.sourceDocManager.insertDocumentFromFile(stat,STATUTORY_REF_PAPER) def onUploadSurveyorRef(self): ''' Slot raised when the user clicks to upload a surveyor reference ''' surveyorStr = QApplication.translate("newSTRWiz", "Specify Surveyor Reference File Location") surveyorRefs = self.selectSourceDocumentDialog(surveyorStr) for surveyorRef in surveyorRefs: self.sourceDocManager.insertDocumentFromFile(surveyorRef,SURVEYOR_REF) def onUploadNotaryRef(self): ''' Slot raised when the user clicks to upload a notary reference ''' notaryStr = QApplication.translate("newSTRWiz", "Specify Notary Reference File Location") notaryRefs = self.selectSourceDocumentDialog(notaryStr) for notaryRef in notaryRefs: self.sourceDocManager.insertDocumentFromFile(notaryRef,NOTARY_REF) def onUploadPrivateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for private property ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.privateTaxDocManager, scan, TAX_RECEIPT_PRIVATE) def onUploadStateReceiptScan(self): ''' Slot raised when the user clicks to upload a receipt scan for stateland ''' receiptScan = QApplication.translate("newSTRWiz", "Specify Receipt Scan File Location") scan = self.selectReceiptScanDialog(receiptScan) if scan != "" or scan != None: #Ensure that there is only one tax receipt document before inserting self.validateReceiptScanInsertion(self.stateTaxDocManager, scan, TAX_RECEIPT_STATE) def validateReceiptScanInsertion(self,documentmanager,scan,containerid): ''' Checks and ensures that only one document exists in the specified container. ''' container = documentmanager.container(containerid) if container.count() > 0: msg = QApplication.translate("newSTRWiz", "Only one receipt scan can be uploaded.\nWould you like to replace " \ "the existing one?") result = QMessageBox.warning(self,QApplication.translate("newSTRWiz","Replace Receipt Scan"),msg, QMessageBox.Yes| QMessageBox.No) if result == QMessageBox.Yes: docWidget = container.itemAt(0).widget() docWidget.removeDocument() documentmanager.insertDocumentFromFile(scan,containerid) else: return else: documentmanager.insertDocumentFromFile(scan,containerid) def selectSourceDocumentDialog(self,title): ''' Displays a file dialog for a user to specify a source document ''' files = QFileDialog.getOpenFileNames(self,title,"/home","Source Documents (*.*)") return files def selectReceiptScanDialog(self,title): ''' Displays a file dialog for a user to specify a file location of a receipt scan ''' file = QFileDialog.getOpenFileName(self,title,"/home","Tax Receipt Scan (*.pdf)") return file def uploadDocument(self,path,containerid): ''' Upload source document ''' self.sourceDocManager.insertDocumentFromFile(path, containerid)