def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n',
                                  'projectsldplugin_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.SETTINGS_SECTION = '/projectsldplugin/'
        self.filename = self.getSettingsValue('lastfile')

        # Create the dialog (after translation) and keep reference
        self.dlg = ProjectSldPluginDialog()
        self.dlg.ui.cbx_save_as_file.toggled.connect(self.saveAsFileToggled)
        self.dlg.ui.cbx_post_to_server.toggled.connect(
            self.postToServerToggled)
        self.dlg.ui.btn_filename.clicked.connect(self.filenameButtonClicked)
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n', 'projectsldplugin_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.SETTINGS_SECTION = '/projectsldplugin/'
        self.filename = self.getSettingsValue('lastfile')

        # Create the dialog (after translation) and keep reference
        self.dlg = ProjectSldPluginDialog()
        self.dlg.ui.cbx_save_as_file.toggled.connect(self.saveAsFileToggled)
        self.dlg.ui.cbx_post_to_server.toggled.connect(self.postToServerToggled)
        self.dlg.ui.btn_filename.clicked.connect(self.filenameButtonClicked)
class ProjectSldPlugin:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n',
                                  'projectsldplugin_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.SETTINGS_SECTION = '/projectsldplugin/'
        self.filename = self.getSettingsValue('lastfile')

        # Create the dialog (after translation) and keep reference
        self.dlg = ProjectSldPluginDialog()
        self.dlg.ui.cbx_save_as_file.toggled.connect(self.saveAsFileToggled)
        self.dlg.ui.cbx_post_to_server.toggled.connect(
            self.postToServerToggled)
        self.dlg.ui.btn_filename.clicked.connect(self.filenameButtonClicked)

    def initGui(self):
        # Create action that will start plugin configuration
        self.action = QAction(QIcon(":/plugins/projectsldplugin/icon.png"),
                              u"SLD export", self.iface.mainWindow())
        # connect the action to the run method
        self.action.triggered.connect(self.run)

        # Add toolbar button and menu item
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(u"SLD export", self.action)

    def unload(self):
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu(u"SLD export", self.action)
        self.iface.removeToolBarIcon(self.action)

    # run method that performs all the real work
    def run(self):
        self.dlg.ui.le_workspace.setText(
            self.getSettingsValue('default-workspace'))
        self.dlg.ui.le_post_url.setText(config.params['post-url'])
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result == 1:
            self.createProjectSld()

    def debug(self, string):
        print "###### DEBUG"
        print string

    def postToServerToggled(self):
        checked = self.dlg.ui.cbx_post_to_server.isChecked()
        self.dlg.ui.lbl_workspace.setEnabled(checked)
        self.dlg.ui.le_workspace.setEnabled(checked)

    def saveAsFileToggled(self):
        checked = self.dlg.ui.cbx_save_as_file.isChecked()
        # disable or enable the inputs
        self.dlg.ui.lbl_filename.setEnabled(checked)
        self.dlg.ui.le_filename.setEnabled(checked)
        self.dlg.ui.btn_filename.setEnabled(checked)
        if checked:
            self.dlg.ui.le_filename.setText(self.getSettingsValue('lastfile'))
        else:
            self.dlg.ui.le_filename.setText('')

    def getSettingsValue(self, key):
        if QSettings().contains(self.SETTINGS_SECTION + key):
            key = self.SETTINGS_SECTION + key
            if QGis.QGIS_VERSION_INT < 10900:  # qgis <= 1.8
                return unicode(QSettings().value(key).toString())
            else:
                return unicode(QSettings().value(key))
        elif config.params.has_key(key):
            return config.params[key]
        else:
            return u''

    def setSettingsValue(self, key, value):
        key = self.SETTINGS_SECTION + key
        QSettings().setValue(key, value)

    def filenameButtonClicked(self):
        (self.filename, filter) = QFileDialog.getSaveFileNameAndFilter(
            self.iface.mainWindow(), "SLD bestand opslaan als...",
            os.path.realpath(self.filename), "sld files (*.sld)")
        fn, fileextension = os.path.splitext(unicode(self.filename))
        if len(fn) == 0:  # user choose cancel
            return
        #if fileextension != '.sld':
        #    self.filename = fn + '.sld'
        # save this filename in settings for later
        self.dlg.ui.le_filename.setText(self.filename)

    def createProjectSld(self):
        if self.dlg.ui.cbx_save_as_file.isChecked() == False:
            file = QTemporaryFile(QDir.tempPath() + os.sep + 'qgis_XXXXXX.sld')
            file.open()
            self.filename = file.fileName()
        else:
            try:
                file = open(self.filename, "w")
            except:
                self.iface.messageBar().pushMessage(
                    'Fout',
                    'Kan het bestand "' + unicode(self.filename) +
                    '" niet opslaan. Is dit een geldige bestandsnaam en schrijfbaar?',
                    level=QgsMessageBar.CRITICAL,
                    duration=5)
                return

        resultdom = None
        # holding the QTemporaryFile handles here, just to be sure they are not
        # removed while working on the layerlist
        layerslds = []
        # for every layer
        for i in range(self.iface.mapCanvas().layerCount() - 1, -1, -1):
            layer = self.iface.mapCanvas().layer(i)
            # for now: only vector layers (== type=0) style can be saved to sld
            if layer.type() > 0:
                continue
            f = QTemporaryFile(QDir.tempPath() + os.sep + 'qgis_XXXXXX.sld')
            f.open()
            fname = f.fileName()
            # create a sld in temporary dir
            layer.saveSldStyle(fname)
            if resultdom == None:
                resultdom = parse(
                    fname)  # is now holding a DOM of the first sld
                self.addFillElementToGraphicMark(resultdom)
            else:
                layer_dom = parse(fname)
                namedlayer = layer_dom.getElementsByTagName('NamedLayer')[0]
                self.addFillElementToGraphicMark(namedlayer)
                resultdom.getElementsByTagName(
                    'StyledLayerDescriptor')[0].appendChild(namedlayer)

            # append both fname AND temporary file object (to prevent it being removed)
            layerslds.append((fname, f))

        if resultdom == None:
            self.iface.messageBar().pushMessage(
                "Warning",
                "Geen sld bestand aangemaakt. Zijn er wel vector lagen aanwezig?",
                level=QgsMessageBar.WARNING,
                duration=510)
            return

        # multiplier for stroke width in sld
        self.multiplyStrokeWidth(resultdom)
        # multiplier for point size symbols
        self.multipyPointSize(resultdom)

        #print resultdom.toxml()
        # toprettyxml looks better, but has an awfull lot of whitespace,
        # see: http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/
        #xml = resultdom.toprettyxml()
        xml = resultdom.toxml()

        # now replace all replacements from config
        for key in config.replace:
            xml = xml.replace(key, config.replace[key])
        file.write(xml)
        file.close()

        # only remember if checked and succesfull
        if self.dlg.ui.cbx_save_as_file.isChecked():
            self.setSettingsValue('lastfile', self.filename)
            self.iface.messageBar().pushMessage(
                "Info",
                "Sld succesvol opgeslagen als: " + unicode(self.filename),
                level=QgsMessageBar.INFO,
                duration=2)

        if self.dlg.ui.cbx_post_to_server.isChecked():
            self.post_sld()

    def post_sld(self):
        url = config.params['post-url']
        files = {'file': open(self.filename, 'rb')}
        workspace = self.dlg.ui.le_workspace.text()
        workspacekey = config.params['post-workspace-param']
        self.setSettingsValue('default-workspace', workspace)
        username = config.params['post-username']
        password = config.params['post-password']
        try:
            r = requests.post(url,
                              timeout=10,
                              data={workspacekey: workspace},
                              files=files,
                              auth=HTTPBasicAuth(username, password))
            if r.status_code == 200:
                self.iface.messageBar().pushMessage(
                    "Info",
                    "Sld succesvol verstuurd... ",
                    level=QgsMessageBar.INFO,
                    duration=2)
                sldurl = r.text
                QMessageBox.information(
                    self.iface.mainWindow(), "Sld",
                    ("Gebruik onderstaande url in Kaartenbalie:\n\n" + sldurl +
                     "\n"), QMessageBox.Ok, QMessageBox.Ok)
            else:
                self.iface.messageBar().pushMessage(
                    "Fout",
                    "Probleem bij het versturen van de sld: " +
                    unicode(r.status_code),
                    level=QgsMessageBar.CRITICAL,
                    duration=5)
        except requests.exceptions.Timeout:
            self.iface.messageBar().pushMessage("Fout",
                                                "Timout bij posten naar: " +
                                                unicode(url) +
                                                ". Is de url wel juist?",
                                                level=QgsMessageBar.CRITICAL,
                                                duration=5)

    # <se:SvgParameter name="stroke-width">2</se:SvgParameter>
    def multiplyStrokeWidth(self, dom):
        strokeWidthMultiplier = float(config.params['stroke-width-multiplier'])
        svgparams = dom.getElementsByTagName('se:SvgParameter')
        if len(svgparams) > 0:
            for svgparam in svgparams:
                if svgparam.getAttribute('name') == 'stroke-width':
                    width = float(svgparam.childNodes[0].nodeValue)
                    svgparam.childNodes[
                        0].nodeValue = width * strokeWidthMultiplier

    # <se:PointSymbolizer>..<se:Size>2</se:Size>
    def multipyPointSize(self, dom):
        pointSizeMultiplier = float(config.params['point-size-multiplier'])
        pointsyms = dom.getElementsByTagName('se:PointSymbolizer')
        if len(pointsyms) > 0:
            for pointsym in pointsyms:
                size = float(self.childNodeValue(pointsym, 'se:Size'))
                sizeElement = pointsym.getElementsByTagName('se:Size')
                sizeElement[0].childNodes[
                    0].nodeValue = size * pointSizeMultiplier

    def addFillElementToGraphicMark(self, dom):
        marks = dom.getElementsByTagName('se:Mark')
        if len(marks) > 0:
            for mark in marks:
                mark_type = self.childNodeValue(mark, 'se:WellKnownName')
                # only adding fill for following 'wellknowname' types:
                # QGIS: only do: horline, line, cross, slash, backslash, x
                if mark_type in [
                        'horline', 'line', 'cross', 'slash', 'backslash', 'x'
                ]:
                    stroke = mark.getElementsByTagName('se:Stroke')
                    if len(stroke):
                        stroke_color = self.childNodeValue(
                            stroke[0], 'se:SvgParameter')
                        fill = parseString(
                            u'<se:Fill xmlns:se="http://www.opengis.net/se"><se:CssParameter name="fill">'
                            + stroke_color + u'</se:CssParameter></se:Fill>')
                        fill_elm = fill.getElementsByTagName('se:Fill')[0]
                        mark.appendChild(fill_elm)

    def childNodeValue(self, node, childName):
        nodes = node.getElementsByTagName(childName)
        if len(nodes) == 1 and nodes[0].hasChildNodes():
            return nodes[0].childNodes[0].nodeValue
        if len(nodes) > 1:
            arr = u''
            for child in nodes:
                # extra check, we only want direct childs
                if child.parentNode.nodeName == node.nodeName and child.hasChildNodes(
                ):
                    arr += (child.childNodes[0].nodeValue)
                    arr += ','
            return arr.rstrip(',')
        return ''
class ProjectSldPlugin:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 'i18n', 'projectsldplugin_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.SETTINGS_SECTION = '/projectsldplugin/'
        self.filename = self.getSettingsValue('lastfile')

        # Create the dialog (after translation) and keep reference
        self.dlg = ProjectSldPluginDialog()
        self.dlg.ui.cbx_save_as_file.toggled.connect(self.saveAsFileToggled)
        self.dlg.ui.cbx_post_to_server.toggled.connect(self.postToServerToggled)
        self.dlg.ui.btn_filename.clicked.connect(self.filenameButtonClicked)

    def initGui(self):
        # Create action that will start plugin configuration
        self.action = QAction(
            QIcon(":/plugins/projectsldplugin/icon.png"),
            u"SLD export", self.iface.mainWindow())
        # connect the action to the run method
        self.action.triggered.connect(self.run)

        # Add toolbar button and menu item
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(u"SLD export", self.action)

    def unload(self):
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu(u"SLD export", self.action)
        self.iface.removeToolBarIcon(self.action)

    # run method that performs all the real work
    def run(self):
        self.dlg.ui.le_workspace.setText(self.getSettingsValue('default-workspace'))
        self.dlg.ui.le_post_url.setText(config.params['post-url'])
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result == 1:
            self.createProjectSld()

    def debug(self, string):
        print "###### DEBUG"
        print string

    def postToServerToggled(self):
        checked = self.dlg.ui.cbx_post_to_server.isChecked()
        self.dlg.ui.lbl_workspace.setEnabled(checked)
        self.dlg.ui.le_workspace.setEnabled(checked)

    def saveAsFileToggled(self):
        checked = self.dlg.ui.cbx_save_as_file.isChecked()
        # disable or enable the inputs
        self.dlg.ui.lbl_filename.setEnabled(checked)
        self.dlg.ui.le_filename.setEnabled(checked)
        self.dlg.ui.btn_filename.setEnabled(checked)
        if checked:
            self.dlg.ui.le_filename.setText(self.getSettingsValue('lastfile'))
        else:
            self.dlg.ui.le_filename.setText('')

    def getSettingsValue(self, key):
        if QSettings().contains(self.SETTINGS_SECTION + key):
            key = self.SETTINGS_SECTION + key
            if QGis.QGIS_VERSION_INT < 10900: # qgis <= 1.8
                return unicode(QSettings().value(key).toString())
            else:
                return unicode(QSettings().value(key))
        elif config.params.has_key(key):
            return config.params[key]
        else:
            return u''
    def setSettingsValue(self, key, value):
        key = self.SETTINGS_SECTION + key
        QSettings().setValue(key, value)

    def filenameButtonClicked(self):
        (self.filename, filter) = QFileDialog.getSaveFileNameAndFilter(
            self.iface.mainWindow(),
            "SLD bestand opslaan als...",
            os.path.realpath(self.filename),
            "sld files (*.sld)")
        fn, fileextension = os.path.splitext(unicode(self.filename))
        if len(fn) == 0: # user choose cancel
            return
        #if fileextension != '.sld':
        #    self.filename = fn + '.sld'
        # save this filename in settings for later
        self.dlg.ui.le_filename.setText(self.filename)

    def createProjectSld(self):
        if self.dlg.ui.cbx_save_as_file.isChecked() == False:
            file = QTemporaryFile(QDir.tempPath()+os.sep+'qgis_XXXXXX.sld')
            file.open()
            self.filename = file.fileName()
        else:
            try:
                file = open(self.filename, "w")
            except:
                self.iface.messageBar().pushMessage('Fout', 
                    'Kan het bestand "'+
                    unicode(self.filename) + '" niet opslaan. Is dit een geldige bestandsnaam en schrijfbaar?', level=QgsMessageBar.CRITICAL, duration=5)
                return

        resultdom = None
        # holding the QTemporaryFile handles here, just to be sure they are not
        # removed while working on the layerlist
        layerslds = []
        # for every layer
        for i in range (self.iface.mapCanvas().layerCount()-1, -1, -1):
            layer = self.iface.mapCanvas().layer(i)
            # for now: only vector layers (== type=0) style can be saved to sld
            if layer.type() >0:
                continue
            f = QTemporaryFile(QDir.tempPath()+os.sep+'qgis_XXXXXX.sld')
            f.open()
            fname = f.fileName()
            # create a sld in temporary dir
            layer.saveSldStyle(fname)
            if resultdom == None:
                resultdom = parse(fname) # is now holding a DOM of the first sld
                self.addFillElementToGraphicMark(resultdom)
            else:
                layer_dom = parse(fname)
                namedlayer = layer_dom.getElementsByTagName('NamedLayer')[0]
                self.addFillElementToGraphicMark(namedlayer)
                resultdom.getElementsByTagName('StyledLayerDescriptor')[0].appendChild(namedlayer)

            # append both fname AND temporary file object (to prevent it being removed)
            layerslds.append((fname, f))

        if resultdom == None:
            self.iface.messageBar().pushMessage("Warning", "Geen sld bestand aangemaakt. Zijn er wel vector lagen aanwezig?", level=QgsMessageBar.WARNING, duration=510)
            return

        # multiplier for stroke width in sld
        self.multiplyStrokeWidth(resultdom)
        # multiplier for point size symbols
        self.multipyPointSize(resultdom)

        #print resultdom.toxml()
        # toprettyxml looks better, but has an awfull lot of whitespace, 
        # see: http://ronrothman.com/public/leftbraned/xml-dom-minidom-toprettyxml-and-silly-whitespace/
        #xml = resultdom.toprettyxml()
        xml = resultdom.toxml()

        # now replace all replacements from config
        for key in config.replace:
            xml = xml.replace(key, config.replace[key])
        file.write(xml)
        file.close()

        # only remember if checked and succesfull
        if self.dlg.ui.cbx_save_as_file.isChecked():
            self.setSettingsValue('lastfile', self.filename)
            self.iface.messageBar().pushMessage("Info", "Sld succesvol opgeslagen als: "+unicode(self.filename), level=QgsMessageBar.INFO, duration=2)

        if self.dlg.ui.cbx_post_to_server.isChecked():
            self.post_sld()

    def post_sld(self):
        url = config.params['post-url']
        files = {'file': open(self.filename, 'rb')}
        workspace = self.dlg.ui.le_workspace.text()
        workspacekey = config.params['post-workspace-param']
        self.setSettingsValue('default-workspace', workspace)
        username = config.params['post-username']
        password = config.params['post-password']
        try:
            r = requests.post(url,
                timeout=10,
                data={workspacekey:workspace},
                files=files,
                auth=HTTPBasicAuth(username, password))
            if r.status_code == 200:
                self.iface.messageBar().pushMessage("Info", "Sld succesvol verstuurd... ", level=QgsMessageBar.INFO, duration=2)
                sldurl = r.text
                QMessageBox.information(self.iface.mainWindow(), "Sld", 
                    ("Gebruik onderstaande url in Kaartenbalie:\n\n" + sldurl +
                    "\n"), QMessageBox.Ok, QMessageBox.Ok)
            else:
                self.iface.messageBar().pushMessage("Fout", 
                    "Probleem bij het versturen van de sld: "+
                    unicode(r.status_code), level=QgsMessageBar.CRITICAL, duration=5)
        except requests.exceptions.Timeout:
            self.iface.messageBar().pushMessage("Fout", 
                "Timout bij posten naar: "+
                unicode(url) + ". Is de url wel juist?", level=QgsMessageBar.CRITICAL, duration=5)


    # <se:SvgParameter name="stroke-width">2</se:SvgParameter>
    def multiplyStrokeWidth(self, dom):
        strokeWidthMultiplier = float(config.params['stroke-width-multiplier'])
        svgparams = dom.getElementsByTagName('se:SvgParameter')
        if len(svgparams)>0:
            for svgparam in svgparams:
                if svgparam.getAttribute('name')=='stroke-width':
                    width = float(svgparam.childNodes[0].nodeValue)
                    svgparam.childNodes[0].nodeValue=width*strokeWidthMultiplier

    # <se:PointSymbolizer>..<se:Size>2</se:Size>
    def multipyPointSize(self, dom):
        pointSizeMultiplier = float(config.params['point-size-multiplier'])
        pointsyms = dom.getElementsByTagName('se:PointSymbolizer')
        if len(pointsyms)>0:
            for pointsym in pointsyms:
                size = float(self.childNodeValue(pointsym, 'se:Size'))
                sizeElement = pointsym.getElementsByTagName('se:Size')
                sizeElement[0].childNodes[0].nodeValue=size*pointSizeMultiplier

    def addFillElementToGraphicMark(self, dom):
        marks = dom.getElementsByTagName('se:Mark')
        if len(marks)>0:
            for mark in marks:
                mark_type = self.childNodeValue(mark, 'se:WellKnownName')
                # only adding fill for following 'wellknowname' types:
                # QGIS: only do: horline, line, cross, slash, backslash, x
                if mark_type in ['horline', 'line', 'cross', 'slash', 'backslash', 'x']:
                    stroke = mark.getElementsByTagName('se:Stroke')
                    if len(stroke):
                        stroke_color = self.childNodeValue(stroke[0], 'se:SvgParameter')
                        fill = parseString(u'<se:Fill xmlns:se="http://www.opengis.net/se"><se:CssParameter name="fill">'+stroke_color+u'</se:CssParameter></se:Fill>')
                        fill_elm = fill.getElementsByTagName('se:Fill')[0]
                        mark.appendChild(fill_elm)

    def childNodeValue(self, node, childName):
        nodes = node.getElementsByTagName(childName)
        if len(nodes)==1 and nodes[0].hasChildNodes():
            return nodes[0].childNodes[0].nodeValue
        if len(nodes)>1:
            arr = u''
            for child in nodes:
                # extra check, we only want direct childs
                if child.parentNode.nodeName==node.nodeName and child.hasChildNodes():
                    arr+=(child.childNodes[0].nodeValue)
                    arr+=','
            return arr.rstrip(',')
        return ''