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 __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 __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 __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()
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 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, 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 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)