class ApplyTemplatesDialog(QDialog, FORM_CLASS): def __init__(self, iface, parent=None): super(ApplyTemplatesDialog, self).__init__(parent) self.setupUi(self) self.iface = iface self.layers = [] self.translatedNoneLabel = QCoreApplication.translate( "Metatools", "None") self.licenseTemplateManager = LicenseTemplateManager(currentPath) self.workflowTemplateManager = WorkflowTemplateManager(currentPath) self.datatypeTemplateManager = DatatypeTemplateManager(currentPath) path = os.path.join(currentPath, "templates/institutions.xml") self.orgsTemplateManager = OrganizationTemplateManager(path) self.btnApply = QPushButton(self.tr("Apply")) self.btnClose = QPushButton(self.tr("Close")) self.buttonBox.clear() self.buttonBox.addButton(self.btnApply, QDialogButtonBox.AcceptRole) self.buttonBox.addButton(self.btnClose, QDialogButtonBox.RejectRole) self.chkExternalFiles.stateChanged.connect(self.toggleExternalFiles) self.lstLayers.itemSelectionChanged.connect(self.updateLayerList) self.btnSelectDataFiles.clicked.connect(self.selectExternalFiles) self.btnManageLicenses.clicked.connect(self.manageLicenses) self.btnManageOrgs.clicked.connect(self.manageOrganizations) self.btnManageWorkflows.clicked.connect(self.manageWorkflows) self.btnManageDatatypes.clicked.connect(self.manageDatatypes) self.btnSelectLogFile.clicked.connect(self.selectLogFile) self.buttonBox.accepted.disconnect(self.accept) self.btnApply.clicked.connect(self.applyTemplates) self.manageGui() def manageGui(self): # read settings and restore checkbox state self.__loadSettings() # populate layer list self.fillLstLayers() # populate comboboxes with templates self.updateLicenseTemplatesList() self.updateWorkflowTemplatesList() self.updateOrgsTemplatesList() self.updateDatatypesTemplatesList() # disable Apply button when there are no layers if len(self.layers) == 0: self.btnApply.setEnabled(False) #version from trunk def fillLstLayers(self): self.lstLayers.clear() layers = utils.getSupportedLayers() for (name, source) in layers: item = QListWidgetItem(name, self.lstLayers) item.setData(Qt.UserRole, source) item.setData(Qt.ToolTipRole, source) def toggleExternalFiles(self): self.btnApply.setEnabled(False) if self.chkExternalFiles.isChecked(): self.lstLayers.clear() self.lstLayers.setSelectionMode(QAbstractItemView.NoSelection) self.btnSelectDataFiles.setEnabled(True) self.layers = [] else: self.fillLstLayers() self.lstLayers.setSelectionMode( QAbstractItemView.ExtendedSelection) self.btnSelectDataFiles.setEnabled(False) self.updateLayerList() def selectExternalFiles(self): files = QFileDialog.getOpenFileNames(self, self.tr("Select files"), ".", self.tr("All files (*.*)")) if len(files) == 0: return self.layers = files self.lstLayers.addItems(files) self.btnApply.setEnabled(True) def manageLicenses(self): oldValue = self.cmbLicense.currentText() dlg = LicenseEditorDialog() dlg.exec_() self.updateLicenseTemplatesList() # try to restore previous value index = self.cmbLicense.findText(oldValue) if index != -1: self.cmbLicense.setCurrentIndex(index) def manageDatatypes(self): oldValue = self.cmbDatatype.currentText() dlg = DataTypeEditorDialog() dlg.exec_() self.updateDatatypesTemplatesList() # try to restore previous value index = self.cmbDatatype.findText(oldValue) if index != -1: self.cmbDatatype.setCurrentIndex(index) def manageWorkflows(self): oldValue = self.cmbWorkflow.currentText() dlg = WorkflowEditorDialog() dlg.exec_() self.updateWorkflowTemplatesList() # try to restore previous value index = self.cmbWorkflow.findText(oldValue) if index != -1: self.cmbWorkflow.setCurrentIndex(index) def manageOrganizations(self): oldValue = self.cmbOrganization.currentText() dlg = OrganizationEditorDialog() dlg.exec_() self.orgsTemplateManager.reloadTemplates() self.updateOrgsTemplatesList() # try to restore previous value index = self.cmbOrganization.findText(oldValue) if index != -1: self.cmbOrganization.setCurrentIndex(index) def selectLogFile(self): # TODO: need to save last dir and set it in dialog logFileName = QFileDialog.getOpenFileName( self, self.tr("Select log file"), ".", self.tr("Text files (*.txt);;Log files (*.log);;All files (*)"), options=QFileDialog.ReadOnly) self.leLogFile.setText(logFileName) self.leLogFile.setToolTip(logFileName) def updateLicenseTemplatesList(self): self.cmbLicense.clear() self.cmbLicense.addItem(self.translatedNoneLabel) self.cmbLicense.addItems(self.licenseTemplateManager.getTemplateList()) def updateWorkflowTemplatesList(self): self.cmbWorkflow.clear() self.cmbWorkflow.addItem(self.translatedNoneLabel) self.cmbWorkflow.addItems( self.workflowTemplateManager.getTemplateList()) def updateOrgsTemplatesList(self): self.cmbOrganization.clear() self.cmbOrganization.addItem(self.translatedNoneLabel) self.cmbOrganization.addItems( self.orgsTemplateManager.tempalateNames()) def updateDatatypesTemplatesList(self): self.cmbDatatype.clear() self.cmbDatatype.addItem(self.translatedNoneLabel) self.cmbDatatype.addItems( self.datatypeTemplateManager.getTemplateList()) def updateLayerList(self): self.layers = [] selection = self.lstLayers.selectedItems() for item in selection: layerSource = item.data(Qt.UserRole) self.layers.append(layerSource) #my old version #layer = utils.getRasterLayerByName(item.text()) #self.layers.append(layer.source()) if len(self.layers) != 0: self.btnApply.setEnabled(True) def applyTemplates(self): # TODO: !!! Remake to metaprovider !!! # TODO: !!! Adding standard check !!! # TODO: check if there are some templates selected # get profile from settings settings = QSettings("NextGIS", "metatools") profile = "xml_iso19115.xml" if profile == "": QMessageBox.warning( self, self.tr("No profile"), self. tr("No profile selected. Please set default profile in plugin settings" )) return profilePath = unicode( QDir.toNativeSeparators( os.path.join(currentPath, "xml_profiles", unicode(profile)))) try: for layer in self.layers: # get metadata file path metaFilePath = utils.mdPathFromLayerPath(layer) # check if metadata file exists and create it if necessary if not os.path.exists(metaFilePath): try: shutil.copyfile(profilePath, metaFilePath) except: QMessageBox.warning( self, self.tr("Metatools"), self.tr("Metadata file can't be created: ") + unicode(sys.exc_info()[1])) continue # check metadata standard metaprovider = FileMetadataProvider( unicode(layer)) #temporary code standard = MetaInfoStandard.tryDetermineStandard(metaprovider) if standard != MetaInfoStandard.ISO19115: QMessageBox.warning( self, self.tr("Metatools"), self. tr("File %s has unsupported metadata standard! Only ISO19115 supported now!" ) % (layer)) continue if os.path.splitext(unicode(layer))[1].lower() not in (".shp", ".mif", ".tab"): # extract image specific information if self.chkUpdateImageInfo.isChecked(): utils.writeRasterInfo(layer, metaFilePath) # generate preview if self.chkGeneratePreview.isChecked(): utils.generatePreview(layer) else: if self.chkUpdateImageInfo.isChecked(): utils.writeVectorInfo(layer, metaFilePath) # load metadata file metadata_file = QFile(metaFilePath) metaXML = QDomDocument() metaXML.setContent(metadata_file) # apply templates (BAD version - change to applier with standard) self.applyInstitutionTemplate(metaXML) self.applyLicenseTemplate(metaXML) self.applyWorkflowTemplate(metaXML) self.applyDatatypeTemplate(metaXML) self.applyLogFile(metaXML) # save metadata file (hmm.. why not QFile?) metafile = codecs.open(metaFilePath, "w", encoding="utf-8") metafile.write(metaXML.toString()) metafile.close() QMessageBox.information(self, self.tr("Metatools"), self.tr("Done!")) # clear selection and disable Apply button self.lstLayers.clearSelection() self.layers = [] self.btnApply.setEnabled(False) # save settings self.__saveSettings() except: QMessageBox.warning( self, self.tr("Metatools"), self.tr("Operation can't be completed: ") + unicode(sys.exc_info()[1])) # ----------- Appliers ----------- def applyInstitutionTemplate(self, metaXML): # TODO: make more safe #if self.cmbOrganization.currentIndex() == -1: if self.cmbOrganization.currentText() == self.translatedNoneLabel: return template = self.orgsTemplateManager.organizations[ self.cmbOrganization.currentText()] root = metaXML.documentElement() mdContact = utils.getOrCreateChild(root, "contact") mdResponsibleParty = utils.getOrCreateChild(mdContact, "CI_ResponsibleParty") # individualName mdIndividualName = utils.getOrCreateChild(mdResponsibleParty, "individualName") mdCharStringElement = utils.getOrCreateChild(mdIndividualName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.person) # organisationName mdOrganisationName = utils.getOrCreateChild(mdResponsibleParty, "organisationName") mdCharStringElement = utils.getOrCreateChild(mdOrganisationName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.name) # positionName mdPositionName = utils.getOrCreateChild(mdResponsibleParty, "positionName") mdCharStringElement = utils.getOrCreateChild(mdPositionName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.position) # go deeper... fill contactInfo mdContactInfo = utils.getOrCreateChild(mdResponsibleParty, "contactInfo") mdCIContact = utils.getOrCreateChild(mdContactInfo, "CI_Contact") # hours of service mdHours = utils.getOrCreateChild(mdCIContact, "hoursOfService") mdCharStringElement = utils.getOrCreateChild(mdHours, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.hours) # fill phones mdPhone = utils.getOrCreateChild(mdCIContact, "phone") mdCIPhone = utils.getOrCreateChild(mdPhone, "CI_Telephone") mdVoice = utils.getOrCreateChild(mdCIPhone, "voice") mdCharStringElement = utils.getOrCreateChild(mdVoice, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.phone) mdFacsimile = utils.getOrCreateChild(mdCIPhone, "facsimile") mdCharStringElement = utils.getOrCreateChild(mdFacsimile, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.phone) # fill address mdAddress = utils.getOrCreateChild(mdCIContact, "address") mdCIAddress = utils.getOrCreateChild(mdAddress, "CI_Address") # deliveryPoint mdDeliveryPoint = utils.getOrCreateChild(mdCIAddress, "deliveryPoint") mdCharStringElement = utils.getOrCreateChild(mdDeliveryPoint, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.deliveryPoint) # city mdCity = utils.getOrCreateChild(mdCIAddress, "city") mdCharStringElement = utils.getOrCreateChild(mdCity, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.city) # administrativeArea mdAdminArea = utils.getOrCreateChild(mdCIAddress, "administrativeArea") mdCharStringElement = utils.getOrCreateChild(mdAdminArea, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.adminArea) # postalCode mdPostalCode = utils.getOrCreateChild(mdCIAddress, "postalCode") mdCharStringElement = utils.getOrCreateChild(mdPostalCode, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.postalCode) # country mdCountry = utils.getOrCreateChild(mdCIAddress, "country") mdCharStringElement = utils.getOrCreateChild(mdCountry, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.country) # email mdEmail = utils.getOrCreateChild(mdCIAddress, "electronicMailAddress") mdCharStringElement = utils.getOrCreateChild(mdEmail, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.email) def applyLicenseTemplate(self, metaXML): # TODO: make more safe #if self.cmbLicense.currentIndex() == -1: if self.cmbLicense.currentText() == self.translatedNoneLabel: return licenseTemplate = self.licenseTemplateManager.loadTemplate( self.cmbLicense.currentText()) root = metaXML.documentElement() mdIdentificationInfo = utils.getOrCreateChild(root, "identificationInfo") mdDataIdentification = utils.getOrCreateChild(mdIdentificationInfo, "MD_DataIdentification") mdResourceConstraints = utils.getOrIsertAfterChild( mdDataIdentification, "resourceConstraints", [ "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract" ]) mdLegalConstraintsElement = utils.getOrCreateChild( mdResourceConstraints, "MD_LegalConstraints") # useLimitation mdUseLimitationElement = utils.getOrCreateChild( mdLegalConstraintsElement, "useLimitation") mdCharStringElement = utils.getOrCreateChild(mdUseLimitationElement, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(licenseTemplate.stringRepresentation()) # useConstraints mdUseConstraintsElement = utils.getOrCreateChild( mdLegalConstraintsElement, "useConstraints") mdRestrictionCodeElement = utils.getOrCreateChild( mdUseConstraintsElement, "MD_RestrictionCode") mdRestrictionCodeElement.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode" ) mdRestrictionCodeElement.setAttribute("codeListValue", "license") textNode = utils.getOrCreateTextChild(mdRestrictionCodeElement) textNode.setNodeValue("license") def applyWorkflowTemplate(self, metaXML): # TODO: make more safe #if self.cmbWorkflow.currentIndex() == -1: if self.cmbWorkflow.currentText() == self.translatedNoneLabel: return workflowTemplate = self.workflowTemplateManager.loadTemplate( self.cmbWorkflow.currentText()) root = metaXML.documentElement() mdDataQualityInfo = utils.getOrIsertAfterChild( root, "dataQualityInfo", ["distributionInfo", "contentInfo", "identificationInfo"]) mdDQData = utils.getOrCreateChild(mdDataQualityInfo, "DQ_DataQuality") # check requirements (not need for workflow) if mdDQData.firstChildElement("scope").isNull(): mdScope = utils.getOrIsertTopChild(mdDQData, "scope") mdDQScope = utils.getOrCreateChild(mdScope, "DQ_Scope") mdLevel = utils.getOrIsertTopChild(mdDQScope, "level") mdScopeCode = utils.getOrCreateChild(mdLevel, "MD_ScopeCode") mdScopeCode.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_ScopeCode" ) mdScopeCode.setAttribute("codeListValue", "dataset") textNode = utils.getOrCreateTextChild(mdScopeCode) textNode.setNodeValue("dataset") mdLineage = utils.getOrCreateChild(mdDQData, "lineage") mdLiLineage = utils.getOrCreateChild(mdLineage, "LI_Lineage") mdStatement = utils.getOrIsertTopChild(mdLiLineage, "statement") mdCharStringElement = utils.getOrCreateChild(mdStatement, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(workflowTemplate.stringRepresentation()) def applyDatatypeTemplate(self, metaXML): # TODO: make more safe if self.cmbDatatype.currentText() == self.translatedNoneLabel: return datatypeTemplate = self.datatypeTemplateManager.loadTemplate( self.cmbDatatype.currentText()) root = metaXML.documentElement() mdIdentificationInfo = utils.getOrCreateChild(root, "identificationInfo") mdDataIdentification = utils.getOrCreateChild(mdIdentificationInfo, "MD_DataIdentification") #insert type of data mdSpatialRep = utils.getOrIsertAfterChild( mdDataIdentification, "spatialRepresentationType", [ "aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract" ]) mdSpatialRepTypeCode = utils.getOrCreateChild( mdSpatialRep, "MD_SpatialRepresentationTypeCode") mdSpatialRepTypeCode.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_SpatialRepresentationTypeCode" ) textNode = utils.getOrCreateTextChild(mdSpatialRepTypeCode) if datatypeTemplate.type == "vector": mdSpatialRepTypeCode.setAttribute("codeListValue", "vector") textNode.setNodeValue("vector") else: mdSpatialRepTypeCode.setAttribute("codeListValue", "grid") textNode.setNodeValue("grid") #adding raster type mdContentInfo = utils.getOrCreateChild(root, "contentInfo") mdImageDescription = utils.getOrCreateChild( mdContentInfo, "MD_ImageDescription") mdContentType = utils.getOrIsertAfterChild( mdImageDescription, "contentType", ["attributeDescription"]) mdContentTypeCode = utils.getOrCreateChild( mdContentType, "MD_CoverageContentTypeCode") mdContentTypeCode.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_CoverageContentTypeCode" ) mdContentTypeCode.setAttribute("codeListValue", datatypeTemplate.type) textNode = utils.getOrCreateTextChild(mdContentTypeCode) textNode.setNodeValue(datatypeTemplate.type) #insert keywords mdDescKeywords = utils.getOrIsertAfterChild( mdDataIdentification, "descriptiveKeywords", [ "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract" ]) mdKeywords = utils.getOrCreateChild(mdDescKeywords, "MD_Keywords") for keyword in datatypeTemplate.keywords: mdKeyword = utils.insertAfterChild(mdKeywords, "keyword", [ "keyword", ]) mdString = utils.getOrCreateChild(mdKeyword, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdString) textNode.setNodeValue(keyword) mdType = utils.getOrIsertAfterChild(mdKeywords, "type", [ "keyword", ]) mdTypeCode = utils.getOrCreateChild(mdType, "MD_KeywordTypeCode") mdTypeCode.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode" ) mdTypeCode.setAttribute("codeListValue", "theme") textNode = utils.getOrCreateTextChild(mdTypeCode) textNode.setNodeValue("theme") #drop all spatial scale/accuracy while not mdDataIdentification.firstChildElement( "spatialResolution").isNull(): mdDataIdentification.removeChild( mdDataIdentification.firstChildElement("spatialResolution")) #insert spatial scale mdSpatialResolution = utils.insertAfterChild( mdDataIdentification, "spatialResolution", [ "spatialRepresentationType", "aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract" ]) mdResolution = utils.getOrCreateChild(mdSpatialResolution, "MD_Resolution") mdEqScale = utils.getOrIsertTopChild(mdResolution, "equivalentScale") mdFraction = utils.getOrCreateChild(mdEqScale, "MD_RepresentativeFraction") mdDenominator = utils.getOrCreateChild(mdFraction, "denominator") mdInteger = utils.getOrCreateChild(mdDenominator, "gco:Integer") textNode = utils.getOrCreateTextChild(mdInteger) textNode.setNodeValue(datatypeTemplate.scale) #insert spatial accuracy mdSpatialResolution = utils.insertAfterChild( mdDataIdentification, "spatialResolution", [ "spatialResolution", "spatialRepresentationType", "aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract" ]) mdResolution = utils.getOrCreateChild(mdSpatialResolution, "MD_Resolution") mdDistance = utils.getOrCreateChild(mdResolution, "distance") mdGcoDistance = utils.getOrCreateChild(mdDistance, "gco:Distance") textNode = utils.getOrCreateTextChild(mdGcoDistance) textNode.setNodeValue(datatypeTemplate.accuracy) mdGcoDistance.setAttribute("uom", "M") #insert thematic accurancy?????? return def applyLogFile(self, metaXML): # TODO: make more safe if self.leLogFile.text() == "": return logFile = codecs.open(self.leLogFile.text(), "r", encoding="utf-8") logFileContent = logFile.read() logFile.close() root = metaXML.documentElement() mdDataQualityInfo = utils.getOrIsertAfterChild( root, "dataQualityInfo", ["distributionInfo", "contentInfo", "identificationInfo"]) mdDQData = utils.getOrCreateChild(mdDataQualityInfo, "DQ_DataQuality") # check requirements (not need for log file) if mdDQData.firstChildElement("scope").isNull(): mdScope = utils.getOrIsertTopChild(mdDQData, "scope") mdDQScope = utils.getOrCreateChild(mdScope, "DQ_Scope") mdLevel = utils.getOrIsertTopChild(mdDQScope, "level") mdScopeCode = utils.getOrCreateChild(mdLevel, "MD_ScopeCode") mdScopeCode.setAttribute( "codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode" ) mdScopeCode.setAttribute("codeListValue", "dataset") textNode = utils.getOrCreateTextChild(mdScopeCode) textNode.setNodeValue("dataset") mdLineage = utils.getOrCreateChild(mdDQData, "lineage") mdLiLineage = utils.getOrCreateChild(mdLineage, "LI_Lineage") mdProcessStep = utils.getOrCreateChild(mdLiLineage, "processStep") mdLIProcessStep = utils.getOrCreateChild(mdProcessStep, "LI_ProcessStep") mdDescription = utils.getOrIsertTopChild(mdLIProcessStep, "description") mdCharStringElement = utils.getOrCreateChild(mdDescription, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(logFileContent) def __loadSettings(self): settings = QSettings("NextGIS", "metatools") self.chkUpdateImageInfo.setCheckState( int(settings.value("templates/extractLayerInfo", 0))) self.chkGeneratePreview.setCheckState( int(settings.value("templates/generatePreview", 0))) def __saveSettings(self): settings = QSettings("NextGIS", "metatools") settings.setValue("templates/extractLayerInfo", self.chkUpdateImageInfo.checkState()) settings.setValue("templates/generatePreview", self.chkGeneratePreview.checkState()) def accept(self): QDialog.accept(self)
class OrganizationEditorDialog(QDialog, Ui_OrganizationEditorDialog): def __init__(self): QDialog.__init__(self) self.setupUi(self) path = os.path.join(currentPath, "templates/institutions.xml") self.orgTemplateManager = OrganizationTemplateManager(path) self.orgTemplate = OrganizationTemplate() self.btnSave = self.buttonBox.button(QDialogButtonBox.Save) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close) self.btnNew.clicked.connect(self.newOrganization) self.btnRemove.clicked.connect(self.removeOrganization) self.leName.textEdited.connect(self.templateModified) self.leDeliveryPoint.textEdited.connect(self.templateModified) self.leCity.textEdited.connect(self.templateModified) self.leAdminArea.textEdited.connect(self.templateModified) self.lePostCode.textEdited.connect(self.templateModified) self.leCountry.textEdited.connect(self.templateModified) self.lePhone.textEdited.connect(self.templateModified) self.leFax.textEdited.connect(self.templateModified) self.leEmail.textEdited.connect(self.templateModified) self.leContactPerson.textEdited.connect(self.templateModified) self.lePersonTitle.textEdited.connect(self.templateModified) self.lePersonPosition.textEdited.connect(self.templateModified) self.leOfficeHours.textEdited.connect(self.templateModified) self.cmbOrganization.currentIndexChanged.connect( self.organizationChanged) self.buttonBox.accepted.disconnect(self.accept) self.btnSave.clicked.connect(self.saveTemplate) self.manageGui() def manageGui(self): self.btnRemove.setEnabled(False) self.reloadTemplatesList() self.btnSave.setEnabled(False) def reloadTemplatesList(self): self.cmbOrganization.clear() self.cmbOrganization.addItems(self.orgTemplateManager.tempalateNames()) def newOrganization(self): if self.btnSave.isEnabled() and QMessageBox.question( None, self.tr("Metatools"), self. tr("Template contains unsaved data. Create new template without saving?" ), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return self.clearFormFields() self.orgTemplate = OrganizationTemplate() self.btnSave.setEnabled(False) def removeOrganization(self): self.orgTemplateManager.removeTemplate( self.cmbOrganization.currentText()) self.reloadTemplatesList() if self.cmbOrganization.count() == 0: self.clearFormFields() # enable save button when template edited def templateModified(self): self.btnSave.setEnabled(True) def organizationChanged(self): templateName = self.cmbOrganization.currentText() if templateName == "": self.orgTemplate = OrganizationTemplate() self.btnRemove.setEnabled(False) return self.orgTemplate = self.orgTemplateManager.organizations[templateName] self.templateToForm(self.orgTemplate) self.btnSave.setEnabled(False) self.btnRemove.setEnabled(True) def saveTemplate(self): template = self.templateFromForm() self.orgTemplateManager.addTemplate(template.name, template) self.orgTemplateManager.saveTemplates() # reload form self.reloadTemplatesList() # set combobox item index = self.cmbOrganization.findText(template.name) if index != -1: self.cmbOrganization.setCurrentIndex(index) self.btnSave.setEnabled(False) def clearFormFields(self): self.leName.clear() self.leDeliveryPoint.clear() self.leCity.clear() self.leAdminArea.clear() self.lePostCode.clear() self.leCountry.clear() self.lePhone.clear() self.leFax.clear() self.leEmail.clear() self.leContactPerson.clear() self.lePersonTitle.clear() self.lePersonPosition.clear() self.leOfficeHours.clear() # populate form with template data def templateToForm(self, template): self.leName.setText(template.name or "") self.leDeliveryPoint.setText(template.deliveryPoint or "") self.leCity.setText(template.city or "") self.leAdminArea.setText(template.adminArea or "") self.lePostCode.setText(template.postalCode or "") self.leCountry.setText(template.country or "") self.lePhone.setText(template.phone or "") self.leFax.setText(template.fax or "") self.leEmail.setText(template.email or "") self.leContactPerson.setText(template.person or "") self.lePersonTitle.setText(template.title or "") self.lePersonPosition.setText(template.position or "") self.leOfficeHours.setText(template.hours or "") # create template from entered values def templateFromForm(self): template = OrganizationTemplate() template.name = self.leName.text() template.deliveryPoint = self.leDeliveryPoint.text() template.city = self.leCity.text() template.adminArea = self.leAdminArea.text() template.postalCode = self.lePostCode.text() template.country = self.leCountry.text() template.phone = self.lePhone.text() template.fax = self.leFax.text() template.email = self.leEmail.text() template.person = self.leContactPerson.text() template.title = self.lePersonTitle.text() template.position = self.lePersonPosition.text() template.hours = self.leOfficeHours.text() return template def reject(self): if self.btnSave.isEnabled() and QMessageBox.question( None, self.tr("Metatools"), self. tr("Template contains unsaved data. Close the window without saving?" ), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return QDialog.reject(self) def accept(self): QDialog.accept(self)
class ApplyTemplatesDialog(QDialog, Ui_ApplyTemplatesDialog): def __init__(self, iface): QDialog.__init__(self) self.setupUi(self) self.iface = iface self.layers = [] self.translatedNoneLabel = QCoreApplication.translate("Metatools", "None") self.licenseTemplateManager = LicenseTemplateManager(currentPath) self.workflowTemplateManager = WorkflowTemplateManager(currentPath) self.datatypeTemplateManager = DatatypeTemplateManager(currentPath) path = os.path.join(currentPath, "templates/institutions.xml") self.orgsTemplateManager = OrganizationTemplateManager(path) self.btnApply = QPushButton(self.tr("Apply")) self.btnClose = QPushButton(self.tr("Close")) self.buttonBox.clear() self.buttonBox.addButton(self.btnApply, QDialogButtonBox.AcceptRole) self.buttonBox.addButton(self.btnClose, QDialogButtonBox.RejectRole) self.chkExternalFiles.stateChanged.connect(self.toggleExternalFiles) self.lstLayers.itemSelectionChanged.connect(self.updateLayerList) self.btnSelectDataFiles.clicked.connect(self.selectExternalFiles) self.btnManageLicenses.clicked.connect(self.manageLicenses) self.btnManageOrgs.clicked.connect(self.manageOrganizations) self.btnManageWorkflows.clicked.connect(self.manageWorkflows) self.btnManageDatatypes.clicked.connect(self.manageDatatypes) self.btnSelectLogFile.clicked.connect(self.selectLogFile) self.buttonBox.accepted.disconnect(self.accept) self.btnApply.clicked.connect(self.applyTemplates) self.manageGui() def manageGui(self): # read settings and restore checkbox state self.__loadSettings() # populate layer list self.fillLstLayers() # populate comboboxes with templates self.updateLicenseTemplatesList() self.updateWorkflowTemplatesList() self.updateOrgsTemplatesList() self.updateDatatypesTemplatesList() # disable Apply button when there are no layers if len(self.layers) == 0: self.btnApply.setEnabled(False) #version from trunk def fillLstLayers(self): self.lstLayers.clear() layers = utils.getSupportedLayers() for (name, source) in layers: item = QListWidgetItem(name, self.lstLayers) item.setData(Qt.UserRole, source) item.setData(Qt.ToolTipRole, source) def toggleExternalFiles(self): self.btnApply.setEnabled(False) if self.chkExternalFiles.isChecked(): self.lstLayers.clear() self.lstLayers.setSelectionMode(QAbstractItemView.NoSelection) self.btnSelectDataFiles.setEnabled(True) self.layers = [] else: self.fillLstLayers() self.lstLayers.setSelectionMode(QAbstractItemView.ExtendedSelection) self.btnSelectDataFiles.setEnabled(False) self.updateLayerList() def selectExternalFiles(self): files = QFileDialog.getOpenFileNames(self, self.tr("Select files"), ".", self.tr("All files (*.*)") ) if len(files) == 0: return self.layers = files self.lstLayers.addItems(files) self.btnApply.setEnabled(True) def manageLicenses(self): oldValue = self.cmbLicense.currentText() dlg = LicenseEditorDialog() dlg.exec_() self.updateLicenseTemplatesList() # try to restore previous value index = self.cmbLicense.findText(oldValue) if index != -1: self.cmbLicense.setCurrentIndex(index) def manageDatatypes(self): oldValue = self.cmbDatatype.currentText() dlg = DataTypeEditorDialog() dlg.exec_() self.updateDatatypesTemplatesList() # try to restore previous value index = self.cmbDatatype.findText(oldValue) if index != -1: self.cmbDatatype.setCurrentIndex(index) def manageWorkflows(self): oldValue = self.cmbWorkflow.currentText() dlg = WorkflowEditorDialog() dlg.exec_() self.updateWorkflowTemplatesList() # try to restore previous value index = self.cmbWorkflow.findText(oldValue) if index != -1: self.cmbWorkflow.setCurrentIndex(index) def manageOrganizations(self): oldValue = self.cmbOrganization.currentText() dlg = OrganizationEditorDialog() dlg.exec_() self.orgsTemplateManager.reloadTemplates() self.updateOrgsTemplatesList() # try to restore previous value index = self.cmbOrganization.findText(oldValue) if index != -1: self.cmbOrganization.setCurrentIndex(index) def selectLogFile(self): # TODO: need to save last dir and set it in dialog logFileName = QFileDialog.getOpenFileName(self, self.tr("Select log file"), ".", self.tr("Text files (*.txt);;Log files (*.log);;All files (*)"), options=QFileDialog.ReadOnly ) self.leLogFile.setText(logFileName) self.leLogFile.setToolTip(logFileName) def updateLicenseTemplatesList(self): self.cmbLicense.clear() self.cmbLicense.addItem(self.translatedNoneLabel) self.cmbLicense.addItems(self.licenseTemplateManager.getTemplateList()) def updateWorkflowTemplatesList(self): self.cmbWorkflow.clear() self.cmbWorkflow.addItem(self.translatedNoneLabel) self.cmbWorkflow.addItems(self.workflowTemplateManager.getTemplateList()) def updateOrgsTemplatesList(self): self.cmbOrganization.clear() self.cmbOrganization.addItem(self.translatedNoneLabel) self.cmbOrganization.addItems(self.orgsTemplateManager.tempalateNames()) def updateDatatypesTemplatesList(self): self.cmbDatatype.clear() self.cmbDatatype.addItem(self.translatedNoneLabel) self.cmbDatatype.addItems(self.datatypeTemplateManager.getTemplateList()) def updateLayerList(self): self.layers = [] selection = self.lstLayers.selectedItems() for item in selection: layerSource = item.data(Qt.UserRole) self.layers.append(layerSource) #my old version #layer = utils.getRasterLayerByName(item.text()) #self.layers.append(layer.source()) if len(self.layers) != 0: self.btnApply.setEnabled(True) def applyTemplates(self): # TODO: !!! Remake to metaprovider !!! # TODO: !!! Adding standard check !!! # TODO: check if there are some templates selected # get profile from settings settings = QSettings("NextGIS", "metatools") profile = settings.value("general/defaultProfile", "") if profile == "": QMessageBox.warning(self, self.tr("No profile"), self.tr("No profile selected. Please set default profile in plugin settings") ) return profilePath = unicode(QDir.toNativeSeparators(os.path.join(currentPath, "xml_profiles", unicode(profile)))) try: for layer in self.layers: # get metadata file path metaFilePath = utils.mdPathFromLayerPath(layer) # check if metadata file exists and create it if necessary if not os.path.exists(metaFilePath): try: shutil.copyfile(profilePath, metaFilePath) except: QMessageBox.warning(self, self.tr("Metatools"), self.tr("Metadata file can't be created: ") + unicode(sys.exc_info()[1]) ) continue # check metadata standard metaprovider = FileMetadataProvider(unicode(layer)) #temporary code standard = MetaInfoStandard.tryDetermineStandard(metaprovider) if standard != MetaInfoStandard.ISO19115: QMessageBox.warning(self, self.tr("Metatools"), self.tr("File %s has unsupported metadata standard! Only ISO19115 supported now!") % (layer)) continue if os.path.splitext(unicode(layer))[1].lower() not in (".shp", ".mif", ".tab"): # extract image specific information if self.chkUpdateImageInfo.isChecked(): utils.writeRasterInfo(layer, metaFilePath) # generate preview if self.chkGeneratePreview.isChecked(): utils.generatePreview(layer) else: if self.chkUpdateImageInfo.isChecked(): utils.writeVectorInfo(layer, metaFilePath) # load metadata file metadata_file = QFile(metaFilePath) metaXML = QDomDocument() metaXML.setContent(metadata_file) # apply templates (BAD version - change to applier with standard) self.applyInstitutionTemplate(metaXML) self.applyLicenseTemplate(metaXML) self.applyWorkflowTemplate(metaXML) self.applyDatatypeTemplate(metaXML) self.applyLogFile(metaXML) # save metadata file (hmm.. why not QFile?) metafile = codecs.open(metaFilePath, "w", encoding="utf-8") metafile.write(unicode(metaXML, "utf-8")) metafile.close() QMessageBox.information(self, self.tr("Metatools"), self.tr("Done!") ) # clear selection and disable Apply button self.lstLayers.clearSelection() self.layers = [] self.btnApply.setEnabled(False) # save settings self.__saveSettings() except: QMessageBox.warning(self, self.tr("Metatools"), self.tr("Operation can't be completed: ") + unicode(sys.exc_info()[1]) ) # ----------- Appliers ----------- def applyInstitutionTemplate(self, metaXML): # TODO: make more safe #if self.cmbOrganization.currentIndex() == -1: if self.cmbOrganization.currentText() == self.translatedNoneLabel: return template = self.orgsTemplateManager.organizations[self.cmbOrganization.currentText()] root = metaXML.documentElement() mdContact = utils.getOrCreateChild(root, "contact") mdResponsibleParty = utils.getOrCreateChild(mdContact, "CI_ResponsibleParty") # individualName mdIndividualName = utils.getOrCreateChild(mdResponsibleParty, "individualName") mdCharStringElement = utils.getOrCreateChild(mdIndividualName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.person) # organisationName mdOrganisationName = utils.getOrCreateChild(mdResponsibleParty, "organisationName") mdCharStringElement = utils.getOrCreateChild(mdOrganisationName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.name) # positionName mdPositionName = utils.getOrCreateChild(mdResponsibleParty, "positionName") mdCharStringElement = utils.getOrCreateChild(mdPositionName, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.position) # go deeper... fill contactInfo mdContactInfo = utils.getOrCreateChild(mdResponsibleParty, "contactInfo") mdCIContact = utils.getOrCreateChild(mdContactInfo, "CI_Contact") # hours of service mdHours = utils.getOrCreateChild(mdCIContact, "hoursOfService") mdCharStringElement = utils.getOrCreateChild(mdHours, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.hours) # fill phones mdPhone = utils.getOrCreateChild(mdCIContact, "phone") mdCIPhone = utils.getOrCreateChild(mdPhone, "CI_Telephone") mdVoice = utils.getOrCreateChild(mdCIPhone, "voice") mdCharStringElement = utils.getOrCreateChild(mdVoice, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.phone) mdFacsimile = utils.getOrCreateChild(mdCIPhone, "facsimile") mdCharStringElement = utils.getOrCreateChild(mdFacsimile, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.phone) # fill address mdAddress = utils.getOrCreateChild(mdCIContact, "address") mdCIAddress = utils.getOrCreateChild(mdAddress, "CI_Address") # deliveryPoint mdDeliveryPoint = utils.getOrCreateChild(mdCIAddress, "deliveryPoint") mdCharStringElement = utils.getOrCreateChild(mdDeliveryPoint, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.deliveryPoint) # city mdCity = utils.getOrCreateChild(mdCIAddress, "city") mdCharStringElement = utils.getOrCreateChild(mdCity, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.city) # administrativeArea mdAdminArea = utils.getOrCreateChild(mdCIAddress, "administrativeArea") mdCharStringElement = utils.getOrCreateChild(mdAdminArea, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.adminArea) # postalCode mdPostalCode = utils.getOrCreateChild(mdCIAddress, "postalCode") mdCharStringElement = utils.getOrCreateChild(mdPostalCode, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.postalCode) # country mdCountry = utils.getOrCreateChild(mdCIAddress, "country") mdCharStringElement = utils.getOrCreateChild(mdCountry, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.country) # email mdEmail = utils.getOrCreateChild(mdCIAddress, "electronicMailAddress") mdCharStringElement = utils.getOrCreateChild(mdEmail, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(template.email) def applyLicenseTemplate(self, metaXML): # TODO: make more safe #if self.cmbLicense.currentIndex() == -1: if self.cmbLicense.currentText() == self.translatedNoneLabel: return licenseTemplate = self.licenseTemplateManager.loadTemplate(self.cmbLicense.currentText()) root = metaXML.documentElement() mdIdentificationInfo = utils.getOrCreateChild(root, "identificationInfo") mdDataIdentification = utils.getOrCreateChild(mdIdentificationInfo, "MD_DataIdentification") mdResourceConstraints = utils.getOrIsertAfterChild(mdDataIdentification, "resourceConstraints", ["resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract"]) mdLegalConstraintsElement = utils.getOrCreateChild(mdResourceConstraints, "MD_LegalConstraints") # useLimitation mdUseLimitationElement = utils.getOrCreateChild(mdLegalConstraintsElement, "useLimitation") mdCharStringElement = utils.getOrCreateChild(mdUseLimitationElement, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(licenseTemplate.stringRepresentation()) # useConstraints mdUseConstraintsElement = utils.getOrCreateChild(mdLegalConstraintsElement, "useConstraints") mdRestrictionCodeElement = utils.getOrCreateChild(mdUseConstraintsElement, "MD_RestrictionCode") mdRestrictionCodeElement.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode") mdRestrictionCodeElement.setAttribute("codeListValue", "license") textNode = utils.getOrCreateTextChild(mdRestrictionCodeElement) textNode.setNodeValue("license") def applyWorkflowTemplate(self, metaXML): # TODO: make more safe #if self.cmbWorkflow.currentIndex() == -1: if self.cmbWorkflow.currentText() == self.translatedNoneLabel: return workflowTemplate = self.workflowTemplateManager.loadTemplate(self.cmbWorkflow.currentText()) root = metaXML.documentElement() mdDataQualityInfo = utils.getOrIsertAfterChild(root, "dataQualityInfo", ["distributionInfo", "contentInfo", "identificationInfo"]) mdDQData = utils.getOrCreateChild(mdDataQualityInfo, "DQ_DataQuality") # check requirements (not need for workflow) if mdDQData.firstChildElement("scope").isNull(): mdScope = utils.getOrIsertTopChild(mdDQData, "scope") mdDQScope = utils.getOrCreateChild(mdScope, "DQ_Scope") mdLevel = utils.getOrIsertTopChild(mdDQScope, "level") mdScopeCode = utils.getOrCreateChild(mdLevel, "MD_ScopeCode") mdScopeCode.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_ScopeCode") mdScopeCode.setAttribute("codeListValue", "dataset") textNode = utils.getOrCreateTextChild(mdScopeCode) textNode.setNodeValue("dataset") mdLineage = utils.getOrCreateChild(mdDQData, "lineage") mdLiLineage = utils.getOrCreateChild(mdLineage, "LI_Lineage") mdStatement = utils.getOrIsertTopChild(mdLiLineage, "statement") mdCharStringElement = utils.getOrCreateChild(mdStatement, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(workflowTemplate.stringRepresentation()) def applyDatatypeTemplate(self, metaXML): # TODO: make more safe if self.cmbDatatype.currentText() == self.translatedNoneLabel: return datatypeTemplate = self.datatypeTemplateManager.loadTemplate(self.cmbDatatype.currentText()) root = metaXML.documentElement() mdIdentificationInfo = utils.getOrCreateChild(root, "identificationInfo") mdDataIdentification = utils.getOrCreateChild(mdIdentificationInfo, "MD_DataIdentification") #insert type of data mdSpatialRep = utils.getOrIsertAfterChild(mdDataIdentification, "spatialRepresentationType", ["aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract"]) mdSpatialRepTypeCode = utils.getOrCreateChild(mdSpatialRep, "MD_SpatialRepresentationTypeCode") mdSpatialRepTypeCode.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_SpatialRepresentationTypeCode") textNode = utils.getOrCreateTextChild(mdSpatialRepTypeCode) if datatypeTemplate.type == "vector": mdSpatialRepTypeCode.setAttribute("codeListValue", "vector") textNode.setNodeValue("vector") else: mdSpatialRepTypeCode.setAttribute("codeListValue", "grid") textNode.setNodeValue("grid") #adding raster type mdContentInfo = utils.getOrCreateChild(root, "contentInfo") mdImageDescription = utils.getOrCreateChild(mdContentInfo, "MD_ImageDescription") mdContentType = utils.getOrIsertAfterChild(mdImageDescription, "contentType", ["attributeDescription"]) mdContentTypeCode = utils.getOrCreateChild(mdContentType, "MD_CoverageContentTypeCode") mdContentTypeCode.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_CoverageContentTypeCode") mdContentTypeCode.setAttribute("codeListValue", datatypeTemplate.type) textNode = utils.getOrCreateTextChild(mdContentTypeCode) textNode.setNodeValue(datatypeTemplate.type) #insert keywords mdDescKeywords = utils.getOrIsertAfterChild(mdDataIdentification, "descriptiveKeywords", ["resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract"]) mdKeywords = utils.getOrCreateChild(mdDescKeywords, "MD_Keywords") for keyword in datatypeTemplate.keywords: mdKeyword = utils.insertAfterChild(mdKeywords, "keyword", ["keyword",]) mdString = utils.getOrCreateChild(mdKeyword, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdString) textNode.setNodeValue(keyword) mdType = utils.getOrIsertAfterChild(mdKeywords, "type", ["keyword",]) mdTypeCode = utils.getOrCreateChild(mdType, "MD_KeywordTypeCode") mdTypeCode.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_KeywordTypeCode") mdTypeCode.setAttribute("codeListValue", "theme") textNode = utils.getOrCreateTextChild(mdTypeCode) textNode.setNodeValue("theme") #drop all spatial scale/accuracy while not mdDataIdentification.firstChildElement("spatialResolution").isNull(): mdDataIdentification.removeChild(mdDataIdentification.firstChildElement("spatialResolution")) #insert spatial scale mdSpatialResolution = utils.insertAfterChild(mdDataIdentification, "spatialResolution", ["spatialRepresentationType", "aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract"]) mdResolution = utils.getOrCreateChild(mdSpatialResolution, "MD_Resolution") mdEqScale = utils.getOrIsertTopChild(mdResolution, "equivalentScale") mdFraction = utils.getOrCreateChild(mdEqScale, "MD_RepresentativeFraction") mdDenominator = utils.getOrCreateChild(mdFraction, "denominator") mdInteger = utils.getOrCreateChild(mdDenominator, "gco:Integer") textNode = utils.getOrCreateTextChild(mdInteger) textNode.setNodeValue(datatypeTemplate.scale) #insert spatial accuracy mdSpatialResolution = utils.insertAfterChild(mdDataIdentification, "spatialResolution", ["spatialResolution", "spatialRepresentationType", "aggregationInfo", "resourceConstraints", "resourceSpecificUsage", "descriptiveKeywords", "resourceFormat", "graphicOverview", "resourceMaintenance", "pointOfContact", "status", "credit", "purpose", "abstract"]) mdResolution = utils.getOrCreateChild(mdSpatialResolution, "MD_Resolution") mdDistance = utils.getOrCreateChild(mdResolution, "distance") mdGcoDistance = utils.getOrCreateChild(mdDistance, "gco:Distance") textNode = utils.getOrCreateTextChild(mdGcoDistance) textNode.setNodeValue(datatypeTemplate.accuracy) mdGcoDistance.setAttribute("uom", "M") #insert thematic accurancy?????? return def applyLogFile(self, metaXML): # TODO: make more safe if self.leLogFile.text() == "": return logFile = codecs.open(self.leLogFile.text(), "r", encoding="utf-8") logFileContent = logFile.read() logFile.close() root = metaXML.documentElement() mdDataQualityInfo = utils.getOrIsertAfterChild(root, "dataQualityInfo", ["distributionInfo", "contentInfo", "identificationInfo"]) mdDQData = utils.getOrCreateChild(mdDataQualityInfo, "DQ_DataQuality") # check requirements (not need for log file) if mdDQData.firstChildElement("scope").isNull(): mdScope = utils.getOrIsertTopChild(mdDQData, "scope") mdDQScope = utils.getOrCreateChild(mdScope, "DQ_Scope") mdLevel = utils.getOrIsertTopChild(mdDQScope, "level") mdScopeCode = utils.getOrCreateChild(mdLevel, "MD_ScopeCode") mdScopeCode.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#MD_ScopeCode") mdScopeCode.setAttribute("codeListValue", "dataset") textNode = utils.getOrCreateTextChild(mdScopeCode) textNode.setNodeValue("dataset") mdLineage = utils.getOrCreateChild(mdDQData, "lineage") mdLiLineage = utils.getOrCreateChild(mdLineage, "LI_Lineage") mdProcessStep = utils.getOrCreateChild(mdLiLineage, "processStep") mdLIProcessStep = utils.getOrCreateChild(mdProcessStep, "LI_ProcessStep") mdDescription = utils.getOrIsertTopChild(mdLIProcessStep, "description") mdCharStringElement = utils.getOrCreateChild(mdDescription, "gco:CharacterString") textNode = utils.getOrCreateTextChild(mdCharStringElement) textNode.setNodeValue(logFileContent) def __loadSettings(self): settings = QSettings("NextGIS", "metatools") self.chkUpdateImageInfo.setCheckState(int(settings.value("templates/extractLayerInfo", 0))) self.chkGeneratePreview.setCheckState(int(settings.value("templates/generatePreview", 0))) def __saveSettings(self): settings = QSettings("NextGIS", "metatools") settings.setValue("templates/extractLayerInfo", self.chkUpdateImageInfo.checkState()) settings.setValue("templates/generatePreview", self.chkGeneratePreview.checkState()) def accept(self): QDialog.accept(self)
class OrganizationEditorDialog(QDialog, FORM_CLASS): def __init__(self, parent=None): super(OrganizationEditorDialog, self).__init__(parent) self.setupUi(self) path = os.path.join(currentPath, "templates/institutions.xml") self.orgTemplateManager = OrganizationTemplateManager(path) self.orgTemplate = OrganizationTemplate() self.btnSave = self.buttonBox.button(QDialogButtonBox.Save) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close) self.btnNew.clicked.connect(self.newOrganization) self.btnRemove.clicked.connect(self.removeOrganization) self.leName.textEdited.connect(self.templateModified) self.leDeliveryPoint.textEdited.connect(self.templateModified) self.leCity.textEdited.connect(self.templateModified) self.leAdminArea.textEdited.connect(self.templateModified) self.lePostCode.textEdited.connect(self.templateModified) self.leCountry.textEdited.connect(self.templateModified) self.lePhone.textEdited.connect(self.templateModified) self.leFax.textEdited.connect(self.templateModified) self.leEmail.textEdited.connect(self.templateModified) self.leContactPerson.textEdited.connect(self.templateModified) self.lePersonTitle.textEdited.connect(self.templateModified) self.lePersonPosition.textEdited.connect(self.templateModified) self.leOfficeHours.textEdited.connect(self.templateModified) self.cmbOrganization.currentIndexChanged.connect(self.organizationChanged) self.buttonBox.accepted.disconnect(self.accept) self.btnSave.clicked.connect(self.saveTemplate) self.manageGui() def manageGui(self): self.btnRemove.setEnabled(False) self.reloadTemplatesList() self.btnSave.setEnabled(False) def reloadTemplatesList(self): self.cmbOrganization.clear() self.cmbOrganization.addItems(self.orgTemplateManager.tempalateNames()) def newOrganization(self): if self.btnSave.isEnabled() and QMessageBox.question(None, self.tr("Metatools"), self.tr("Template contains unsaved data. Create new template without saving?"), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return self.clearFormFields() self.orgTemplate = OrganizationTemplate() self.btnSave.setEnabled(False) def removeOrganization(self): self.orgTemplateManager.removeTemplate(self.cmbOrganization.currentText()) self.reloadTemplatesList() if self.cmbOrganization.count() == 0: self.clearFormFields() # enable save button when template edited def templateModified(self): self.btnSave.setEnabled(True) def organizationChanged(self): templateName = self.cmbOrganization.currentText() if templateName == "": self.orgTemplate = OrganizationTemplate() self.btnRemove.setEnabled(False) return self.orgTemplate = self.orgTemplateManager.organizations[templateName] self.templateToForm(self.orgTemplate) self.btnSave.setEnabled(False) self.btnRemove.setEnabled(True) def saveTemplate(self): template = self.templateFromForm() self.orgTemplateManager.addTemplate(template.name, template) self.orgTemplateManager.saveTemplates() # reload form self.reloadTemplatesList() # set combobox item index = self.cmbOrganization.findText(template.name) if index != -1: self.cmbOrganization.setCurrentIndex(index) self.btnSave.setEnabled(False) def clearFormFields(self): self.leName.clear() self.leDeliveryPoint.clear() self.leCity.clear() self.leAdminArea.clear() self.lePostCode.clear() self.leCountry.clear() self.lePhone.clear() self.leFax.clear() self.leEmail.clear() self.leContactPerson.clear() self.lePersonTitle.clear() self.lePersonPosition.clear() self.leOfficeHours.clear() # populate form with template data def templateToForm(self, template): self.leName.setText(template.name or "") self.leDeliveryPoint.setText(template.deliveryPoint or "") self.leCity.setText(template.city or "") self.leAdminArea.setText(template.adminArea or "") self.lePostCode.setText(template.postalCode or "") self.leCountry.setText(template.country or "") self.lePhone.setText(template.phone or "") self.leFax.setText(template.fax or "") self.leEmail.setText(template.email or "") self.leContactPerson.setText(template.person or "") self.lePersonTitle.setText(template.title or "") self.lePersonPosition.setText(template.position or "") self.leOfficeHours.setText(template.hours or "") # create template from entered values def templateFromForm(self): template = OrganizationTemplate() template.name = self.leName.text() template.deliveryPoint = self.leDeliveryPoint.text() template.city = self.leCity.text() template.adminArea = self.leAdminArea.text() template.postalCode = self.lePostCode.text() template.country = self.leCountry.text() template.phone = self.lePhone.text() template.fax = self.leFax.text() template.email = self.leEmail.text() template.person = self.leContactPerson.text() template.title = self.lePersonTitle.text() template.position = self.lePersonPosition.text() template.hours = self.leOfficeHours.text() return template def reject(self): if self.btnSave.isEnabled() and QMessageBox.question(None, self.tr("Metatools"), self.tr("Template contains unsaved data. Close the window without saving?"), QMessageBox.Yes | QMessageBox.No) == QMessageBox.No: return QDialog.reject(self) def accept(self): QDialog.accept(self)