예제 #1
0
    def addAction(self, action):
        button = QToolButton(self)
        button.setProperty("action", True)
        button.setIconSize(QSize(64, 64))
        button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        button.setDefaultAction(action)

        self.actionsLayout.addWidget(button)
예제 #2
0
    def addAction(self, action, row, column):
        button = QToolButton(self)
        button.setObjectName(action.objectName())
        button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        button.setProperty("action", True)
        button.setIconSize(QSize(64, 64))
        button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        button.setDefaultAction(action)
        action.triggered.connect(self.close)

        self.actionsLayout.addWidget(button, row, column)
예제 #3
0
 def createAction(self, provider):
     icon = QIcon(':/plugins/PosiView/ledgreen.png')
     icon.addFile(':/plugins/PosiView/ledgrey.png', QSize(), QIcon.Disabled, QIcon.Off)
     action = QAction(icon, provider.name, None)
     button = QToolButton()
     button.setDefaultAction(action)
     action.setEnabled(False)
     provider.deviceConnected.connect(action.setEnabled)
     provider.deviceDisconnected.connect(action.setDisabled)
     self.signalMapper.setMapping(action, provider.name)
     action.triggered.connect(self.signalMapper.map)
     self.addAction(action)
     self.actions.append(action)
예제 #4
0
    def __init__(self, parent, tree, name, value, action=None):
        QTreeWidgetItem.__init__(self, parent)
        self.parent = parent
        self.tree = tree
        self.name = name
        self._value = value
        self.combo = None
        self.list = None
        self.setText(0, name)
        widget = None
        if isinstance(value, QgsColorButton):
            widget = value
        elif isinstance(value, bool):
            if value:
                self.setCheckState(1, Qt.Checked)
            else:
                self.setCheckState(1, Qt.Unchecked)
        elif isinstance(value, tuple):
            self.combo = QComboBox()
            self.combo.setSizeAdjustPolicy(0)
            for option in value:
                self.combo.addItem(option)
            widget = self.combo
        elif isinstance(value, list):
            self.list = QListWidget()
            self.list.setSizeAdjustPolicy(0)
            self.list.setSelectionMode(QListWidget.MultiSelection)
            for option in value:
                self.list.addItem(option)
            widget = self.list
        else:
            self.setText(1, unicode(value))

        if action:
            layout = QHBoxLayout()
            layout.setMargin(0)
            if widget:
                layout.addWidget(widget)
            button = QToolButton()
            button.setDefaultAction(action)
            button.setText(action.text())
            layout.addWidget(button)
            layout.addStretch(1)
            widget = QWidget()
            widget.setLayout(layout)

        if widget:
            self.tree.setItemWidget(self, 1, widget)
예제 #5
0
    def _set_info_button(self):
        """ Set Giswater information button (always visible)
            If project is loaded show information form relating to Plugin Giswater
            Else open admin form with which can manage database and qgis projects
        """

        # Create instance class and add button into QGIS toolbar
        main_toolbutton = QToolButton()
        self.action_info = self.iface.addToolBarWidget(main_toolbutton)

        # Set icon button if exists
        icon_path = self.icon_folder + '36.png'
        if os.path.exists(icon_path):
            icon = QIcon(icon_path)
            self.action = QAction(icon, "Show info", self.iface.mainWindow())
        else:
            self.action = QAction("Show info", self.iface.mainWindow())

        main_toolbutton.setDefaultAction(self.action)
        admin_button = GwAdminButton()
        self.action.triggered.connect(partial(admin_button.init_sql, True))
class GeoGigPlugin(object):

    def __init__(self, iface):
        self.iface = iface
        config.iface = iface
        readSettings()
        config.initConfigParams()

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            trackLayer(layer)
        try:
            from qgistester.tests import addTestModule
            from geogig.tests import testplugin
            addTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        QSettings().setValue("/qgis/walForSqlite3", False)

    def unload(self):
        navigatorInstance.setVisible(False)
        try:
            QgsMapLayerRegistry.instance().layerWasAdded.disconnect(trackLayer)
            QgsMapLayerRegistry.instance().layerRemoved.disconnect(layerRemoved)
        except:
            pass

        self.menu.deleteLater()
        self.toolButton.deleteLater()

        self.iface.removePluginMenu("&GeoGig", self.explorerAction)
        self.iface.removePluginMenu("&GeoGig", self.toolAction)

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            removeLayerActions(layer)
        removeNonexistentTrackedLayers()
        removeTempFolder()

        try:
            from qgistester.tests import removeTestModule
            from geogig.tests import testplugin
            removeTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        try:
            from lessons import removeLessonsFolder
            removeLessonsFolder(folder, "geogig")
        except:
            pass

        removeHelpMenu("GeoGig")
        removeAboutMenu("GeoGig")
        removeSettingsMenu("GeoGig")

    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool", self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)

        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        bar.addWidget(self.toolButton)
        self.iface.addPluginToMenu("&GeoGig", self.explorerAction)
        self.iface.addPluginToMenu("&GeoGig", self.toolAction)

        addSettingsMenu("GeoGig")
        addHelpMenu("GeoGig")
        addAboutMenu("GeoGig")

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())

        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
            group_description = os.path.join(folder, "group.md")
            addGroup("GeoGig lessons", group_description)
        except Exception as e:
            pass

    def setWarning(self, msg):
        QMessageBox.warning(None, 'Could not complete GeoGig command',
                                  msg,
                                  QMessageBox.Ok)

    def setTool(self):
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)
예제 #7
0
class QRAVE:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        self.tm = QgsApplication.taskManager()
        self.qproject = QgsProject.instance()

        self.pluginIsActive = False

        self.dockwidget = None
        self.metawidget = None

        # Populated on load from a URL
        self.acknowledgements = None

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'QRAVE_{}.qm'.format(locale))
        self.settings = Settings(iface=self.iface)

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Riverscapes Plugin (QRAVE)')

        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'QRAVE')
        self.toolbar.setObjectName(u'QRAVE')

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('QRAVE', message)

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        self.qproject.readProject.connect(self.onProjectLoad)

        self.openAction = QAction(
            QIcon(':/plugins/qrave_toolbar/RaveAddIn_16px.png'),
            self.tr(u'Riverscapes Plugin (QRAVE)'), self.iface.mainWindow())
        self.openAction.triggered.connect(self.toggle_widget)

        self.openAction.setStatusTip('Toggle the project viewer')
        self.openAction.setWhatsThis('Toggle the project viewer')

        self.openProjectAction = QAction(
            QIcon(':/plugins/qrave_toolbar/OpenProject.png'),
            self.tr(u'Open Riverscapes Project'), self.iface.mainWindow())
        self.openProjectAction.triggered.connect(self.projectBrowserDlg)

        self.openProjectAction.setStatusTip('Open QRAVE project')
        self.openProjectAction.setWhatsThis('Open QRAVE project')

        self.helpButton = QToolButton()
        self.helpButton.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.helpButton.setMenu(QMenu())
        self.helpButton.setPopupMode(QToolButton.MenuButtonPopup)

        m = self.helpButton.menu()

        # TODO: get the local help working
        # self.helpAction = QAction(
        #     QIcon(':/plugins/qrave_toolbar/Help.png'),
        #     self.tr('Help'),
        #     self.iface.mainWindow()
        # )
        # self.helpAction.triggered.connect(partial(showPluginHelp, None, filename=':/plugins/qrave_toolbar/help/build/html/index'))
        # self.websiteAction = QAction(
        #     QIcon(':/plugins/qrave_toolbar/RaveAddIn_16px.png'),
        #     self.tr('Website'),
        #     self.iface.mainWindow()
        # )
        # self.websiteAction.triggered.connect(lambda: QDesktopServices.openUrl(QUrl("http://rave.riverscapes.xyz")))

        self.helpAction = QAction(QIcon(':/plugins/qrave_toolbar/Help.png'),
                                  self.tr('Help'), self.iface.mainWindow())
        self.helpAction.triggered.connect(lambda: QDesktopServices.openUrl(
            QUrl("http://rave.riverscapes.xyz")))

        self.raveOptionsAction = QAction(
            QIcon(':/plugins/qrave_toolbar/Options.png'), self.tr('Settings'),
            self.iface.mainWindow())
        self.raveOptionsAction.triggered.connect(self.options_load)

        self.net_sync_action = QAction(
            QIcon(':/plugins/qrave_toolbar/refresh.png'),
            self.tr('Update resources'), self.iface.mainWindow())
        self.net_sync_action.triggered.connect(
            lambda: self.net_sync_load(force=True))

        self.find_resources_action = QAction(
            QIcon(':/plugins/qrave_toolbar/BrowseFolder.png'),
            self.tr('Find Resources folder'), self.iface.mainWindow())
        self.find_resources_action.triggered.connect(self.locateResources)

        self.about_action = QAction(
            QIcon(':/plugins/qrave_toolbar/RaveAddIn_16px.png'),
            self.tr('About QRAVE'), self.iface.mainWindow())
        self.about_action.triggered.connect(self.about_load)

        m.addAction(self.helpAction)
        # m.addAction(self.websiteAction)
        m.addAction(self.raveOptionsAction)
        m.addAction(self.net_sync_action)
        m.addSeparator()
        m.addAction(self.find_resources_action)
        m.addAction(self.about_action)
        self.helpButton.setDefaultAction(self.helpAction)

        self.toolbar.addAction(self.openAction)
        self.toolbar.addAction(self.openProjectAction)
        self.toolbar.addWidget(self.helpButton)

        # Do a check to see if the stored version is different than the current version
        lastVersion = self.settings.getValue('pluginVersion')

        # This does a lazy netsync (i.e. it will run it if it feels like it)
        versionChange = lastVersion != __version__
        self.net_sync_load(force=versionChange)

        if versionChange:
            QgsMessageLog.logMessage(
                "Version change detected: {} ==> {}".format(
                    lastVersion, __version__),
                'QRAVE',
                level=Qgis.Info)
            self.settings.setValue('pluginVersion', __version__)

    def onProjectLoad(self, doc):
        # If the project has the plugin enabled then restore it.
        qrave_enabled, type_conversion_ok = self.qproject.readEntry(
            CONSTANTS['settingsCategory'], 'enabled')
        if type_conversion_ok and qrave_enabled == '1':
            self.toggle_widget(forceOn=True)
            if self.dockwidget is not None:
                self.dockwidget.reload_tree()

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        if self.metawidget is not None:
            self.metawidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.hide()

        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
        self.qproject.readProject.disconnect(self.onProjectLoad)
        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        self.dockwidget = None

        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        if self.metawidget is not None:
            self.metawidget.hide()
        if self.dockwidget is not None:
            self.dockwidget.hide()

        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Riverscapes Plugin (QRAVE)'), action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def toggle_widget(self, forceOn=False):
        """Toggle the widget open and closed when clicking the toolbar"""
        if not self.pluginIsActive:
            self.pluginIsActive = True

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget is None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = QRAVEDockWidget()
                self.metawidget = QRAVEMetaWidget()
                # Hook metadata changes up to the metawidget
                self.dockwidget.metaChange.connect(self.metawidget.load)

                # Run a network sync operation to get the latest stuff. Don't force it.
                #  This is just a quick check
                self.net_sync_load()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.metawidget)
            self.dockwidget.show()

        else:
            if self.dockwidget is not None:
                if self.dockwidget.isHidden():
                    self.dockwidget.show()
                elif forceOn is False:
                    self.dockwidget.hide()

        # The metawidget always starts hidden
        if self.metawidget is not None:
            self.metawidget.hide()

        if self.dockwidget is not None and not self.dockwidget.isHidden():
            self.qproject.writeEntry(CONSTANTS['settingsCategory'], 'enabled',
                                     True)
        else:
            self.qproject.removeEntry(CONSTANTS['settingsCategory'], 'enabled')

    def net_sync_load(self, force=False):
        """
        Periodically check for new files
        """

        lastDigestSync = self.settings.getValue('lastDigestSync')
        lastVersion = self.settings.getValue('pluginVersion')

        currTime = int(time())  # timestamp in seconds
        plugin_init = self.settings.getValue('initialized')
        autoUpdate = self.settings.getValue('autoUpdate')

        self.netsync = NetSync('Sync QRAVE resource files')

        perform_sync = False

        # setting the force flag overrides everything else
        if force:
            perform_sync = True

        # Otherwise you only get a sync if 'autoUpdate' is turned on
        elif autoUpdate:
            # If this is an old version or the plugin is uninitialized
            if not plugin_init or lastVersion != __version__ or self.netsync.need_sync:
                perform_sync = True
            # If we haven't checked for more than `digestSyncFreqHours` hours
            elif isinstance(lastDigestSync, int) \
                    and ((currTime - lastDigestSync) / 3600) > CONSTANTS['digestSyncFreqHours']:
                perform_sync = True

        if perform_sync is False:
            self.netsync = None
            return

        # Trigger the dockwidget to repaint after the netsync
        if self.dockwidget is not None:
            self.netsync.taskCompleted.connect(self.dockwidget.reload_tree)

        # FOR DEBUGGING ONLY. NEVER IN PRODUCTION
        # self.netsync.run()

        # COMMENT THIS OUT AND USE THE LINE ABOVE FOR SYNCHRONOUS DEBUGGING
        self.tm.addTask(self.netsync)

    def projectBrowserDlg(self):
        """
        Browse for a project directory
        :return:
        """
        last_browse_path = self.settings.getValue('lastBrowsePath')
        last_dir = os.path.dirname(
            last_browse_path) if last_browse_path is not None else None

        dialog_return = QFileDialog.getOpenFileName(
            self.dockwidget, "Open a Riverscapes project", last_dir,
            self.tr("Riverscapes Project files (project.rs.xml)"))
        if dialog_return is not None and dialog_return[
                0] != "" and os.path.isfile(dialog_return[0]):
            # We set the proect path in the project settings. This way it will be saved with the QgsProject file
            if self.dockwidget is None or self.dockwidget.isHidden() is True:
                self.toggle_widget(forceOn=True)
            self.dockwidget.add_project(dialog_return[0])

    def locateResources(self):
        """This the OS-agnostic "show in Finder" or "show in explorer" equivalent
        It should open the folder of the item in question

        Args:
            fpath (str): [description]
        """
        qurl = QUrl.fromLocalFile(RESOURCES_DIR)
        QDesktopServices.openUrl(qurl)

    def options_load(self):
        """
        Open the options/settings dialog
        """
        dialog = OptionsDialog()
        if self.dockwidget:
            dialog.dataChange.connect(self.dockwidget.dataChange)
        dialog.exec_()

    def about_load(self):
        """
        Open the About dialog
        """
        dialog = AboutDialog()
        if self.acknowledgements is None:
            self.acknowledgements = requests.get(
                'http://rave.riverscapes.xyz/dotnetack.html').text

        dialog.acknowledgements.setText(self.acknowledgements)
        dialog.exec_()
예제 #8
0
class QWaterPlugin(object):
    # Store settings in QGIS projects under this key
    SETTINGS = "QWater"  #"ghydraulics""QWater"

    def __init__(self, iface):
        # save reference to the QGIS interface
        self.iface = iface

        # Create the dialog (after translation) and keep reference
        self.dlg = QWaterSettingsDialog()  #QWater_SettingsDialog()
        #self.dlg.setWindowModality( Qt.WindowStaysOnTopHint ) #ApplicationModal
        self.dlg.setWindowFlag(Qt.WindowStaysOnTopHint)
        self.VazaoClasse = QWater_02Flow()
        self.common = QWater_00Common()
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        try:
            pluginMetadata = configparser.ConfigParser()
            pluginMetadata.read(os.path.join(self.plugin_dir, 'metadata.txt'))
            self.VERSION = pluginMetadata.get('general', 'version')
            '''
            from qgis.gui import QgsPluginManagerInterface
            plugInter = iface.pluginManagerInterface()
            #plugInter.showPluginManager()
            meta = plugInter.pluginMetadata(self.SETTINGS)#'QWater'
            self.VERSION = meta['version_installed']
            '''
        except:
            self.VERSION = "3.0.0"

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'QWater_{}.qm'.format(locale))

        if os.path.exists(locale_path):  #se n for pt traduz pra ingles
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
        QgsMessageLog.logMessage(
            'Qt:{} QWater:{} Lng: {}'.format(qVersion(), self.VERSION, locale),
            self.SETTINGS, Qgis.Info)

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate(QWaterPlugin.SETTINGS, message)

    def initGui(self):
        # create actions
        defIconPath = ":/plugins/QWater/icons/qwater.svg"
        self.action = QAction(QIcon(':/plugins/QWater/icons/sizing.svg'),
                              'Calculate economic diameters',
                              self.iface.mainWindow())
        self.action.setWhatsThis(
            "Calculate economic pipe diameters based on flow data.")
        self.settingsAction = QAction(
            QIcon(':/plugins/QWater/icons/00settings.svg'), 'Settings',
            self.iface.mainWindow())
        self.makeModelAction = QAction(
            QIcon(':/plugins/QWater/icons/makemodel.svg'), 'Make Model',
            self.iface.mainWindow())
        self.fillFieldsAction = QAction(
            QIcon(':/plugins/QWater/icons/fields_fill.svg'), 'Fill up Fields',
            self.iface.mainWindow())
        self.writeInpAction = QAction(
            QIcon(':/plugins/QWater/icons/epanet.svg'),
            'Write EPANET INP file', self.iface.mainWindow())
        self.runEpanetAction = QAction(QIcon(':/plugins/QWater/icons/run.svg'),
                                       'Run EPANET simulation',
                                       self.iface.mainWindow())
        self.aboutAction = QAction(
            QIcon(":/plugins/QWater/icons/qwater.svg"),
            QCoreApplication.translate('GHydraulics', "&About"),
            self.iface.mainWindow())

        self.LoadStylesAction = QAction(
            QIcon(":/plugins/QWater/icons/style.svg"), "Load default styles",
            self.iface.mainWindow())
        self.GetElevationAction = QAction(
            QIcon(":/plugins/QWater/icons/getelevation.svg"),
            "Get Elevation from Raster", self.iface.mainWindow())
        self.vazaoAction = QAction(QIcon(':/plugins/QWater/icons/01vazao.svg'),
                                   self.tr('Calc Flow'),
                                   self.iface.mainWindow())
        self.renameAction = QAction(
            QIcon(':/plugins/QWater/icons/01rename.svg'), 'Renumber Network',
            self.iface.mainWindow())
        self.updateDN_Action = QAction(
            QIcon(":/plugins/QWater/icons/qwater.svg"), "Update DN field",
            self.iface.mainWindow())

        # Connect actions to triggers
        self.action.triggered.connect(self.run)
        self.settingsAction.triggered.connect(self.showSettings)
        self.makeModelAction.triggered.connect(self.makeModel)
        self.fillFieldsAction.triggered.connect(self.fillFields)
        self.writeInpAction.triggered.connect(self.writeInpFile)
        self.GetElevationAction.triggered.connect(self.GetElevation)
        self.updateDN_Action.triggered.connect(self.update_DN)

        self.runEpanetAction.triggered.connect(self.runEpanet)
        self.aboutAction.triggered.connect(self.about)

        self.RenameClasse = Rename_Tools(self.iface)
        self.renameAction.triggered.connect(self.RenameCall)

        Qwflow = QWater_02Flow().CalcFlow
        self.vazaoAction.triggered.connect(
            self.VazaoClasse.CalcFlow
        )  #self.Vazao #ListNoDemandNodes #QWater_02Flow.CalcFlow

        self.LoadStylesAction.triggered.connect(self.LoadStyles)

        #Create toolbar
        self.toolbar = self.iface.addToolBar('&QWater')
        self.toolbar.setObjectName('&QWater')

        # add toolbar buttons
        self.toolbar.addAction(self.settingsAction)
        self.toolbar.addAction(self.makeModelAction)
        self.toolbar.addAction(self.renameAction)
        self.toolbar.addAction(self.fillFieldsAction)
        self.toolbar.addAction(self.vazaoAction)
        self.toolbar.addAction(self.action)
        self.toolbar.addAction(self.runEpanetAction)
        #self.iface.addToolBarIcon(self.settingsAction)

        #Add separator
        self.toolbar.addSeparator()

        # Add ToolButton (with Menu)
        self.menuButton = QToolButton()  #QPushButton()#QToolButton
        self.menuButton.setMenu(QMenu())
        self.menuButton.setPopupMode(QToolButton.MenuButtonPopup)
        # self.menuButton.setAutoRaise(True)

        m = self.menuButton.menu()
        m.addAction(self.LoadStylesAction)
        m.addAction(self.writeInpAction)
        m.addAction(self.GetElevationAction)
        m.addAction(self.updateDN_Action)

        self.menuButton.setDefaultAction(self.GetElevationAction)
        self.menuButtonAction = self.toolbar.addWidget(self.menuButton)

        # add menu items
        self.iface.addPluginToMenu("&QWater", self.settingsAction)
        self.iface.addPluginToMenu('&QWater', self.makeModelAction)
        self.iface.addPluginToMenu('&QWater', self.renameAction)
        self.iface.addPluginToMenu('&QWater', self.fillFieldsAction)
        self.iface.addPluginToMenu('&QWater', self.vazaoAction)
        self.iface.addPluginToMenu("&QWater", self.action)
        self.iface.addPluginToMenu('&QWater', self.runEpanetAction)

        # tools submenu
        self.tools_menu = QMenu('&Tools')
        self.tools_menu.addAction(self.LoadStylesAction)
        self.tools_menu.addAction(self.writeInpAction)
        self.tools_menu.addAction(self.GetElevationAction)
        self.tools_menu.addAction(self.updateDN_Action)

        # Projects submenu
        self.project_menu = QMenu('&Projects')

        self.newProjectAction = QAction(self.iface.actionNewProject().icon(),
                                        'New Project', self.iface.mainWindow())
        self.newProjectAction.triggered.connect(self.newProject)
        self.project_menu.addAction(self.newProjectAction)

        self.sampleDwCmdAction = QAction(
            QIcon(':/python/plugins/ghydraulic/icon.xpm'),
            'Sample Darcy-Weisbach, cubic meters/day', self.iface.mainWindow())
        self.sampleDwCmdAction.triggered.connect(self.openDwCmdSample)
        self.project_menu.addAction(self.sampleDwCmdAction)

        self.sampleDwLpsAction = QAction(
            QIcon(':/python/plugins/ghydraulic/icon.xpm'),
            'Sample Darcy-Weisbach, liters/second', self.iface.mainWindow())
        self.sampleDwLpsAction.triggered.connect(self.openDwLpsSample)
        self.project_menu.addAction(self.sampleDwLpsAction)

        self.sampleHwGpmAction = QAction(
            QIcon(':/python/plugins/ghydraulic/icon.xpm'),
            'Sample Hazen-Williams, gallons/min', self.iface.mainWindow())
        self.sampleHwGpmAction.triggered.connect(self.openHwGpmSample)
        self.project_menu.addAction(self.sampleHwGpmAction)

        # Back in main menu
        self.iface.addPluginToMenu("&QWater", self.tools_menu.menuAction())
        self.iface.addPluginToMenu("&QWater", self.project_menu.menuAction())
        self.iface.addPluginToMenu("&QWater", self.aboutAction)

    def unload(self):
        # remove the plugin menu item and icon
        self.iface.removePluginMenu("&QWater", self.aboutAction)
        self.iface.removePluginMenu('&QWater', self.runEpanetAction)
        self.iface.removePluginMenu("&QWater", self.writeInpAction)
        self.iface.removePluginMenu("&QWater", self.GetElevationAction)
        self.iface.removePluginMenu("&QWater", self.LoadStylesAction)
        self.iface.removePluginMenu("&QWater", self.updateDN_Action)

        self.iface.removePluginMenu('&QWater', self.vazaoAction)
        self.iface.removePluginMenu('&QWater', self.makeModelAction)
        self.iface.removePluginMenu('&QWater', self.fillFieldsAction)
        self.iface.removePluginMenu('&QWater', self.renameAction)
        self.iface.removePluginMenu("&QWater", self.settingsAction)
        self.iface.removePluginMenu("&QWater", self.action)
        self.iface.removePluginMenu("&QWater", self.project_menu.menuAction())
        self.iface.removePluginMenu("&QWater", self.tools_menu.menuAction())
        self.iface.removeToolBarIcon(self.settingsAction)
        self.toolbar.removeAction(self.settingsAction)
        self.toolbar.removeAction(self.LoadStylesAction)
        self.toolbar.removeAction(self.GetElevationAction)
        self.toolbar.removeAction(self.updateDN_Action)

        self.toolbar.removeAction(self.vazaoAction)
        self.toolbar.removeAction(self.runEpanetAction)
        self.toolbar.removeAction(self.action)
        self.toolbar.removeAction(self.renameAction)

        # remove the toolbar
        del self.toolbar

    def RenameCall(self):
        self.RenameClasse.initGui()

    def fillFields(self):
        proj = QgsProject.instance()
        autolen = proj.readEntry(QWaterPlugin.SETTINGS, 'autolength', "0")[0]
        undefs = False
        preencheu = False
        fillCOLUMNS = {
            'JUNCTIONS': {
                'ELEVATION': 0
            },
            'PIPES': {
                'LENGTH': 'CALCULA',
                'DIAMETER': 54.6,
                'ROUGHNESS': 1,
                'MINORLOSS': 0,
                'STATUS': 'OPEN'
            }
        }
        for secao in ['PIPES', 'JUNCTIONS']:
            vLayer = self.common.PegaQWaterLayer(secao)
            if vLayer != False:
                feicoes = vLayer.getFeatures()
                vLayer.startEditing()
                for feicao in feicoes:
                    camposPadroes = fillCOLUMNS[secao]
                    for (campo, valorPad) in camposPadroes.items():
                        featVal = feicao[campo]
                        if campo == 'LENGTH' and autolen == '1':
                            ext = feicao.geometry().length()
                            feicao[campo] = ext
                            preencheu = True
                        else:
                            if featVal == NULL or featVal is None:
                                feicao[campo] = valorPad
                                preencheu = True
                    vLayer.updateFeature(feicao)
            else:
                undefs = True
#        self.warning('Fill Fields call not working yet')
        if not undefs:
            if preencheu:
                self.warning('Successfull fill in!', Qgis.Info)
            else:
                self.warning('Nothing to fill in!', Qgis.Info)

    # Calculate economic diameters
    def run(self):
        # Check for "LPS" flow units
        dlg = self.dlg  #GHydraulicsSettingsDialog()
        template = dlg.getTemplate()
        inp = GHydraulicsInpReader(template)
        inpunits = inp.getValue('OPTIONS', 'Units').upper()
        if inpunits != EpanetModel.LPS:
            self.warning(
                '"Calculate economic diameters" requires "LPS" flow units instead of "'
                + inpunits + '". Please change the template INP file.')
            return

        maker = GHydraulicsModelMaker(template)
        self.checkModel(maker)

        # Let user agree to the change
        selectedbutton = QMessageBox.question(
            self.iface.mainWindow(), self.SETTINGS,
            "This will overwrite all DIAMETER and ROUGHNESS field values using Pipes Table data from settings Dialog. Do you want to continue?",
            QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel)
        if QMessageBox.Cancel == selectedbutton:
            return

        # Execute the action
        ecodia = GhyEconomicDiameter(GHydraulicsModel.RESULT_FLO,
                                     EpanetModel.DIAMETER)
        maker.beginEditCommand('Calculate economic diameters')
        try:
            maker.eachLayer(ecodia.commitEconomicDiametersForLayer,
                            [EpanetModel.PIPES])
        except GHydraulicsException as e:
            self.warning(str(e))
        maker.endEditCommand()
        self.update_DN()

    # Display the About dialog
    def about(self):
        infoString = self.tr(
            self.SETTINGS + " Plugin " + self.VERSION +
            "<br />This plugin integrates EPANET with QGIS.<br />Copyright (c) 2017 - 2017 Jorge Almerio<br /><a href=\"https://github.com/jorgealmerio/QWater/blob/master/README.md\">github.com/jorgealmerio/QWater</a>\n"
        )
        QMessageBox.information(self.iface.mainWindow(),
                                "About " + self.SETTINGS, infoString)

    # Display the settings dialog
    def showSettings(self):
        dlg = self.dlg  #QWaterSettingsDialog()
        proj = QgsProject.instance()
        layers = proj.mapLayers()
        hasVectorLayers = False

        msgs = ''
        QWaterEntries = proj.entryList(QWaterPlugin.SETTINGS, '')
        GhydraulicsEntries = proj.entryList('ghydraulics', '')
        # Restore selected layers
        for secao in EpanetModel.GIS_SECTIONS:
            #Create QgsMapLayerComboBox filters
            widget = dlg.findChild(QgsMapLayerComboBox, 'CMB' + secao)
            if secao in GHydraulicsModel.NODE_SECTIONS:
                widget.setFilters(QgsMapLayerProxyModel.PointLayer)
            else:
                if secao == 'ZONES':
                    widget.setFilters(QgsMapLayerProxyModel.PolygonLayer)
                else:
                    widget.setFilters(QgsMapLayerProxyModel.LineLayer)
            widget.setAllowEmptyLayer(
                True
            )  #added in QGIS 3.0: Sets whether an optional empty layer ("not set") option is shown in the combo box
            #Read and restore file Entries
            if secao in QWaterEntries:
                lyrName = proj.readEntry(QWaterPlugin.SETTINGS, secao, "")[0]
                layerEntry = proj.mapLayersByName(lyrName)
                if layerEntry:
                    widget.setLayer(layerEntry[0])
                    msgs += '\n{}:{} -> QWater Layer found'.format(
                        secao, lyrName)
                else:
                    msgs += '\n{}:{} -> QWater Layer NOT found'.format(
                        secao, lyrName)
                    widget.setLayer(None)
            elif secao in GhydraulicsEntries:  #if has Not QWater settings try to get ghydraulics settings
                pickle_list = str(proj.readEntry('ghydraulics', secao, "")[0])
                if '' != pickle_list:
                    # Windows QGIS injects some carriage returns here
                    pickle_list = pickle_list.replace(
                        '\r', '').encode()  #use encode convet to byte
                    try:
                        l = loads(pickle_list)
                        valor = l
                        if valor:
                            layerEntry = proj.mapLayersByName(valor[0])
                            if layerEntry:
                                widget.setLayer(layerEntry[0])
                                msgs += '\n{}:{} -> GHydraulics Layer found'.format(
                                    secao, layerEntry[0].name())
                            else:
                                widget.setLayer(None)
                                msgs += '\n{}:{} -> GHydraulics Layer NOT found'.format(
                                    secao, valor[0])
                        else:
                            widget.setLayer(None)
                            msgs += '\n{} -> GHydraulics Previous Settings Null'.format(
                                secao)
                    except (KeyError):
                        widget.setLayer(None)
                        # fix_print_with_import
                        print('Error on section:' + secao)
                        continue
            else:
                msgs += '\n{} -> Previous Settings NOT found'.format(secao)
                widget.setLayer(None)

        #if msgs!='':
        #    print msgs

        # Restore template inp file
        template = dlg.getTemplate()
        dlg.ui.inpFileLineEdit.setText(template)
        # Restore auto length checkbox
        dlg.ui.autoLengthCB.setChecked(dlg.getAutoLength())
        # Restore backdrop checkbox
        dlg.ui.writeBackdropCB.setChecked(dlg.getWriteBackdrop())

        # Restore data variables
        dataDefs = QWaterModel.DATA_DEFS
        for dataDf, defVal in dataDefs.items():
            #Get widget
            widget = dlg.findChild(QLineEdit, 'Txt_' + dataDf)
            inVar = proj.readEntry(QWaterPlugin.SETTINGS, dataDf, defVal)[0]
            widget.setText(inVar)

        #Carrega Tubos
        tubosMat = proj.readEntry(QWaterPlugin.SETTINGS, "TUBOS_MAT", "0")[0]
        if tubosMat == '0':  #se nao tiver lista de materiais definidas carrega o padrao do modelo
            tubos = QWaterModel.TUBOS_MAT
        else:
            tubos = eval(tubosMat)
            if not isinstance(tubos[0][0], str):
                QgsMessageLog.logMessage('Wrong Pipes settings' + tubosMat,
                                         self.SETTINGS,
                                         Qgis.Warning)  #Show Warning Message
                tubos = QWaterModel.TUBOS_MAT
            #else:
            #QgsMessageLog.logMessage('Right Pipes settings'+tubosMat,self.SETTINGS,Qgis.Info) #Show Info Message
        self.carregaTabMats(tubos)

        # Exibe o resumo de extensoes de rede se tiver PIPES definido
        ProjVar = proj.readEntry(QWaterPlugin.SETTINGS, 'PIPES')[0]

        if ProjVar != '':
            try:
                myLayer = proj.mapLayersByName(ProjVar)[0]
                tot, geo = QWater_00Common().CompRealGeom(myLayer)

                msgTxt = self.tr(
                    u'<span style=" color:#0000ff;">Geometric Length: {0:.2f} m</span>'
                ).format(geo)
                dlg.ui.lbl_extGeo.setText(msgTxt)
                msgTxt = ''

                if tot > 0:
                    msgTxt = self.tr(
                        u'<span style=" color:#37c322;">Length Field Sum: {0:.2f} m</span>'
                    ).format(tot)
                dlg.ui.lbl_extReal.setText(msgTxt)
                msgTxt = ''
            except:
                pass

        #Call Combobox Zones activated signal to refresh it
        cmbZones = dlg.ui.CMBZONES
        cmbZones.activated.emit(cmbZones.currentIndex())

        dlg.ui.Txt_POPINI.editingFinished.emit()
        # show the dialog
        dlg.show()
        #for i in range(0, dlg.UNUSED_ITEM+1):
        #    dlg.ui.treeWidget.topLevelItem(i).setExpanded(True)
        #result = dlg.exec_()
        result = dlg.exec_()
        if result:
            self.accepted()

    def accepted(self):
        # Store layers
        dlg = self.dlg  #QWaterSettingsDialog()
        proj = QgsProject.instance()
        for secao in EpanetModel.GIS_SECTIONS:
            #Get QgsMapLayerComboBoxs
            widget = dlg.findChild(QgsMapLayerComboBox, 'CMB' + secao)
            curlyr = widget.currentLayer()
            if not (curlyr is None):
                lyrName = curlyr.name()
            else:
                lyrName = ''
            #print secao,widget,lyrName
            proj.writeEntry(self.SETTINGS, secao, lyrName)

        #proj.writeEntry("ghydraulics",EpanetModel.GIS_SECTIONS[i], dumps(layers))
        # Store Inp file
        templatedir = os.path.join(os.path.dirname(__file__), 'etc')
        template = str(dlg.ui.inpFileLineEdit.text()).replace(
            templatedir + os.path.sep, '')
        proj.writeEntry(self.SETTINGS, "templateinpfile", template)
        # Store auto length configuration
        autoLength = dlg.STRING_FALSE
        if dlg.ui.autoLengthCB.isChecked():
            autoLength = dlg.STRING_TRUE
        proj.writeEntry(self.SETTINGS, dlg.AUTO_LENGTH, autoLength)
        # Store backdrop configuration
        writeBackdrop = dlg.STRING_FALSE
        if dlg.ui.writeBackdropCB.isChecked():
            writeBackdrop = dlg.STRING_TRUE
        proj.writeEntry(self.SETTINGS, dlg.WRITE_BACKDROP, writeBackdrop)

        # Store data variables
        dataDefs = QWaterModel.DATA_DEFS
        for dataDf, defVal in dataDefs.items():
            #Get widget
            widget = dlg.findChild(QLineEdit, 'Txt_' + dataDf)
            inVar = widget.text()
            proj.writeEntry(QWaterPlugin.SETTINGS, dataDf, inVar)

        proj.writeEntry(QWaterPlugin.SETTINGS, "TUBOS_MAT",
                        str(self.tableToArray()))

    # Display a message once
    def explainOnce(self, key, title, message):
        proj = QgsProject.instance()
        if GHydraulicsModel.STRING_TRUE == str(
                proj.readEntry(QWaterPlugin.SETTINGS, key)[0]):
            return True
        reply = QMessageBox.question(self.iface.mainWindow(), title, message,
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.Yes)
        if QMessageBox.Yes == reply:
            proj.writeEntry(QWaterPlugin.SETTINGS, key,
                            GHydraulicsModel.STRING_TRUE)
            return True
        return False

    # Check if all fields are in place
    def checkModel(self, maker):
        checker = maker.checker
        if 0 == checker.getLayerCount(
                EpanetModel.JUNCTIONS) or 0 == checker.getLayerCount(
                    EpanetModel.PIPES):
            question = 'Your junction and/or pipe layer configuration is incomplete. Do you want configure the layers now?'
            reply = QMessageBox.question(self.iface.mainWindow(),
                                         GHydraulicsModelChecker.TITLE,
                                         question,
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                self.showSettings()
            if 0 == checker.getLayerCount(
                    EpanetModel.JUNCTIONS) or 0 == checker.getLayerCount(
                        EpanetModel.PIPES):
                return False
        self.checkForModifications(checker)
        missing = checker.checkFields()
        if 0 < len(missing):
            fieldlist = []
            for name in list(missing.keys()):
                fieldlist.append('<br/>Layer "' + name + '": ' +
                                 ', '.join(missing[name]))
            message = 'Your model is missing some fields.' + ''.join(
                fieldlist) + '<br/>Would you like to add them?'
            reply = QMessageBox.question(self.iface.mainWindow(),
                                         GHydraulicsModelChecker.TITLE,
                                         message,
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.Yes)
            if QMessageBox.Yes != reply:
                return False
            if not checker.addFields(missing):
                QMessageBox.critical(self.iface.mainWindow(),
                                     GHydraulicsModelChecker.TITLE,
                                     'Not all fields could be added.',
                                     QMessageBox.Ok)
                return False
        crss = checker.getCrsDictionary()
        if 1 != len(crss):
            message = 'Your model uses more than one coordinate reference system. Please use only one.'
            QMessageBox.critical(self.iface.mainWindow(),
                                 GHydraulicsModelChecker.TITLE, message,
                                 QMessageBox.Ok, QMessageBox.Ok)
            return False

        missing = checker.checkIds()
        if 0 < len(missing):
            question = 'There are ' + str(
                len(missing)
            ) + ' duplicate ' + GHydraulicsModel.ID_FIELD + ' values. Do want to fix this automatically now?'
            reply = QMessageBox.question(self.iface.mainWindow(),
                                         GHydraulicsModelChecker.TITLE,
                                         question,
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.Yes)
            if QMessageBox.Yes != reply:
                return False
            if not maker.enforceUniqueIds():
                return False
        multis = checker.getMultipartCount()
        if 0 < multis:
            question = 'There are ' + str(
                multis
            ) + ' pipes with multipart geometries possibly causing problems. Do you want to explode them now?'
            reply = QMessageBox.question(self.iface.mainWindow(),
                                         GHydraulicsModelChecker.TITLE,
                                         question,
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.Yes)
            if QMessageBox.Yes == reply:
                maker.explodeMultipartPipes()

    # Fill the node1, node2 fields
    def makeModel(self):
        if self.common.PegaQWaterLayer('PIPES') == False:
            return
        dlg = self.dlg  #GHydraulicsSettingsDialog()
        template = dlg.getTemplate()
        maker = GHydraulicsModelMaker(template)
        self.iface.mainWindow().statusBar().showMessage(
            'Checking EPANET model')
        self.checkModel(maker)
        question = 'Overwrite the fields NODE1 and NODE2 in all line tables?'
        self.iface.mainWindow().statusBar().showMessage("Making EPANET model")
        autolength = dlg.getAutoLength()
        if autolength:
            question = 'Overwrite the fields NODE1, NODE2 and LENGTH in all line tables?'
        if self.explainOnce('makeModelExplanation', 'Make EPANET Model',
                            question):
            vcount = maker.make()
            if 0 < vcount:
                reply = QMessageBox.question(
                    self.iface.mainWindow(), GHydraulicsModelChecker.TITLE,
                    'Your model is missing ' + str(vcount) +
                    ' junctions. Would you like to add them now?',
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if QMessageBox.Yes == reply:
                    self.iface.mainWindow().statusBar().showMessage(
                        'Adding missing junctions to EPANET model')
                    maker.addMissingJunctions()
                    lyrJunctions = self.common.PegaQWaterLayer('JUNCTIONS')
                    lyrJunctions.triggerRepaint()
            #dlg = GHydraulicsSettingsDialog()
            if autolength:
                self.iface.mainWindow().statusBar().showMessage(
                    'Pipe length calculation')
                maker.calculateLength()
            maker.cleanup()
        self.iface.mainWindow().statusBar().showMessage('')

    # Prevent problems with unsaved data
    def checkForModifications(self, checker):
        modified = checker.getModifiedLayers()
        if 0 < len(modified):
            message = 'Some of your model layers have not been saved (' + ', '.join(
                modified) + ').<br/>Do you want to save them now?'
            reply = QMessageBox.question(self.iface.mainWindow(),
                                         GHydraulicsInpWriter.TITLE, message,
                                         QMessageBox.Yes | QMessageBox.No,
                                         QMessageBox.Yes)
            if QMessageBox.Yes == reply:
                checker.commitChanges()

    # Write out a file in EPANET INP format
    # returns True on success, False on failure
    def writeInpFile(self):
        # Modified layers may not be exprted correctly
        self.menuButton.setDefaultAction(
            self.writeInpAction)  #Change default toolbutton to writeInpAction
        checker = GHydraulicsModelChecker()
        self.checkForModifications(checker)
        # select a file
        prjfi = os.path.splitext(QgsProject.instance().fileName())[0] + '.inp'
        f, __ = QFileDialog.getSaveFileName(self.iface.mainWindow(),
                                            GHydraulicsInpWriter.TITLE, prjfi,
                                            'EPANET INP file (*.inp)')

        if 0 < len(f):
            dlg = self.dlg  #GHydraulicsSettingsDialog()
            template = dlg.getTemplate()
            try:
                writer = GHydraulicsInpWriter(template, self.iface)
                writeBackdrop = dlg.getWriteBackdrop()
                if writeBackdrop:
                    backdropfile = writer.getBackdropFromInp(str(f))
                    question = 'Overwrite ' + os.path.basename(
                        backdropfile) + '?'
                    if os.path.exists(backdropfile) and not self.explainOnce(
                            'overwriteBackdrop', GHydraulicsInpWriter.TITLE,
                            question):
                        writeBackdrop = False
                writer.write(f, writeBackdrop)
            except GHydraulicsException as e:
                self.warning('Saving an INP file failed: ' + str(e))
                return False
            return True
        return False

    # Open CMD sample project
    def openDwCmdSample(self):
        self.iface.addProject(
            os.path.dirname(__file__) + '/samples/d-w/cmd/ghydraulics.qgs')

    # Open LPS sample project
    def openDwLpsSample(self):
        self.iface.addProject(
            os.path.dirname(__file__) + '/samples/d-w/lps/qwater_lps.qgs')

    # Open Net1 sample project
    def openHwGpmSample(self):
        self.iface.addProject(
            os.path.dirname(__file__) + '/samples/h-w/gpm/Net1.qgs')

    # Display message
    def warning(self, message, nivel=Qgis.Warning):
        self.iface.messageBar().pushMessage(self.SETTINGS,
                                            message,
                                            level=nivel,
                                            duration=4)

    # Create a new project, save and configure layers
    def newProject(self):
        self.iface.newProject()
        project = QgsProject.instance()
        crs = project.crs()  #TODO: Solicitar crs ao usuario
        baseName = project.readPath("./")
        for name in EpanetModel.GIS_SECTIONS:
            lname = name.lower()
            #self.iface.mainWindow()
            f, __ = QFileDialog.getSaveFileName(
                caption='Save new ' + lname + ' layer',
                directory=baseName + '/' + lname + '.shp',
                filter='ESRI Shapefile (*.shp)')
            if 0 == len(f):
                continue
            baseName = os.path.split(f)[0]
            fields = QgsFields()
            for i in range(0, len(EpanetModel.COLUMNS[name])):
                field = EpanetModel.COLUMNS[name][i]
                fields.append(
                    QgsField(field, GHydraulicsModel.COLUMN_TYPES[field]))
            geometrytype = QgsWkbTypes.LineString if EpanetModel.PIPES == name else QgsWkbTypes.Point
            writer = QgsVectorFileWriter(f, 'System', fields, geometrytype,
                                         crs, 'ESRI Shapefile')
            if writer.hasError() != QgsVectorFileWriter.NoError:
                self.warning('Error creating shapefile: ' +
                             str(writer.hasError()))
                continue
            del writer
            layer = self.iface.addVectorLayer(f, lname, 'ogr')
            if not layer.isValid():
                self.warning('Failed to load layer!')
                continue
            if not crs:
                crs = layer.crs()
            layers = [lname]
            project.writeEntry(self.SETTINGS, name, lname)
        self.LoadStyles()
        self.showSettings()

    def runEpanet(self):
        lyrPipe = self.common.PegaQWaterLayer('PIPES')
        if not lyrPipe:
            return
        # Get a temporary file
        t = tempfile.mkstemp(suffix='.inp')
        os.close(t[0])
        dlg = self.dlg  #self.dlg #GHydraulicsSettingsDialog()
        template = dlg.getTemplate()
        try:
            writer = GHydraulicsInpWriter(template, self.iface)
            writer.write(t[1], False)
        except GHydraulicsException as e:
            self.warning('Saving an INP file failed :' + str(e))
            return
        try:
            runner = GHydraulicsModelRunner()
            output, report, steps = runner.run(t[1])
            dlg = GHydraulicsResultDialog(runner.setStep)
            dlg.ui.textOutput.setText(output)
            dlg.ui.textReport.setText(report)
            dlg.ui.comboStep.clear()
            dlg.ui.comboStep.addItems([str(x) for x in range(1, steps + 1)])
            dlg.show()
            result = dlg.exec_()
        except GHydraulicsException as e:
            self.warning('Running a simulation failed :' + str(e))
        os.unlink(t[1])
        lyrPipe.triggerRepaint()

    def carregaTabMats(self, tbMats):
        tableWidget = self.dlg.findChild(QTableWidget, 'tableWidget')
        tableWidget.setRowCount(0)
        tableWidget.setColumnCount(0)
        for i, tbMat in enumerate(tbMats):
            row = tableWidget.rowCount()
            tableWidget.insertRow(row)
            tableWidget.setColumnCount(len(tbMat))
            if row < 1:
                tableWidget.setHorizontalHeaderLabels(tbMat)
            else:
                for column, data in enumerate(tbMat):
                    if column == 0:
                        cell_widget = QWidget()
                        lay_out = QHBoxLayout(cell_widget)
                        chk_bx = QCheckBox()
                        if data in [1, '1', 't', 'True']:
                            chk_bx.setCheckState(QtCore.Qt.Checked)
                        else:
                            chk_bx.setCheckState(QtCore.Qt.Unchecked)
                        lay_out.addWidget(chk_bx)
                        lay_out.setAlignment(Qt.AlignCenter)
                        lay_out.setContentsMargins(0, 0, 0, 0)
                        cell_widget.setLayout(lay_out)
                        tableWidget.setCellWidget(row, 0, cell_widget)
                    else:
                        item = QTableWidgetItem("{}".format(data))  #:7.2f
                        item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
                        tableWidget.setItem(row, column, item)
        #tableWidget.setHorizontalHeaderLabels(['On','DN','Diameter','Roughness','Pressure','Headloss','Reference'])
        #for i in range(1,4):
        #    tableWidget.resizeColumnToContents(i)
        tableWidget.removeRow(0)
        tableWidget.resizeColumnsToContents()

    def tableToArray(self):
        table = self.dlg.findChild(QTableWidget, 'tableWidget')
        result = [self.LeCabecalho(table)]
        num_rows, num_cols = table.rowCount(), table.columnCount()
        for row in range(num_rows):
            rows = []
            for col in range(num_cols):
                if col == 0:
                    cell_widget = table.cellWidget(row, col).findChild(
                        type(QCheckBox()))
                    if cell_widget.isChecked(
                    ):  #QTableWidget.item(row,column).checkState()==QtCore.Qt.Checked:
                        rows.append(1)
                    else:
                        rows.append(0)
                else:
                    item = table.item(row, col)
                    rows.append(item.text())  #if item else ''
            result.append(rows)
        return result

    def LeCabecalho(self, tblWid):
        header = []
        for column in range(tblWid.columnCount()):
            header.append(tblWid.horizontalHeaderItem(column).text())
        return header

    def LoadStyles(self):
        self.menuButton.setDefaultAction(self.LoadStylesAction)
        proj = QgsProject.instance()
        qStyles = {
            'PIPES': 'pipe_headloss.qml',
            'JUNCTIONS': 'node_pressure.qml',
            'PUMPS': 'node_pump.qml',
            'RESERVOIRS': 'node_reserv.qml',
            'TANKS': 'node_tank.qml',
            'VALVES': 'node_valve.qml'
        }  #{tipo:estilo}
        rootID = QWaterPlugin.SETTINGS
        for tipo, estilo in qStyles.items():
            ProjVar = proj.readEntry(rootID, tipo)[0]
            if ProjVar != '':
                myLayer = proj.mapLayersByName(ProjVar)[0]
                self.CarregaEstilo(myLayer, estilo)

    def CarregaEstilo(self, vLayer, Estilo):
        basepath = os.path.dirname(__file__)  #os.path.realpath(
        FullPath = os.path.join(basepath, 'style/' + Estilo)
        vLayer.loadNamedStyle(FullPath)
        vLayer.triggerRepaint()

    def GetElevation(self):
        self.menuButton.setDefaultAction(
            self.GetElevationAction
        )  #Change default toolbutton to GetElevationAction
        dlg = QDialog()
        dlg.setWindowTitle('Select Elevation Raster')

        #Combobox
        ml = QgsMapLayerComboBox()
        ml.setFilters(QgsMapLayerProxyModel.RasterLayer)

        #ButtonBox
        bb = QDialogButtonBox()
        bb.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        #layout
        layOut = QVBoxLayout()
        layOut.addWidget(ml)
        layOut.addWidget(bb)
        dlg.setLayout(layOut)
        dlg.setMinimumWidth(300)

        # Signals answers
        def ok():
            dlg.close()
            self.RasterSampling(ml.currentLayer())
            #curlyr = ml.currentLayer()
        def cancel():
            print('cancelled')
            dlg.close()

        #connect to signals
        bb.accepted.connect(ok)
        bb.rejected.connect(cancel)

        dlg.show()

    def RasterSampling(self, Raster):
        nodeLyr = self.common.PegaQWaterLayer('JUNCTIONS')
        if not nodeLyr:
            iface.messageBar().pushMessage(self.SETTINGS,
                                           'No Junction layer defined!',
                                           level=Qgis.Warning,
                                           duration=5)
            return
        noElevPtos = []
        nodeLyr.startEditing()
        for pto in nodeLyr.getFeatures():
            if pto.geometry().isMultipart():
                point = pto.geometry().asMultiPoint()[0]
            else:
                point = pto.geometry().asPoint()

            rastSample = Raster.dataProvider().identify(
                point, QgsRaster.IdentifyFormatValue).results()
            #previousRastSample = rastSample
            #value, ok = Raster.dataProvider().sample(point, 1)
            value = rastSample[1]
            if value:
                pto['ELEVATION'] = value
                #print(pto['DC_ID'],'=',value)
                nodeLyr.updateFeature(pto)
            else:
                noElevPtos.append(pto.id())
        if noElevPtos:
            #print(noElevPtos)
            nodeLyr.selectByIds(noElevPtos)
            mapCanvas = iface.mapCanvas()
            mapCanvas.zoomToSelected(nodeLyr)
            iface.messageBar().pushMessage(
                self.SETTINGS,
                'Check Selected features with No Elevation data!',
                level=Qgis.Warning,
                duration=0)
        else:
            iface.messageBar().pushMessage(
                self.SETTINGS,
                'Get elevation from Raster success!',
                level=Qgis.Info,
                duration=5)
        nodeLyr.triggerRepaint()

    def update_DN(self):
        self.menuButton.setDefaultAction(self.updateDN_Action)
        #Check and get Pipes Layer
        pipeLyr = self.common.PegaQWaterLayer('PIPES')
        if not pipeLyr:
            return

        #Check and create field 'DN' #NPS (Nominal Pipe Size)
        field_index = pipeLyr.fields().indexFromName('DN')
        pipeLyr.startEditing()
        if field_index == -1:
            #if field does not exist create it
            DNfld = QgsField("DN", QVariant.Int)
            pipeLyr.addAttribute(DNfld)
            pipeLyr.updateFields()
            field_index = pipeLyr.fields().indexFromName('DN')
            editSet = QgsEditorWidgetSetup('TextEdit',
                                           {})  #{'IsMultiline': 'True'}
            pipeLyr.setEditorWidgetSetup(field_index, editSet)
        #Carrega Tubos
        proj = QgsProject.instance()
        tubosMat = proj.readEntry(self.SETTINGS, "TUBOS_MAT", "0")[0]
        if tubosMat == '0':
            raise GHydraulicsException(
                'ERROR: Please, Define Pipes on settings dialog First!')
            #tubos=QWaterModel.TUBOS_MAT
        else:
            tubos = eval(tubosMat)
            if not isinstance(tubos[0][0], str):
                raise GHydraulicsException(
                    'ERROR: Incorrect Pipes definition!. Please, Define Pipes on settings dialog First!'
                )

        cabecalho = tubos[0]
        diaIdx = cabecalho.index('Diameter')
        dnIdx = cabecalho.index('DN')
        indices = [diaIdx, dnIdx]
        diaXdn = {}
        for linha in range(1, len(tubos)):
            diam = eval(tubos[linha][diaIdx])
            diaXdn[diam] = eval(tubos[linha][dnIdx])

        #diaXdn= [[each_list[i] for i in indices] for each_list in tubos]
        noDNdef = []
        #Update DN field
        for f in pipeLyr.getFeatures():
            diam = f['DIAMETER']
            #Check if Diameter exists in Pipes Table Setting
            if diam not in diaXdn:
                noDNdef.append(f.id())
            else:
                f['DN'] = diaXdn[diam]
                pipeLyr.updateFeature(f)
        pipeLyr.triggerRepaint()
        if noDNdef:
            pipeLyr.selectByIds(noDNdef)
            mapCanvas = iface.mapCanvas()
            mapCanvas.zoomToSelected(pipeLyr)
            iface.messageBar().pushMessage(
                self.SETTINGS,
                'Check Selected features with Diameters not in Pipes Table Setting or use Calculate economic Diameters tool!',
                level=Qgis.Warning,
                duration=0)
        else:
            iface.messageBar().pushMessage(self.SETTINGS,
                                           'DN success updated!',
                                           level=Qgis.Info,
                                           duration=3)
예제 #9
0
class FeatureSelectorWidget(QWidget):
    feature_identified = pyqtSignal(QgsFeature)

    def __init__(self, parent):
        QWidget.__init__(self, parent)

        edit_layout = QHBoxLayout()
        edit_layout.setContentsMargins(0, 0, 0, 0)
        edit_layout.setSpacing(2)
        self.setLayout(edit_layout)

        self.line_edit = QLineEdit(self)
        self.line_edit.setReadOnly(True)
        edit_layout.addWidget(self.line_edit)

        self.highlight_feature_button = QToolButton(self)
        self.highlight_feature_button.setPopupMode(QToolButton.MenuButtonPopup)
        self.highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionHighlightFeature.svg"),
            "Highlight feature", self)
        self.scale_highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionScaleHighlightFeature.svg"),
            "Scale and highlight feature", self)
        self.pan_highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionPanHighlightFeature.svg"),
            "Pan and highlight feature", self)
        self.highlight_feature_button.addAction(self.highlight_feature_action)
        self.highlight_feature_button.addAction(
            self.scale_highlight_feature_action)
        self.highlight_feature_button.addAction(
            self.pan_highlight_feature_action)
        self.highlight_feature_button.setDefaultAction(
            self.highlight_feature_action)
        edit_layout.addWidget(self.highlight_feature_button)

        self.map_identification_button = QToolButton(self)
        self.map_identification_button.setIcon(
            QgsApplication.getThemeIcon("/mActionMapIdentification.svg"))
        self.map_identification_button.setText("Select on map")
        self.map_identification_button.setCheckable(True)
        edit_layout.addWidget(self.map_identification_button)

        self.map_identification_button.clicked.connect(self.map_identification)
        self.highlight_feature_button.triggered.connect(
            self.highlight_action_triggered)

        self.layer = None
        self.map_tool = None
        self.canvas = None
        self.window_widget = None
        self.highlight = None
        self.feature = QgsFeature()

    def set_canvas(self, map_canvas):
        self.map_tool = QgsMapToolIdentifyFeature(map_canvas)
        self.map_tool.setButton(self.map_identification_button)
        self.canvas = map_canvas

    def set_layer(self, layer):
        self.layer = layer

    def set_feature(self, feature, canvas_extent=CanvasExtent.Fixed):
        self.line_edit.clear()
        self.feature = feature

        if self.feature is None or not self.feature.isValid(
        ) or self.layer is None:
            return

        expression = QgsExpression(self.layer.displayExpression())
        context = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        context.appendScope(scope)
        scope.setFeature(feature)
        feature_title = expression.evaluate(context)
        if feature_title == "":
            feature_title = feature.id()
        self.line_edit.setText(str(feature_title))
        self.highlight_feature(canvas_extent)

    def clear(self):
        self.feature = QgsFeature()
        self.line_edit.clear()

    @pyqtSlot()
    def map_identification(self):
        if self.layer is None or self.map_tool is None or self.canvas is None:
            return

        self.map_tool.setLayer(self.layer)
        self.canvas.setMapTool(self.map_tool)

        self.window_widget = QWidget.window(self)
        self.canvas.window().raise_()
        self.canvas.activateWindow()
        self.canvas.setFocus()

        self.map_tool.featureIdentified.connect(
            self.map_tool_feature_identified)
        self.map_tool.deactivated.connect(self.map_tool_deactivated)

    def map_tool_feature_identified(self, feature):
        feature = QgsFeature(feature)
        self.feature_identified.emit(feature)
        self.unset_map_tool()
        self.set_feature(feature)

    def map_tool_deactivated(self):
        if self.window_widget is not None:
            self.window_widget.raise_()
            self.window_widget.activateWindow()

    def highlight_feature(self, canvas_extent=CanvasExtent.Fixed):
        if self.canvas is None or not self.feature.isValid():
            return

        geom = self.feature.geometry()

        if geom is None:
            return

        if canvas_extent == CanvasExtent.Scale:
            feature_bounding_box = geom.boundingBox()
            feature_bounding_box = self.canvas.mapSettings(
            ).layerToMapCoordinates(self.layer, feature_bounding_box)
            extent = self.canvas.extent()
            if not extent.contains(feature_bounding_box):
                extent.combineExtentWith(feature_bounding_box)
                extent.scale(1.1)
                self.canvas.setExtent(extent)
                self.canvas.refresh()

        elif canvas_extent == CanvasExtent.Pan:
            centroid = geom.centroid()
            center = centroid.asPoint()

            center = self.canvas.mapSettings().layerToMapCoordinates(
                self.layer, center)
            self.canvas.zoomByFactor(1.0,
                                     center)  # refresh is done in this method

        # highlight
        self.delete_highlight()
        self.highlight = QgsHighlight(self.canvas, geom, self.layer)

        settings = QSettings()
        color = QColor(
            settings.value("/Map/highlight/color",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.name()))
        alpha = int(
            settings.value("/Map/highlight/colorAlpha",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.alpha()))
        buffer = 2 * float(
            settings.value("/Map/highlight/buffer",
                           Qgis.DEFAULT_HIGHLIGHT_BUFFER_MM))
        min_width = 2 * float(
            settings.value("/Map/highlight/min_width",
                           Qgis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM))

        self.highlight.setColor(color)  # sets also fill with default alpha
        color.setAlpha(alpha)
        self.highlight.setFillColor(color)  # sets fill with alpha
        self.highlight.setBuffer(buffer)
        self.highlight.setMinWidth(min_width)
        self.highlight.setWidth(4.0)
        self.highlight.show()

        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.delete_highlight)
        self.timer.start(3000)

    def delete_highlight(self):
        if self.highlight is not None:
            self.highlight.hide()
            del self.highlight
            self.highlight = None

    def unset_map_tool(self):
        if self.canvas is not None and self.map_tool is not None:
            # this will call mapTool.deactivated
            self.canvas.unsetMapTool(self.map_tool)

    def highlight_action_triggered(self, action):
        self.highlight_feature_button.setDefaultAction(action)

        if action == self.highlight_feature_action:
            self.highlight_feature()

        elif action == self.scale_highlight_feature_action:
            self.highlight_feature(CanvasExtent.Scale)

        elif action == self.pan_highlight_feature_action:
            self.highlight_feature(CanvasExtent.Pan)
예제 #10
0
class Plugin():
    """The QGIS interface implementation for the InaSAFE plugin.

    This class acts as the 'glue' between QGIS and our custom logic.
    It creates a toolbar and menu bar entry and launches the InaSAFE user
    interface if these are activated.
    """
    def __init__(self, iface):
        """Class constructor.

        On instantiation, the plugin instance will be assigned a copy
        of the QGIS iface object which will allow this plugin to access and
        manipulate the running QGIS instance that spawned it.

        :param iface:Quantum GIS iface instance. This instance is
            automatically passed to the plugin by QGIS when it loads the
            plugin.
        :type iface: QgisAppInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        self.dock_widget = None

        # Actions
        self.action_add_layers = None
        self.action_add_osm_layer = None
        self.action_add_petabencana_layer = None
        self.action_batch_runner = None
        self.action_dock = None
        self.action_extent_selector = None
        self.action_field_mapping = None
        self.action_multi_exposure = None
        self.action_function_centric_wizard = None
        self.action_import_dialog = None
        self.action_keywords_wizard = None
        self.action_minimum_needs = None
        self.action_minimum_needs_config = None
        self.action_multi_buffer = None
        self.action_options = None
        self.action_run_tests = None
        self.action_save_scenario = None
        self.action_shake_converter = None
        self.action_show_definitions = None
        self.action_toggle_rubberbands = None
        self.action_metadata_converter = None

        self.translator = None
        self.toolbar = None
        self.wizard = None
        self.actions = []  # list of all QActions we create for InaSAFE

        self.message_bar_item = None
        # Flag indicating if toolbar should show only common icons or not
        self.full_toolbar = False
        # print self.tr('InaSAFE')
        # For enable/disable the keyword editor icon
        self.iface.currentLayerChanged.connect(self.layer_changed)

        developer_mode = setting('developer_mode', False, expected_type=bool)
        self.hide_developer_buttons = (inasafe_release_status == 'final'
                                       and not developer_mode)

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Plugin', message)

    def add_action(self, action, add_to_toolbar=True, add_to_legend=False):
        """Add a toolbar icon to the InaSAFE toolbar.

        :param action: The action that should be added to the toolbar.
        :type action: QAction

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the InaSAFE toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param add_to_legend: Flag indicating whether the action should also
            be added to the layer legend menu. Default to False.
        :type add_to_legend: bool
        """
        # store in the class list of actions for easy plugin unloading
        self.actions.append(action)
        self.iface.addPluginToMenu(self.tr('InaSAFE'), action)
        if add_to_toolbar:
            self.toolbar.addAction(action)
        if add_to_legend:
            # The id is the action name without spaces, tabs ...
            self.iface.addCustomActionForLayerType(action, self.tr('InaSAFE'),
                                                   QgsMapLayer.VectorLayer,
                                                   True)
            self.iface.addCustomActionForLayerType(action, self.tr('InaSAFE'),
                                                   QgsMapLayer.RasterLayer,
                                                   True)

    def _create_dock_toggle_action(self):
        """Create action for plugin dockable window (show/hide)."""
        # pylint: disable=W0201
        icon = resources_path('img', 'icons', 'icon.svg')
        self.action_dock = QAction(QIcon(icon), self.tr('Toggle InaSAFE Dock'),
                                   self.iface.mainWindow())
        self.action_dock.setObjectName('InaSAFEDockToggle')
        self.action_dock.setStatusTip(self.tr('Show/hide InaSAFE dock widget'))
        self.action_dock.setWhatsThis(self.tr('Show/hide InaSAFE dock widget'))
        self.action_dock.setCheckable(True)
        self.action_dock.setChecked(True)
        self.action_dock.triggered.connect(self.toggle_dock_visibility)
        self.add_action(self.action_dock)

        # --------------------------------------
        # Create action for keywords creation wizard
        # -------------------------------------

    def _create_keywords_wizard_action(self):
        """Create action for keywords creation wizard."""
        icon = resources_path('img', 'icons', 'show-keyword-wizard.svg')
        self.action_keywords_wizard = QAction(
            QIcon(icon), self.tr('Keywords Creation Wizard'),
            self.iface.mainWindow())
        self.action_keywords_wizard.setStatusTip(
            self.tr('Open InaSAFE keywords creation wizard'))
        self.action_keywords_wizard.setWhatsThis(
            self.tr('Open InaSAFE keywords creation wizard'))
        self.action_keywords_wizard.setEnabled(False)
        self.action_keywords_wizard.triggered.connect(
            self.show_keywords_wizard)
        self.add_action(self.action_keywords_wizard, add_to_legend=True)

    def _create_analysis_wizard_action(self):
        """Create action for IF-centric wizard."""
        icon = resources_path('img', 'icons', 'show-wizard.svg')
        self.action_function_centric_wizard = QAction(
            QIcon(icon), self.tr('Impact Function Centric Wizard'),
            self.iface.mainWindow())
        self.action_function_centric_wizard.setStatusTip(
            self.tr('Open InaSAFE impact function centric wizard'))
        self.action_function_centric_wizard.setWhatsThis(
            self.tr('Open InaSAFE impact function centric wizard'))
        self.action_function_centric_wizard.setEnabled(True)
        self.action_function_centric_wizard.triggered.connect(
            self.show_function_centric_wizard)
        self.add_action(self.action_function_centric_wizard)

    def _create_options_dialog_action(self):
        """Create action for options dialog."""
        icon = resources_path('img', 'icons', 'configure-inasafe.svg')
        self.action_options = QAction(QIcon(icon), self.tr('Options'),
                                      self.iface.mainWindow())
        self.action_options.setStatusTip(
            self.tr('Open InaSAFE options dialog'))
        self.action_options.setWhatsThis(
            self.tr('Open InaSAFE options dialog'))
        self.action_options.triggered.connect(self.show_options)
        self.add_action(self.action_options, add_to_toolbar=self.full_toolbar)

    def _create_minimum_needs_action(self):
        """Create action for minimum needs dialog."""
        icon = resources_path('img', 'icons', 'show-minimum-needs.svg')
        self.action_minimum_needs = QAction(
            QIcon(icon), self.tr('Minimum Needs Calculator'),
            self.iface.mainWindow())
        self.action_minimum_needs.setStatusTip(
            self.tr('Open InaSAFE minimum needs calculator'))
        self.action_minimum_needs.setWhatsThis(
            self.tr('Open InaSAFE minimum needs calculator'))
        self.action_minimum_needs.triggered.connect(self.show_minimum_needs)
        self.add_action(self.action_minimum_needs,
                        add_to_toolbar=self.full_toolbar)

    def _create_multi_buffer_action(self):
        """Create action for multi buffer dialog."""
        icon = resources_path('img', 'icons', 'show-multi-buffer.svg')
        self.action_multi_buffer = QAction(QIcon(icon),
                                           self.tr('Multi Buffer'),
                                           self.iface.mainWindow())
        self.action_multi_buffer.setStatusTip(
            self.tr('Open InaSAFE multi buffer'))
        self.action_multi_buffer.setWhatsThis(
            self.tr('Open InaSAFE multi buffer'))
        self.action_multi_buffer.triggered.connect(self.show_multi_buffer)
        self.add_action(self.action_multi_buffer,
                        add_to_toolbar=self.full_toolbar)

    def _create_minimum_needs_options_action(self):
        """Create action for global minimum needs dialog."""
        icon = resources_path('img', 'icons', 'show-global-minimum-needs.svg')
        self.action_minimum_needs_config = QAction(
            QIcon(icon), self.tr('Minimum Needs Configuration'),
            self.iface.mainWindow())
        self.action_minimum_needs_config.setStatusTip(
            self.tr('Open InaSAFE minimum needs configuration'))
        self.action_minimum_needs_config.setWhatsThis(
            self.tr('Open InaSAFE minimum needs configuration'))
        self.action_minimum_needs_config.triggered.connect(
            self.show_minimum_needs_configuration)
        self.add_action(self.action_minimum_needs_config,
                        add_to_toolbar=self.full_toolbar)

    def _create_shakemap_converter_action(self):
        """Create action for converter dialog."""
        icon = resources_path('img', 'icons', 'show-converter-tool.svg')
        self.action_shake_converter = QAction(QIcon(icon),
                                              self.tr('Shakemap Converter'),
                                              self.iface.mainWindow())
        self.action_shake_converter.setStatusTip(
            self.tr('Open InaSAFE Converter'))
        self.action_shake_converter.setWhatsThis(
            self.tr('Open InaSAFE Converter'))
        self.action_shake_converter.triggered.connect(
            self.show_shakemap_importer)
        self.add_action(self.action_shake_converter,
                        add_to_toolbar=self.full_toolbar)

    def _create_batch_runner_action(self):
        """Create action for batch runner dialog."""
        icon = resources_path('img', 'icons', 'show-batch-runner.svg')
        self.action_batch_runner = QAction(QIcon(icon),
                                           self.tr('Batch Runner'),
                                           self.iface.mainWindow())
        self.action_batch_runner.setStatusTip(self.tr('Open Batch Runner'))
        self.action_batch_runner.setWhatsThis(self.tr('Open Batch Runner'))
        self.action_batch_runner.triggered.connect(self.show_batch_runner)
        self.add_action(self.action_batch_runner,
                        add_to_toolbar=self.full_toolbar)

    def _create_save_scenario_action(self):
        """Create action for save scenario dialog."""
        icon = resources_path('img', 'icons', 'save-as-scenario.svg')
        self.action_save_scenario = QAction(QIcon(icon),
                                            self.tr('Save Current Scenario'),
                                            self.iface.mainWindow())
        message = self.tr('Save current scenario to text file')
        self.action_save_scenario.setStatusTip(message)
        self.action_save_scenario.setWhatsThis(message)
        # noinspection PyUnresolvedReferences
        self.action_save_scenario.triggered.connect(self.save_scenario)
        self.add_action(self.action_save_scenario,
                        add_to_toolbar=self.full_toolbar)

    def _create_osm_downloader_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'show-osm-download.svg')
        self.action_import_dialog = QAction(
            QIcon(icon), self.tr('OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.action_import_dialog.setStatusTip(
            self.tr('OpenStreetMap Downloader'))
        self.action_import_dialog.setWhatsThis(
            self.tr('OpenStreetMap Downloader'))
        self.action_import_dialog.triggered.connect(self.show_osm_downloader)
        self.add_action(self.action_import_dialog, add_to_toolbar=True)

    def _create_geonode_uploader_action(self):
        """Create action for Geonode uploader dialog."""
        icon = resources_path('img', 'icons', 'geonode.png')
        label = tr('Geonode Uploader')
        self.action_geonode = QAction(QIcon(icon), label,
                                      self.iface.mainWindow())
        self.action_geonode.setStatusTip(label)
        self.action_geonode.setWhatsThis(label)
        self.action_geonode.triggered.connect(self.show_geonode_uploader)
        self.add_action(self.action_geonode, add_to_toolbar=False)

    def _create_add_osm_layer_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'add-osm-tiles-layer.svg')
        self.action_add_osm_layer = QAction(
            QIcon(icon), self.tr('Add OpenStreetMap Tile Layer'),
            self.iface.mainWindow())
        self.action_add_osm_layer.setStatusTip(
            self.tr('Add OpenStreetMap Tile Layer'))
        self.action_add_osm_layer.setWhatsThis(
            self.tr('Use this to add an OSM layer to your map. '
                    'It needs internet access to function.'))
        self.action_add_osm_layer.triggered.connect(self.add_osm_layer)
        self.add_action(self.action_add_osm_layer, add_to_toolbar=True)

    def _create_show_definitions_action(self):
        """Create action for showing definitions / help."""
        icon = resources_path('img', 'icons', 'show-inasafe-help.svg')
        self.action_show_definitions = QAction(QIcon(icon),
                                               self.tr('InaSAFE Help'),
                                               self.iface.mainWindow())
        self.action_show_definitions.setStatusTip(self.tr('Show InaSAFE Help'))
        self.action_show_definitions.setWhatsThis(
            self.
            tr('Use this to show a document describing all InaSAFE concepts.'))
        self.action_show_definitions.triggered.connect(self.show_definitions)
        self.add_action(self.action_show_definitions, add_to_toolbar=True)

    def _create_metadata_converter_action(self):
        """Create action for showing metadata converter dialog."""
        icon = resources_path('img', 'icons', 'show-metadata-converter.svg')
        self.action_metadata_converter = QAction(
            QIcon(icon), self.tr('InaSAFE Metadata Converter'),
            self.iface.mainWindow())
        self.action_metadata_converter.setStatusTip(
            self.tr('Convert metadata from version 4.3 to version 3.5.'))
        self.action_metadata_converter.setWhatsThis(
            self.tr('Use this tool to convert metadata 4.3 to version 3.5'))
        self.action_metadata_converter.triggered.connect(
            self.show_metadata_converter)
        self.add_action(self.action_metadata_converter,
                        add_to_toolbar=self.full_toolbar)

    def _create_field_mapping_action(self):
        """Create action for showing field mapping dialog."""
        icon = resources_path('img', 'icons', 'show-mapping-tool.svg')
        self.action_field_mapping = QAction(
            QIcon(icon), self.tr('InaSAFE Field Mapping Tool'),
            self.iface.mainWindow())
        self.action_field_mapping.setStatusTip(
            self.tr('Assign field mapping to layer.'))
        self.action_field_mapping.setWhatsThis(
            self.tr('Use this tool to assign field mapping in layer.'))
        self.action_field_mapping.setEnabled(False)
        self.action_field_mapping.triggered.connect(self.show_field_mapping)
        self.add_action(self.action_field_mapping,
                        add_to_toolbar=self.full_toolbar)

    def _create_multi_exposure_action(self):
        """Create action for showing the multi exposure tool."""
        self.action_multi_exposure = QAction(
            QIcon(resources_path('img', 'icons', 'show-multi-exposure.svg')),
            self.tr('InaSAFE Multi Exposure Tool'), self.iface.mainWindow())
        self.action_multi_exposure.setStatusTip(
            self.tr('Open the multi exposure tool.'))
        self.action_multi_exposure.setWhatsThis(
            self.tr('Open the multi exposure tool.'))
        self.action_multi_exposure.setEnabled(True)
        self.action_multi_exposure.triggered.connect(self.show_multi_exposure)
        self.add_action(self.action_multi_exposure,
                        add_to_toolbar=self.full_toolbar)

    def _create_add_petabencana_layer_action(self):
        """Create action for import OSM Dialog."""
        icon = resources_path('img', 'icons', 'add-petabencana-layer.svg')
        self.action_add_petabencana_layer = QAction(
            QIcon(icon), self.tr('Add PetaBencana Flood Layer'),
            self.iface.mainWindow())
        self.action_add_petabencana_layer.setStatusTip(
            self.tr('Add PetaBencana Flood Layer'))
        self.action_add_petabencana_layer.setWhatsThis(
            self.tr('Use this to add a PetaBencana layer to your map. '
                    'It needs internet access to function.'))
        self.action_add_petabencana_layer.triggered.connect(
            self.add_petabencana_layer)
        self.add_action(self.action_add_petabencana_layer,
                        add_to_toolbar=self.full_toolbar)

    def _create_rubber_bands_action(self):
        """Create action for toggling rubber bands."""
        icon = resources_path('img', 'icons', 'toggle-rubber-bands.svg')
        self.action_toggle_rubberbands = QAction(
            QIcon(icon), self.tr('Toggle Scenario Outlines'),
            self.iface.mainWindow())
        message = self.tr('Toggle rubber bands showing scenario extents.')
        self.action_toggle_rubberbands.setStatusTip(message)
        self.action_toggle_rubberbands.setWhatsThis(message)
        # Set initial state
        self.action_toggle_rubberbands.setCheckable(True)
        flag = setting('showRubberBands', False, expected_type=bool)
        self.action_toggle_rubberbands.setChecked(flag)
        # noinspection PyUnresolvedReferences
        self.action_toggle_rubberbands.triggered.connect(
            self.dock_widget.toggle_rubber_bands)
        self.add_action(self.action_toggle_rubberbands)

    def _create_analysis_extent_action(self):
        """Create action for analysis extent dialog."""
        icon = resources_path('img', 'icons', 'set-extents-tool.svg')
        self.action_extent_selector = QAction(QIcon(icon),
                                              self.tr('Set Analysis Area'),
                                              self.iface.mainWindow())
        self.action_extent_selector.setStatusTip(
            self.tr('Set the analysis area for InaSAFE'))
        self.action_extent_selector.setWhatsThis(
            self.tr('Set the analysis area for InaSAFE'))
        self.action_extent_selector.triggered.connect(
            self.show_extent_selector)
        self.add_action(self.action_extent_selector)

    def _create_test_layers_action(self):
        """Create action for adding layers (developer mode, non final only)."""
        if self.hide_developer_buttons:
            return

        icon = resources_path('img', 'icons', 'add-test-layers.svg')
        self.action_add_layers = QAction(QIcon(icon),
                                         self.tr('Add Test Layers'),
                                         self.iface.mainWindow())
        self.action_add_layers.setStatusTip(self.tr('Add test layers'))
        self.action_add_layers.setWhatsThis(self.tr('Add test layers'))
        self.action_add_layers.triggered.connect(self.add_test_layers)

        self.add_action(self.action_add_layers)

    def _create_run_test_action(self):
        """Create action for running tests (developer mode, non final only)."""
        if self.hide_developer_buttons:
            return

        default_package = str(setting('testPackage', 'safe',
                                      expected_type=str))
        msg = self.tr('Run tests in %s' % default_package)

        self.test_button = QToolButton()
        self.test_button.setMenu(QMenu())
        self.test_button.setPopupMode(QToolButton.MenuButtonPopup)

        icon = resources_path('img', 'icons', 'run-tests.svg')
        self.action_run_tests = QAction(QIcon(icon), msg,
                                        self.iface.mainWindow())

        self.action_run_tests.setStatusTip(msg)
        self.action_run_tests.setWhatsThis(msg)
        self.action_run_tests.triggered.connect(self.run_tests)

        self.test_button.menu().addAction(self.action_run_tests)
        self.test_button.setDefaultAction(self.action_run_tests)

        self.action_select_package = QAction(QIcon(icon),
                                             self.tr('Select package'),
                                             self.iface.mainWindow())

        self.action_select_package.setStatusTip(self.tr('Select Test Package'))
        self.action_select_package.setWhatsThis(self.tr('Select Test Package'))
        self.action_select_package.triggered.connect(self.select_test_package)
        self.test_button.menu().addAction(self.action_select_package)
        self.toolbar.addWidget(self.test_button)

        self.add_action(self.action_run_tests, add_to_toolbar=False)
        self.add_action(self.action_select_package, add_to_toolbar=False)

    def _create_dock(self):
        """Create dockwidget and tabify it with the legend."""
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe.gui.widgets.dock import Dock
        self.dock_widget = Dock(self.iface)
        self.dock_widget.setObjectName('InaSAFE-Dock')
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget)
        legend_tab = self.iface.mainWindow().findChild(QApplication, 'Legend')
        if legend_tab:
            self.iface.mainWindow().tabifyDockWidget(legend_tab,
                                                     self.dock_widget)
            self.dock_widget.raise_()

    # noinspection PyPep8Naming
    def initGui(self):
        """Gui initialisation procedure (for QGIS plugin api).

        .. note:: Don't change the name of this method from initGui!

        This method is called by QGIS and should be used to set up
        any graphical user interface elements that should appear in QGIS by
        default (i.e. before the user performs any explicit action with the
        plugin).
        """
        self.toolbar = self.iface.addToolBar('InaSAFE')
        self.toolbar.setObjectName('InaSAFEToolBar')
        self.dock_widget = None
        # Now create the actual dock
        self._create_dock()
        # And all the menu actions
        # Configuration Group
        self._create_dock_toggle_action()
        self._create_options_dialog_action()
        self._create_minimum_needs_options_action()
        self._create_analysis_extent_action()
        self._create_rubber_bands_action()
        self._add_spacer_to_menu()
        self._create_keywords_wizard_action()
        self._create_analysis_wizard_action()
        self._add_spacer_to_menu()
        self._create_field_mapping_action()
        self._create_multi_exposure_action()
        self._create_metadata_converter_action()
        self._create_osm_downloader_action()
        self._create_add_osm_layer_action()
        self._create_add_petabencana_layer_action()
        self._create_geonode_uploader_action()
        self._create_shakemap_converter_action()
        self._create_minimum_needs_action()
        self._create_multi_buffer_action()
        self._create_test_layers_action()
        self._create_run_test_action()
        self._add_spacer_to_menu()
        self._create_batch_runner_action()
        self._create_save_scenario_action()
        self._add_spacer_to_menu()
        self._create_show_definitions_action()

        # Hook up a slot for when the dock is hidden using its close button
        # or  view-panels
        #
        self.dock_widget.visibilityChanged.connect(self.toggle_inasafe_action)
        # Also deal with the fact that on start of QGIS dock may already be
        # hidden.
        self.action_dock.setChecked(self.dock_widget.isVisible())

        self.iface.initializationCompleted.connect(
            partial(self.show_welcome_message))

    def _add_spacer_to_menu(self):
        """Create a spacer to the menu to separate action groups."""
        separator = QAction(self.iface.mainWindow())
        separator.setSeparator(True)
        self.iface.addPluginToMenu(self.tr('InaSAFE'), separator)

    @staticmethod
    def clear_modules():
        """Unload inasafe functions and try to return QGIS to before InaSAFE.

        .. todo:: I think this function can be removed. TS.
        """
        # next lets force remove any inasafe related modules
        modules = []
        for module in sys.modules:
            if 'inasafe' in module:
                # Check if it is really one of our modules i.e. exists in the
                # plugin directory
                tokens = module.split('.')
                path = ''
                for myToken in tokens:
                    path += os.path.sep + myToken
                parent = os.path.abspath(
                    os.path.join(__file__, os.path.pardir, os.path.pardir))
                full_path = os.path.join(parent, path + '.py')
                if os.path.exists(os.path.abspath(full_path)):
                    LOGGER.debug('Removing: %s' % module)
                    modules.append(module)
        for module in modules:
            del (sys.modules[module])
        for module in sys.modules:
            if 'inasafe' in module:
                print(module)

        # Lets also clean up all the path additions that were made
        package_path = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir))
        LOGGER.debug('Path to remove: %s' % package_path)
        # We use a list comprehension to ensure duplicate entries are removed
        LOGGER.debug(sys.path)
        sys.path = [y for y in sys.path if package_path not in y]
        LOGGER.debug(sys.path)

    def unload(self):
        """GUI breakdown procedure (for QGIS plugin api).

        .. note:: Don't change the name of this method from unload!

        This method is called by QGIS and should be used to *remove*
        any graphical user interface elements that should appear in QGIS.
        """
        # Remove the plugin menu item and icon
        if self.wizard:
            self.wizard.deleteLater()
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(myAction)
            self.iface.removeCustomActionForLayerType(myAction)
        self.iface.mainWindow().removeDockWidget(self.dock_widget)
        self.iface.mainWindow().removeToolBar(self.toolbar)
        self.dock_widget.setVisible(False)
        self.dock_widget.destroy()
        self.iface.currentLayerChanged.disconnect(self.layer_changed)

        # Unload QGIS expressions loaded by the plugin.
        for qgis_expression in list(qgis_expressions().keys()):
            QgsExpression.unregisterFunction(qgis_expression)

    def toggle_inasafe_action(self, checked):
        """Check or un-check the toggle inaSAFE toolbar button.

        This slot is called when the user hides the inaSAFE panel using its
        close button or using view->panels.

        :param checked: True if the dock should be shown, otherwise False.
        :type checked: bool
        """
        self.action_dock.setChecked(checked)

    # Run method that performs all the real work
    def toggle_dock_visibility(self):
        """Show or hide the dock widget."""
        if self.dock_widget.isVisible():
            self.dock_widget.setVisible(False)
        else:
            self.dock_widget.setVisible(True)
            self.dock_widget.raise_()

    def add_test_layers(self):
        """Add standard test layers."""
        from safe.test.utilities import load_standard_layers
        load_standard_layers()
        rect = QgsRectangle(106.806, -6.195, 106.837, -6.167)
        self.iface.mapCanvas().setExtent(rect)

    def select_test_package(self):
        """Select the test package."""
        default_package = 'safe'
        user_package = str(
            setting('testPackage', default_package, expected_type=str))

        test_package, _ = QInputDialog.getText(
            self.iface.mainWindow(), self.tr('Select the python test package'),
            self.tr('Select the python test package'), QLineEdit.Normal,
            user_package)

        if test_package == '':
            test_package = default_package

        set_setting('testPackage', test_package)
        msg = self.tr('Run tests in %s' % test_package)
        self.action_run_tests.setWhatsThis(msg)
        self.action_run_tests.setText(msg)

    def run_tests(self):
        """Run unit tests in the python console."""
        from qgis.PyQt.QtWidgets import QDockWidget
        main_window = self.iface.mainWindow()
        action = main_window.findChild(QAction, 'mActionShowPythonDialog')
        action.trigger()
        package = str(setting('testPackage', 'safe', expected_type=str))
        for child in main_window.findChildren(QDockWidget, 'PythonConsole'):
            if child.objectName() == 'PythonConsole':
                child.show()
                for widget in child.children():
                    if 'PythonConsoleWidget' in str(widget.__class__):
                        # print "Console widget found"
                        shell = widget.shell
                        shell.runCommand(
                            'from inasafe.test_suite import test_package')
                        shell.runCommand('test_package(\'%s\')' % package)
                        break

    def show_extent_selector(self):
        """Show the extent selector widget for defining analysis extents."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.extent_selector_dialog import ExtentSelectorDialog
        widget = ExtentSelectorDialog(
            self.iface,
            self.iface.mainWindow(),
            extent=self.dock_widget.extent.user_extent,
            crs=self.dock_widget.extent.crs)
        widget.clear_extent.connect(
            self.dock_widget.extent.clear_user_analysis_extent)
        widget.extent_defined.connect(
            self.dock_widget.define_user_analysis_extent)
        # This ensures that run button state is updated on dialog close
        widget.extent_selector_closed.connect(
            self.dock_widget.validate_impact_function)
        # Needs to be non modal to support hide -> interact with map -> show
        widget.show()  # non modal

    def show_minimum_needs(self):
        """Show the minimum needs dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.minimum_needs.needs_calculator_dialog import (
            NeedsCalculatorDialog)

        dialog = NeedsCalculatorDialog(self.iface.mainWindow())
        dialog.exec_()

    def show_minimum_needs_configuration(self):
        """Show the minimum needs dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.minimum_needs.needs_manager_dialog import (
            NeedsManagerDialog)

        dialog = NeedsManagerDialog(parent=self.iface.mainWindow(),
                                    dock=self.dock_widget)
        dialog.exec_()  # modal

    def show_options(self):
        """Show the options dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.options_dialog import OptionsDialog

        dialog = OptionsDialog(iface=self.iface,
                               parent=self.iface.mainWindow())
        dialog.show_option_dialog()
        if dialog.exec_():  # modal
            self.dock_widget.read_settings()
            from safe.gui.widgets.message import getting_started_message
            send_static_message(self.dock_widget, getting_started_message())
            # Issue #4734, make sure to update the combobox after update the
            # InaSAFE option
            self.dock_widget.get_layers()

    def show_welcome_message(self):
        """Show the welcome message."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.options_dialog import OptionsDialog

        # Do not show by default
        show_message = False

        previous_version = StrictVersion(setting('previous_version'))
        current_version = StrictVersion(inasafe_version)

        # Set previous_version to the current inasafe_version
        set_setting('previous_version', inasafe_version)

        if setting('always_show_welcome_message', expected_type=bool):
            # Show if it the setting said so
            show_message = True
        elif previous_version < current_version:
            # Always show if the user installed new version
            show_message = True

        # Allow to disable welcome message when running automated tests
        if os.environ.get('INASAFE_DISABLE_WELCOME_MESSAGE', False):
            show_message = False

        if show_message:
            dialog = OptionsDialog(iface=self.iface,
                                   parent=self.iface.mainWindow())
            dialog.show_welcome_dialog()
            if dialog.exec_():  # modal
                self.dock_widget.read_settings()

    def show_keywords_wizard(self):
        """Show the keywords creation wizard."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.wizard.wizard_dialog import WizardDialog

        if self.iface.activeLayer() is None:
            return

        # Don't break an existing wizard session if accidentally clicked
        if self.wizard and self.wizard.isVisible():
            return

        # Prevent spawning multiple copies since the IFCW is non modal
        if not self.wizard:
            self.wizard = WizardDialog(self.iface.mainWindow(), self.iface,
                                       self.dock_widget)
        self.wizard.set_keywords_creation_mode()
        self.wizard.exec_()  # modal

    def show_function_centric_wizard(self):
        """Show the function centric wizard."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.wizard.wizard_dialog import WizardDialog

        # Don't break an existing wizard session if accidentally clicked
        if self.wizard and self.wizard.isVisible():
            return

        # Prevent spawning multiple copies since it is non modal
        if not self.wizard:
            self.wizard = WizardDialog(self.iface.mainWindow(), self.iface,
                                       self.dock_widget)
        self.wizard.set_function_centric_mode()
        # non-modal in order to hide for selecting user extent
        self.wizard.show()

    def show_shakemap_importer(self):
        """Show the converter dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.shake_grid.shakemap_converter_dialog import (
            ShakemapConverterDialog)

        dialog = ShakemapConverterDialog(self.iface.mainWindow(), self.iface,
                                         self.dock_widget)
        dialog.exec_()  # modal

    def show_multi_buffer(self):
        """Show the multi buffer tool."""
        from safe.gui.tools.multi_buffer_dialog import (MultiBufferDialog)

        dialog = MultiBufferDialog(self.iface.mainWindow(), self.iface,
                                   self.dock_widget)
        dialog.exec_()  # modal

    def show_osm_downloader(self):
        """Show the OSM buildings downloader dialog."""
        from safe.gui.tools.osm_downloader_dialog import OsmDownloaderDialog

        dialog = OsmDownloaderDialog(self.iface.mainWindow(), self.iface)
        # otherwise dialog is never deleted
        dialog.setAttribute(Qt.WA_DeleteOnClose, True)
        dialog.show()  # non modal

    def show_geonode_uploader(self):
        """Show the Geonode uploader dialog."""
        from safe.gui.tools.geonode_uploader import GeonodeUploaderDialog

        dialog = GeonodeUploaderDialog(self.iface.mainWindow())
        dialog.show()  # non modal

    def add_osm_layer(self):
        """Add OSM tile layer to the map.

        This uses a gdal wrapper around the OSM tile service - see the
        WorldOSM.gdal file for how it is constructed.
        """
        path = resources_path('osm', 'WorldOSM.gdal')
        layer = QgsRasterLayer(path, self.tr('OpenStreetMap'))
        project = QgsProject.instance()

        # Try to add it as the last layer in the list
        # False flag prevents layer being added to legend
        project.addMapLayer(layer, False)
        root = QgsProject.instance().layerTreeRoot()
        index = len(root.findLayers()) + 1
        # LOGGER.info('Inserting layer %s at position %s' % (
        #    layer.source(), index))
        root.insertLayer(index, layer)
        project.addMapLayer(layer)

    def show_definitions(self):
        """Show InaSAFE Definitions (a report showing all key metadata)."""
        from safe.utilities.help import show_help
        from safe.gui.tools.help import definitions_help
        show_help(definitions_help.definitions_help())

    def show_field_mapping(self):
        """Show InaSAFE Field Mapping."""
        from safe.gui.tools.field_mapping_dialog import FieldMappingDialog
        dialog = FieldMappingDialog(
            parent=self.iface.mainWindow(),
            iface=self.iface,
        )
        if dialog.exec_():  # modal
            LOGGER.debug('Show field mapping accepted')
            self.dock_widget.layer_changed(self.iface.activeLayer())
        else:
            LOGGER.debug('Show field mapping not accepted')

    def show_metadata_converter(self):
        """Show InaSAFE Metadata Converter."""
        from safe.gui.tools.metadata_converter_dialog import (
            MetadataConverterDialog)
        dialog = MetadataConverterDialog(
            parent=self.iface.mainWindow(),
            iface=self.iface,
        )
        dialog.exec_()

    def show_multi_exposure(self):
        """Show InaSAFE Multi Exposure."""
        from safe.gui.tools.multi_exposure_dialog import MultiExposureDialog
        dialog = MultiExposureDialog(self.iface.mainWindow(), self.iface)
        dialog.exec_()  # modal

    def add_petabencana_layer(self):
        """Add petabencana layer to the map.

        This uses the PetaBencana API to fetch the latest floods in JK. See
        https://data.petabencana.id/floods
        """
        from safe.gui.tools.peta_bencana_dialog import PetaBencanaDialog
        dialog = PetaBencanaDialog(self.iface.mainWindow(), self.iface)
        dialog.show()  # non modal

    def show_batch_runner(self):
        """Show the batch runner dialog."""
        from safe.gui.tools.batch.batch_dialog import BatchDialog

        dialog = BatchDialog(parent=self.iface.mainWindow(),
                             iface=self.iface,
                             dock=self.dock_widget)
        dialog.exec_()  # modal

    def save_scenario(self):
        """Save current scenario to text file."""
        from safe.gui.tools.save_scenario import SaveScenarioDialog

        dialog = SaveScenarioDialog(iface=self.iface, dock=self.dock_widget)
        dialog.save_scenario()

    def layer_changed(self, layer):
        """Enable or disable keywords editor icon when active layer changes.

        :param layer: The layer that is now active.
        :type layer: QgsMapLayer
        """
        if not layer:
            enable_keyword_wizard = False
        elif not hasattr(layer, 'providerType'):
            enable_keyword_wizard = False
        elif layer.providerType() == 'wms':
            enable_keyword_wizard = False
        else:
            enable_keyword_wizard = True

        try:
            if layer:
                if is_raster_layer(layer):
                    enable_field_mapping_tool = False
                else:
                    keywords = KeywordIO().read_keywords(layer)
                    keywords_version = keywords.get('keyword_version')
                    if not keywords_version:
                        supported = False
                    else:
                        supported = (
                            is_keyword_version_supported(keywords_version))
                    if not supported:
                        enable_field_mapping_tool = False
                    else:
                        layer_purpose = keywords.get('layer_purpose')

                        if not layer_purpose:
                            enable_field_mapping_tool = False
                        else:
                            if layer_purpose == layer_purpose_exposure['key']:
                                layer_subcategory = keywords.get('exposure')
                            elif layer_purpose == layer_purpose_hazard['key']:
                                layer_subcategory = keywords.get('hazard')
                            else:
                                layer_subcategory = None
                            field_groups = get_field_groups(
                                layer_purpose, layer_subcategory)
                            if len(field_groups) == 0:
                                # No field group, disable field mapping tool.
                                enable_field_mapping_tool = False
                            else:
                                enable_field_mapping_tool = True
            else:
                enable_field_mapping_tool = False
        except (KeywordNotFoundError, NoKeywordsFoundError, MetadataReadError):
            # No keywords, disable field mapping tool.
            enable_field_mapping_tool = False

        self.action_keywords_wizard.setEnabled(enable_keyword_wizard)
        self.action_field_mapping.setEnabled(enable_field_mapping_tool)

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()
예제 #11
0
class HffPlugin_s(object):
    HOME = os.environ['HFF_HOME']

    PARAMS_DICT = {'SERVER': '',
                   'HOST': '',
                   'DATABASE': '',
                   'PASSWORD': '',
                   'PORT': '',
                   'USER': '',
                   'THUMB_PATH': '',
                   'THUMB_RESIZE': '',
                   'EXPERIMENTAL': ''}

    path_rel = os.path.join(os.sep, HOME, 'HFF_DB_folder', 'config.cfg')
    conf = open(path_rel, "rb+")
    data = conf.read()
    text = (b'THUMB_RESIZE')
   
    if text in data:
        pass   
    else:       
        conf.seek(-3,2)
        conf.read(1)    
        conf.write(b"','THUMB_RESIZE' : 'insert path for the image resized'}")
        
   
     
    conf.close()
    PARAMS_DICT = eval(data)

 

    def __init__(self, iface):
        self.iface = iface
        userPluginPath = os.path.dirname(__file__)
        systemPluginPath = QgsApplication.prefixPath() + "/python/plugins/HFF"

        # overrideLocale = QgsSettings().value("locale/overrideFlag", QVariant)  # .toBool()
        # if not overrideLocale:
            # localeFullName = QLocale.system().name()
        # else:
            # localeFullName = QgsSettings().value("locale/userLocale", QVariant)  # .toString()

        # if QFileInfo(userPluginPath).exists():
            # translationPath = userPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"
        # else:
            # translationPath = systemPluginPath + "/i18n/hff_system__plugin_" + localeFullName + ".qm"

        # self.localePath = translationPath
        # if QFileInfo(self.localePath).exists():
            # self.translator = QTranslator()
            # self.translator.load(self.localePath)
            # QCoreApplication.installTranslator(self.translator)

    def initGui(self):
      
        settings = QgsSettings()
        icon_paius = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'hfflogo.png'))
        self.action = QAction(QIcon(icon_paius), "HFF Main Panel",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.showHideDockWidget)

        # dock widget
        self.dockWidget = HffPluginDialog(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        # TOOLBAR
        self.toolBar = self.iface.addToolBar("HFF")
        self.toolBar.setObjectName("HFF")
        self.toolBar.addAction(self.action)

        self.dataToolButton = QToolButton(self.toolBar)
        self.dataToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolBar.addSeparator()
        
        
        ######  Section dedicated to the basic data entry
        # add Actions data
        self.siteToolButton = QToolButton(self.toolBar)
        #self.siteToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_site = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconSite.png'))
        self.actionSite = QAction(QIcon(icon_site), "Site", self.iface.mainWindow())
        self.actionSite.setWhatsThis("Site")
        self.actionSite.triggered.connect(self.runSite)
        self.siteToolButton.addActions([self.actionSite])
        self.siteToolButton.setDefaultAction(self.actionSite)
        self.toolBar.addWidget(self.siteToolButton)
        self.toolBar.addSeparator()
        
        
        self.emeanaToolButton = QToolButton(self.toolBar)
        #self.emeanaToolButton.setPopupMode(QToolButton.MenuButtonPopup)
        icon_eamena = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'eamena.jpg'))
        self.actionEamena = QAction(QIcon(icon_eamena), "Eamena", self.iface.mainWindow())
        self.actionEamena.setWhatsThis("Eamena")
        self.actionEamena.triggered.connect(self.runEamena)
        self.emeanaToolButton.addActions([self.actionEamena])
        self.emeanaToolButton.setDefaultAction(self.actionEamena)
        self.toolBar.addWidget(self.emeanaToolButton)
        self.toolBar.addSeparator()
        
        ######  Section dedicated to the shipwreck
        # add Actions documentation
        self.ShipwreckToolButton = QToolButton(self.toolBar)
        icon_shipwreck = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'Shipwreck.png'))
        self.actionShipwreck = QAction(QIcon(icon_shipwreck), "Shipwreck", self.iface.mainWindow())
        self.actionShipwreck.setWhatsThis("Shipwreck")
        self.actionShipwreck.triggered.connect(self.runShipwreck)
        self.ShipwreckToolButton.addActions([self.actionShipwreck])
        self.ShipwreckToolButton.setDefaultAction(self.actionShipwreck)
        self.toolBar.addWidget(self.ShipwreckToolButton)
        self.toolBar.addSeparator()
        ######  Section dedicated to the UnderWater data entry
        # add Actions data
        icon_UW = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'snorkel.png'))
        self.actionUW = QAction(QIcon(icon_UW), "Divelog Form", self.iface.mainWindow())
        self.actionUW.setWhatsThis("Divelog")
        self.actionUW.triggered.connect(self.runUW)
        
        icon_ANC = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconANC.png'))
        self.actionANC = QAction(QIcon(icon_ANC), "Anchor", self.iface.mainWindow())
        self.actionANC.setWhatsThis("Anchor")
        self.actionANC.triggered.connect(self.runANC)
        
        icon_ART = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'radar.png'))
        self.actionART = QAction(QIcon(icon_ART), "Artefact", self.iface.mainWindow())
        self.actionART.setWhatsThis("Artefact")
        self.actionART.triggered.connect(self.runART)
        
        icon_Pottery = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'pottery.png'))
        self.actionPottery = QAction(QIcon(icon_Pottery), "Pottery", self.iface.mainWindow())
        self.actionPottery.setWhatsThis("Pottery")
        self.actionPottery.triggered.connect(self.runPottery)
        
        self.dataToolButton.addActions(
            [self.actionUW, self.actionART, self.actionANC, self.actionPottery])
        self.dataToolButton.setDefaultAction(self.actionUW)

        self.toolBar.addWidget(self.dataToolButton)

        self.toolBar.addSeparator()
        
        
 
        ######  Section dedicated to the documentation
        # add Actions documentation
        self.docToolButton = QToolButton(self.toolBar)
        self.docToolButton.setPopupMode(QToolButton.MenuButtonPopup)

       
        icon_imageViewer = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'photo.png'))
        self.actionimageViewer = QAction(QIcon(icon_imageViewer), "Media manager", self.iface.mainWindow())
        self.actionimageViewer.setWhatsThis("Media manager")
        self.actionimageViewer.triggered.connect(self.runImageViewer)

        icon_Directory_export = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'directoryExp.png'))
        self.actionImages_Directory_export = QAction(QIcon(icon_Directory_export), "Download image",
                                                     self.iface.mainWindow())
        self.actionImages_Directory_export.setWhatsThis("Download image")
        self.actionImages_Directory_export.triggered.connect(self.runImages_directory_export)

        icon_excel_exp = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'excel-export.png'))
        self.actionexcelExp = QAction(QIcon(icon_excel_exp), "Download EXCEL", self.iface.mainWindow())
        self.actionexcelExp.setWhatsThis("Download EXCEL")
        self.actionexcelExp.triggered.connect(self.runPdfexp)

      
        self.docToolButton.addActions(
            [self.actionexcelExp, self.actionimageViewer, self.actionexcelExp, self.actionImages_Directory_export])

        self.docToolButton.setDefaultAction(self.actionimageViewer)

        #if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
        self.actionImages_Directory_export.setCheckable(True)
        self.actionexcelExp.setCheckable(True)
        self.actionimageViewer.setCheckable(True)

        self.toolBar.addWidget(self.docToolButton)

        self.toolBar.addSeparator()

       

        ######  Section dedicated to the plugin management

        self.manageToolButton = QToolButton(self.toolBar)
        self.manageToolButton.setPopupMode(QToolButton.MenuButtonPopup)


        icon_Con = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconConn.png'))
        self.actionConf = QAction(QIcon(icon_Con), "Config plugin", self.iface.mainWindow())
        self.actionConf.setWhatsThis("Config plugin")
        self.actionConf.triggered.connect(self.runConf)

        icon_Dbmanagment = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'backup.png'))
        self.actionDbmanagment = QAction(QIcon(icon_Dbmanagment), "Database manager", self.iface.mainWindow())
        self.actionDbmanagment.setWhatsThis("Database manager")
        self.actionDbmanagment.triggered.connect(self.runDbmanagment)

        icon_Info = '{}{}'.format(filepath, os.path.join(os.sep, 'resources', 'icons', 'iconInfo.png'))
        self.actionInfo = QAction(QIcon(icon_Info), "Plugin info", self.iface.mainWindow())
        self.actionInfo.setWhatsThis("Plugin info")
        self.actionInfo.triggered.connect(self.runInfo)

        self.manageToolButton.addActions(
            [self.actionConf,  self.actionDbmanagment, self.actionInfo])
        self.manageToolButton.setDefaultAction(self.actionConf)

        self.toolBar.addWidget(self.manageToolButton)

        self.toolBar.addSeparator()

        # menu
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionUW)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionANC)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionART)
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionPottery)
        
        self.iface.addPluginToMenu("HFF - Survey UW Archaeological GIS Tools", self.actionShipwreck)
        
        
        
        self.iface.addPluginToMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionSite)
        self.iface.addPluginToMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionEamena)
        
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionimageViewer)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionexcelExp)
        self.iface.addPluginToMenu("HFF - Media manager GIS Tools", self.actionImages_Directory_export)

        
        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionConf)
        
        self.iface.addPluginToMenu("HFF - Config GIS Tools", self.actionDbmanagment)
        self.iface.addPluginToMenu("HFF - Info GIS Tools", self.actionInfo)

        # MENU
        self.menu = QMenu("HFF")
        self.menu.addActions([self.actionSite])
        
        self.menu.addSeparator()
        self.menu.addActions([self.actionEamena])
        
        self.menu.addSeparator()
        
        self.menu.addActions([self.actionShipwreck])
        self.menu.addSeparator()
        self.menu.addActions([self.actionUW, self.actionART, self.actionANC, self.actionPottery])
        
        
        self.menu.addActions([self.actionimageViewer, self.actionexcelExp, self.actionImages_Directory_export])
        self.menu.addSeparator()
      
        self.menu.addActions([self.actionConf,  self.actionDbmanagment, self.actionInfo])
        menuBar = self.iface.mainWindow().menuBar()
        menuBar.addMenu(self.menu)
    
    ##
    def runSite(self):
        pluginGui = hff_system__Site(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save
        
    
    def runEamena(self):
        pluginGui = Eamena(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save    
    
    
    
    def runUW(self):
        pluginGui = hff_system__UW(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runANC(self):
        pluginGui = hff_system__ANC(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runART(self):
        pluginGui = hff_system__ART(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runPottery(self):
        pluginGui = hff_system__Pottery(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save
        
        
    def runShipwreck(self):
        pluginGui = hff_system__Shipwreck(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save    
    
    
    

    def runConf(self):
        pluginConfGui = HFF_systemDialog_Config()
        pluginConfGui.show()
        self.pluginGui = pluginConfGui  # save

    def runInfo(self):
        pluginInfoGui = HFF_systemDialog_Info()
        pluginInfoGui.show()
        self.pluginGui = pluginInfoGui  # save

    def runImageViewer(self):
        pluginImageView = Main()
        pluginImageView.show()
        self.pluginGui = pluginImageView  # save

   

    def runImages_directory_export(self):
        pluginImage_directory_export = hff_system__Images_directory_export()
        pluginImage_directory_export.show()
        self.pluginGui = pluginImage_directory_export  # save

    

    def runDbmanagment(self):
        pluginDbmanagment = hff_system__dbmanagment(self.iface)
        pluginDbmanagment.show()
        self.pluginGui = pluginDbmanagment  # save

    def runPdfexp(self):
        pluginPdfexp = hff_system__excel_export(self.iface)
        pluginPdfexp.show()
        self.pluginGui = pluginPdfexp  # save

   

    def unload(self):
        # Remove the plugin
        
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionUW)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionANC)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionART)
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionPottery)
        
        self.iface.removePluginMenu("HFF - Survey UW Archaeological GIS Tools", self.actionShipwreck)
        
        self.iface.removePluginMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionSite)
        self.iface.removePluginMenu("HFF - Survey Terrestrial Archaeological GIS Tools", self.actionEamena)
        
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionimageViewer)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionImages_Directory_export)
        self.iface.removePluginMenu("HFF - Media manager GIS Tools", self.actionexcelExp)
        
        self.iface.removePluginMenu("HFF - Config GIS Tools", self.actionConf)
       
        self.iface.removePluginMenu("HFF - Info GIS Tools", self.actionInfo)
        self.iface.removePluginMenu("HFF - Config GIS Tools", self.actionDbmanagment)

        self.iface.removeToolBarIcon(self.actionUW)
        self.iface.removeToolBarIcon(self.actionART)
        self.iface.removeToolBarIcon(self.actionANC)
        self.iface.removeToolBarIcon(self.actionPottery)
        
        self.iface.removeToolBarIcon(self.actionShipwreck)
        
        self.iface.removeToolBarIcon(self.actionSite)
        self.iface.removeToolBarIcon(self.actionEamena)
        self.iface.removeToolBarIcon(self.actionimageViewer)
        self.iface.removeToolBarIcon(self.actionImages_Directory_export)
        self.iface.removeToolBarIcon(self.actionexcelExp)
        
        self.iface.removeToolBarIcon(self.actionConf)
       
        self.iface.removeToolBarIcon(self.actionInfo)
        self.iface.removeToolBarIcon(self.actionDbmanagment)

        self.dockWidget.setVisible(False)
        self.iface.removeDockWidget(self.dockWidget)

        # remove tool bar
        del self.toolBar
    
                
         
    def showHideDockWidget(self):
        if self.dockWidget.isVisible():
            self.dockWidget.hide()
        else:
            self.dockWidget.show()
예제 #12
0
class GeoGigPlugin(object):
    def __init__(self, iface):
        self.iface = iface
        config.iface = iface

        config.initConfigParams()

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            trackLayer(layer)
        try:
            from qgistester.tests import addTestModule
            from geogig.tests import testplugin
            addTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        QSettings().setValue("/qgis/walForSqlite3", False)

    def unload(self):
        navigatorInstance.setVisible(False)
        try:
            QgsMapLayerRegistry.instance().layerWasAdded.disconnect(trackLayer)
            QgsMapLayerRegistry.instance().layerRemoved.disconnect(
                layerRemoved)
        except:
            pass
        self.menu.deleteLater()
        self.toolButton.deleteLater()
        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            removeLayerActions(layer)
        removeNonexistentTrackedLayers()
        deleteTempFolder()

        try:
            from qgistester.tests import removeTestModule
            from geogig.tests import testplugin
            removeTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        try:
            from lessons import removeLessonsFolder
            removeLessonsFolder(folder, "geogig")
        except:
            return

    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/config.png")
        self.configAction = QAction(icon, "GeoGig Settings",
                                    self.iface.mainWindow())
        self.configAction.triggered.connect(self.openSettings)
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool",
                                  self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)
        helpIcon = QgsApplication.getThemeIcon('/mActionHelpAPI.png')
        self.helpAction = QAction(helpIcon, "GeoGig Plugin Help",
                                  self.iface.mainWindow())
        self.helpAction.setObjectName("GeoGigHelp")
        self.helpAction.triggered.connect(
            lambda: webbrowser.open_new("file://" + os.path.join(
                os.path.dirname(__file__), "docs", "html", "index.html")))
        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        self.menu.addAction(self.configAction)
        self.menu.addAction(self.helpAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        useMainMenu = config.getConfigValue(config.GENERAL,
                                            config.USE_MAIN_MENUBAR)
        bar.addWidget(self.toolButton)
        if useMainMenu:
            menuBar = self.iface.mainWindow().menuBar()
            menuBar.insertMenu(
                self.iface.firstRightStandardMenu().menuAction(), self.menu)
        else:
            self.iface.addPluginToMenu(u"&GeoGig", self.explorerAction)
            self.iface.addPluginToMenu(u"&GeoGig", self.configAction)
            self.iface.addPluginToMenu(u"&GeoGig", self.toolAction)

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())
        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
        except Exception as e:
            pass

    def setWarning(self, msg):
        QMessageBox.warning(None, 'Could not complete GeoGig command', msg,
                            QMessageBox.Ok)

    def setTool(self):
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)

    def openSettings(self):
        dlg = ConfigDialog()
        dlg.exec_()
class PdokServicesPlugin(object):
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface

        # docked or dialog, defaults to dialog
        # 2018 may: RD: deprecating Docked window, as the content is getting to big anyway
        # if isinstance(QSettings().value("/pdokservicesplugin/docked"), QVariant):
        #     self.docked = QSettings().value("/pdokservicesplugin/docked", QVariant(False))
        # else:
        #     self.docked = QSettings().value("/pdokservicesplugin/docked", False)
        #
        # # Create the dialog and keep reference
        # if "True" == self.docked or "true" == self.docked or True is self.docked:
        #     self.dlg = PdokServicesPluginDockWidget()
        #     self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dlg)
        # else:
        #     self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow())

        self.dlg = PdokServicesPluginDialog(parent=self.iface.mainWindow())
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        self.currentLayer = None
        self.SETTINGS_SECTION = '/pdokservicesplugin/'
        self.pointer = None
        self.pdokgeocoder = PDOKGeoLocator(self.iface)
        self.geocoderSourceModel = None

    def getSettingsValue(self, key, default=''):
        if QSettings().contains(self.SETTINGS_SECTION + key):
            key = self.SETTINGS_SECTION + key
            if Qgis.QGIS_VERSION_INT < 10900:  # qgis <= 1.8
                return str(QSettings().value(key).toString())
            else:
                return str(QSettings().value(key))
        else:
            return default

    def setSettingsValue(self, key, value):
        key = self.SETTINGS_SECTION + key
        if Qgis.QGIS_VERSION_INT < 10900:
            # qgis <= 1.8
            QSettings().setValue(key, QVariant(value))
        else:
            QSettings().setValue(key, value)

    def initGui(self):
        # Create action that will start plugin configuration
        self.runIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_add_service.svg'))

        self.run_action = QAction(self.runIcon, "PDOK Services plugin",
                                  self.iface.mainWindow())

        self.run_button = QToolButton()
        self.run_button.setMenu(QMenu())
        self.run_button.setPopupMode(QToolButton.MenuButtonPopup)
        self.run_button.setDefaultAction(self.run_action)

        self.servicesLoaded = False
        # connect the action to the run method
        self.run_action.triggered.connect(self.run)
        self.setupfq()

        # Add toolbar button and menu item
        #self.iface.addToolBarIcon(self.action)

        self.toolbar = self.iface.addToolBar("PDOK services plugin")
        self.toolbar.setObjectName("PDOK services plugin")
        #self.toolbar.addAction(self.run_action)
        self.toolbar.addWidget(self.run_button)

        #self.run_button.menu().addSection('Favorieten')

        self.favourite_1_action = QAction('Favoriet 1',
                                          self.iface.mainWindow())
        self.favourite_1_action.setIcon(self.runIcon)
        self.favourite_1_action.triggered.connect(
            lambda: self.load_favourite(1))
        self.set_favourite_action(self.favourite_1_action, 1)
        self.run_button.menu().addAction(self.favourite_1_action)

        self.favourite_2_action = QAction('Favoriet 2',
                                          self.iface.mainWindow())
        self.favourite_2_action.setIcon(self.runIcon)
        self.favourite_2_action.triggered.connect(
            lambda: self.load_favourite(2))
        self.set_favourite_action(self.favourite_2_action, 2)
        self.run_button.menu().addAction(self.favourite_2_action)

        # TODO :-)
        #self.run_button.menu().addSection('Meest Recent')
        #self.run_button.menu().addSeparator()

        self.toolbarSearch = QLineEdit()
        self.toolbarSearch.setMaximumWidth(200)
        self.toolbarSearch.setAlignment(Qt.AlignLeft)
        self.toolbarSearch.setPlaceholderText("PDOK Locatieserver zoek")
        self.toolbar.addWidget(self.toolbarSearch)
        self.toolbarSearch.returnPressed.connect(self.searchAddressFromToolbar)
        # address/point cleanup
        eraserIcon = QIcon(
            os.path.join(self.plugin_dir, 'icon_remove_cross.svg'))
        self.clean_action = QAction(eraserIcon, "Cleanup", self.eraseAddress())
        self.toolbar.addAction(self.clean_action)
        self.clean_action.triggered.connect(self.eraseAddress)
        self.clean_action.setEnabled(False)

        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.run_action)

        # about
        self.aboutAction = QAction(QIcon(":/plugins/pdokservicesplugin/icon_help.png"), \
                            "About", self.iface.mainWindow())
        self.aboutAction.setWhatsThis("Pdok Services Plugin About")
        self.iface.addPluginToMenu(u"&Pdok Services Plugin", self.aboutAction)

        self.aboutAction.triggered.connect(self.about)
        self.dlg.ui.btnLoadLayer.clicked.connect(self.loadService)

        self.dlg.geocoderSearch.returnPressed.connect(self.searchAddress)

        self.dlg.geocoderSearch.textEdited.connect(self.searchAddress)
        self.dlg.geocoderSearch.setPlaceholderText(
            "PDOK Locatieserver zoek, bv postcode of postcode huisnummer")

        self.dlg.geocoderResultSearch.textChanged.connect(
            self.filterGeocoderResult)
        self.dlg.geocoderResultSearch.setPlaceholderText(
            "een of meer zoekwoorden uit resultaat")
        #self.iface.mapCanvas().renderStarting.connect(self.extentsChanged)

        ui = self.dlg.ui
        cbxs = [
            ui.cbx_gem, ui.cbx_wpl, ui.cbx_weg, ui.cbx_pcd, ui.cbx_adr,
            ui.cbx_pcl, ui.cbx_hmp
        ]
        # connect all fq checkboxes with suggest, so upon a change in fq filter we re-search
        for cbx in cbxs:
            cbx.stateChanged.connect(self.searchAddress)

        self.run(True)

    # for now hiding the pointer as soon as the extent changes
    #def extentsChanged(self):
    #    self.removePointer()

    # 2021-02 hiding the check JSON: to much hassle
    def checkPdokJson(self):
        myversion = self.getSettingsValue('pdokversion', '1')
        msgtxt = ''
        msglvl = 0  # QgsMessageBar.INFO
        try:
            response = urllib.request.urlopen(
                'http://www.qgis.nl/pdok.version')
            str_response = response.read().decode('utf-8')
            pdokversion = json.loads(str_response)
            if pdokversion > int(myversion):
                response = urllib.request.urlopen(
                    'http://www.qgis.nl/pdok.json')
                str_response = response.read().decode('utf-8')
                pdokjson = json.loads(str_response)
                with open(os.path.join(self.plugin_dir, 'pdok.json'),
                          'w') as outfile:
                    json.dump(pdokjson, outfile)
                msgtxt = "De laatste versie is opgehaald en zal worden gebruikt " + \
                    str(pdokversion) + ' (was ' + myversion +')'
                self.servicesLoaded = False  # reset reading of json
                self.run()
                self.setSettingsValue('pdokversion', pdokversion)
            else:
                msgtxt = "Geen nieuwere versie beschikbaar dan " + str(
                    pdokversion)
        except Exception as e:
            #print e
            msgtxt = "Fout bij ophalen van service info. Netwerk probleem?"
            msglvl = 2  # QgsMessageBar.CRITICAL
        # msg
        if hasattr(self.iface, 'messageBar'):
            self.iface.messageBar().pushMessage("PDOK services update",
                                                msgtxt,
                                                level=msglvl,
                                                duration=10)
        else:  # 1.8
            QMessageBox.information(self.iface.mainWindow(),
                                    "Pdok Services Plugin", msgtxt)

    def showAndRaise(self):
        self.dlg.show()
        self.dlg.raise_()
        # also remove the pointer
        self.removePointer()

    def about(self):
        infoString = "Written by Richard Duivenvoorde\nEmail - [email protected]\n"
        infoString += "Company - Zuidt - http://www.zuidt.nl\n"
        infoString += "Source: https://github.com/rduivenvoorde/pdokservicesplugin"
        QMessageBox.information(self.iface.mainWindow(),
                                "Pdok Services Plugin About", infoString)

    def unload(self):
        self.removePointer()
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu("&Pdok Services Plugin", self.run_action)
        self.iface.removePluginMenu("&Pdok Services Plugin", self.aboutAction)
        del self.toolbarSearch
        del self.run_action
        del self.aboutAction

    def showService(self, selectedIndexes):
        if len(selectedIndexes) == 0:
            self.currentLayer = None
            self.dlg.ui.layerInfo.setHtml('')
            self.dlg.ui.comboSelectProj.clear()
            return
        # needed to scroll To the selected row incase of using the keyboard / arrows
        self.dlg.servicesView.scrollTo(
            self.dlg.servicesView.selectedIndexes()[0])
        # itemType holds the data (== column 1)
        self.currentLayer = self.dlg.servicesView.selectedIndexes()[1].data(
            Qt.UserRole)
        if isinstance(self.currentLayer, QVariant):
            self.currentLayer = self.currentLayer.toMap()
            # QGIS 1.8: QVariants
            currentLayer = {}
            for key in list(self.currentLayer.keys()):
                val = self.currentLayer[key]
                currentLayer[str(key)] = str(val.toString())
            self.currentLayer = currentLayer
        url = self.currentLayer['url']
        title = self.currentLayer['title']
        style = ''
        if 'style' in self.currentLayer:
            style = self.currentLayer['style']
            title += f' [{style}]'
        servicetitle = self.currentLayer['servicetitle']
        layername = self.currentLayer['layers']
        abstract = self.currentLayer['abstract']
        stype = self.currentLayer['type'].upper()
        minscale = ''
        if 'minscale' in self.currentLayer and self.currentLayer[
                'minscale'] != None and self.currentLayer['minscale'] != '':
            minscale = "min. schaal 1:" + self.currentLayer['minscale']
        maxscale = ''
        if 'maxscale' in self.currentLayer and self.currentLayer[
                'maxscale'] != None and self.currentLayer['maxscale'] != '':
            maxscale = "max. schaal 1:" + self.currentLayer['maxscale']
        self.dlg.ui.layerInfo.setText('')
        self.dlg.ui.btnLoadLayer.setEnabled(True)
        self.dlg.ui.layerInfo.setHtml(
            '<h4>%s</h4><h3>%s</h3><lu><li>%s</li><li>&nbsp;</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li><li>%s</li></lu>'
            % (servicetitle, title, abstract, stype, url, layername, style,
               minscale, maxscale))
        self.dlg.ui.comboSelectProj.clear()
        if stype == "WMS":
            try:
                crs = self.currentLayer['crs']
            except KeyError:
                crs = 'EPSG:28992'
            crs = crs.split(',')
            self.dlg.ui.comboSelectProj.addItems(crs)
            for i in range(len(crs)):
                if crs[i] == 'EPSG:28992':
                    self.dlg.ui.comboSelectProj.setCurrentIndex(i)
        if stype == "WMTS":
            tilematrixsets = self.currentLayer['tilematrixsets'].split(',')
            self.dlg.ui.comboSelectProj.addItems(tilematrixsets)
            for i in range(len(tilematrixsets)):
                if tilematrixsets[i].startswith('EPSG:28992'):
                    self.dlg.ui.comboSelectProj.setCurrentIndex(i)

    def set_favourite_action(self, action, favourite_number):
        if QSettings().contains(
                f'/pdokservicesplugin/favourite_{favourite_number}'):
            layer = QSettings().value(
                f'/pdokservicesplugin/favourite_{favourite_number}', None)
            if layer:
                action.setToolTip(layer['title'].capitalize())
                title = layer['title'].capitalize()
                if 'style' in layer:
                    style = layer['style']
                    title += f' [{style}]'
                if 'type' in layer:
                    stype = layer['type'].upper()
                    title += f' ({stype})'
                action.setText(title)
                action.setIcon(self.runIcon)

    def load_favourite(self, favourite_number):
        if QSettings().contains(
                f'/pdokservicesplugin/favourite_{favourite_number}'):
            layer = QSettings().value(
                f'/pdokservicesplugin/favourite_{favourite_number}', None)
            if layer and layer in self.pdok['services']:
                self.currentLayer = layer
                self.loadService()
                return
        QMessageBox.warning(self.iface.mainWindow(), "Geen Favoriet aanwezig (of verouderd)...", ( \
            "Maak een Favoriet aan door in de dialoog met services en lagen\n via het context menu (rechter muisknop) een Favoriet te kiezen..."
            ), QMessageBox.Ok, QMessageBox.Ok)
        self.run()

    def loadService(self):
        if self.currentLayer == None:
            return
        servicetype = self.currentLayer['type']
        url = self.currentLayer['url']
        # some services have an url with query parameters in it, we have to urlencode those:
        location, query = urllib.parse.splitquery(url)
        url = location
        # RD: 20200820: lijkt of het quoten van de query problemen geeft bij WFS, is/was dit nodig???
        #if query != None and query != '':
        #    url +=('?'+urllib.parse.quote_plus(query))
        title = self.currentLayer['title']
        if 'style' in self.currentLayer:
            style = self.currentLayer['style']
            title += f' [{style}]'
        else:
            style = ''  # == default for this service
        layers = self.currentLayer['layers']
        # mmm, tricky: we take the first one while we can actually want png/gif or jpeg
        if servicetype == "wms":
            imgformat = self.currentLayer['imgformats'].split(',')[0]
            if self.dlg.ui.comboSelectProj.currentIndex() == -1:
                crs = 'EPSG:28992'
            else:
                crs = self.dlg.ui.comboSelectProj.currentText()
            if Qgis.QGIS_VERSION_INT < 10900:
                # qgis <= 1.8
                uri = url
                self.iface.addRasterLayer(
                    uri,  # service uri
                    title,  # name for layer (as seen in QGIS)
                    "wms",  # dataprovider key
                    [layers],  # array of layername(s) for provider (id's)
                    [""
                     ],  # array of stylename(s)  NOTE: ignoring styles here!!!
                    imgformat,  # image format searchstring
                    crs)  # crs code searchstring
            else:
                # qgis > 1.8
                uri = "crs=" + crs + "&layers=" + layers + "&styles=" + style + "&format=" + imgformat + "&url=" + url
                self.iface.addRasterLayer(uri, title, "wms")
        elif servicetype == "wmts":
            if Qgis.QGIS_VERSION_INT < 10900:
                QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", (
                    "Sorry, dit type layer: '" + servicetype.upper() +
                    "' \nkan niet worden geladen in deze versie van QGIS.\nMisschien kunt u QGIS 2.0 installeren (die kan het WEL)?\nOf is de laag niet ook beschikbaar als wms of wfs?"
                ), QMessageBox.Ok, QMessageBox.Ok)
                return
            if self.dlg.ui.comboSelectProj.currentIndex() == -1:
                tilematrixset = 'EPSG:28992'
            else:
                tilematrixset = self.dlg.ui.comboSelectProj.currentText()
            imgformat = self.currentLayer['imgformats'].split(',')[0]
            # special case for luchtfoto
            #if layers=="luchtfoto":
            #    # tileMatrixSet=nltilingschema&crs=EPSG:28992&layers=luchtfoto&styles=&format=image/jpeg&url=http://geodata1.nationaalgeoregister.nl/luchtfoto/wmts/1.0.0/WMTSCapabilities.xml
            #    # {u'layers': u'luchtfoto', u'imgformats': u'image/jpeg', u'title': u'PDOK-achtergrond luchtfoto', u'url': u'http://geodata1.nationaalgeoregister.nl/luchtfoto/wms', u'abstract': u'', u'tilematrixsets': u'nltilingschema', u'type': u'wmts'}
            #    uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url
            #else:
            #    uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=&format="+imgformat+"&url="+url;
            #uri = "tileMatrixSet="+tilematrixsets+"&crs=EPSG:28992&layers="+layers+"&styles=default&format="+imgformat+"&url="+url;
            if tilematrixset.startswith('EPSG:'):
                crs = tilematrixset
                i = crs.find(':', 5)
                if i > -1:
                    crs = crs[:i]
            elif tilematrixset.startswith('OGC:1.0'):
                crs = 'EPSG:3857'
            uri = "tileMatrixSet=" + tilematrixset + "&crs=" + crs + "&layers=" + layers + "&styles=default&format=" + imgformat + "&url=" + url
            #print "############ PDOK URI #################"
            #print uri
            self.iface.addRasterLayer(uri, title, "wms")
        elif servicetype == "wfs":
            location, query = urllib.parse.splitquery(url)
            #uri = location+"?SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME="+layers+"&SRSNAME=EPSG:28992"
            #uri = location + "?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=" + layers + "&SRSNAME=EPSG:28992"
            # adding a bbox paramater forces QGIS to NOT cache features but retrieve new features all the time
            # QGIS will update the BBOX to the right value
            #uri += "&BBOX=-10000,310000,290000,650000"
            uri = " pagingEnabled='true' restrictToRequestBBOX='1' srsname='EPSG:28992' typename='" + layers + "' url='" + url + "' version='2.0.0' "
            self.iface.addVectorLayer(uri, title, "WFS")
        elif servicetype == "wcs":
            # cache=AlwaysCache&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs
            uri = ''
            # cache=AlwaysCache
            # cache=PreferNetwork
            # cache=AlwaysNetwork
            # cache=AlwaysNetwork&crs=EPSG:28992&format=GeoTIFF&identifier=ahn25m:ahn25m&url=http://geodata.nationaalgeoregister.nl/ahn25m/wcs
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.1&identifier="+layers+"&url="+url
            # working for ahn1 ahn2 and ahn3: GEOTIFF_FLOAT32
            format = 'GEOTIFF_FLOAT32'
            # working for ahn25m is only image/tiff
            if layers == 'ahn25m':
                format = 'image/tiff'
            # we handcrated some wcs layers with 2 different image formats: tiff (RGB) and tiff (float32):
            if 'imgformats' in self.currentLayer:
                format = self.currentLayer['imgformats'].split(',')[0]
            uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=" + format + "&identifier=" + layers + "&url=" + url
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format="+format+"&version=1.1.2&identifier=" + layers + "&url=" + url
            #uri = "cache=AlwaysNetwork&crs=EPSG:28992&format=image/tiff&version=1.1.2&identifier=" + layers + "&url=" + url
            self.iface.addRasterLayer(uri, title, "wcs")
        else:
            QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", (
                "Sorry, dit type layer: '" + servicetype.upper() +
                "' \nkan niet worden geladen door de plugin of door QGIS.\nIs het niet beschikbaar als wms, wmts of wfs?"
            ), QMessageBox.Ok, QMessageBox.Ok)
            return

    def filterGeocoderResult(self, string):
        #print "filtering geocoder results: %s" % string
        self.dlg.geocoderResultView.selectRow(0)
        self.geocoderProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.geocoderProxyModel.setFilterFixedString(string)

    def searchAddressFromToolbar(self):
        self.removePointer()
        self.geocoderSourceModel.clear()
        self.geocode()

    def searchAddress(self):
        self.removePointer()
        #print "search geocoder for: %s" % self.dlg.geocoderSearch.text()
        self.geocoderSourceModel.clear()
        #self.geocode(self.dlg.geocoderSearch.text())
        self.suggest()

    def eraseAddress(self):
        """
        clean the input and remove the pointer
        """
        self.removePointer()
        if self.geocoderSourceModel is not None:
            self.geocoderSourceModel.clear()
        if self.dlg.geocoderSearch is not None:
            self.dlg.geocoderSearch.clear()
        if self.toolbarSearch is not None:
            self.toolbarSearch.clear()

    def filterLayers(self, string):
        # remove selection if one row is selected
        self.dlg.servicesView.selectRow(0)
        #self.currentLayer = None
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setFilterFixedString(string)

    #def addSourceRow(self, service, layer):
    def addSourceRow(self, serviceLayer):
        # you can attache different "data's" to to an QStandarditem
        # default one is the visible one:
        itemType = QStandardItem("%s" % (serviceLayer["type"].upper()))
        # userrole is a free form one:
        # only attach the data to the first item
        # service layer = a dict/object with all props of the layer
        itemType.setData(serviceLayer, Qt.UserRole)
        itemType.setToolTip(
            "%s - %s" % (serviceLayer["type"].upper(), serviceLayer["title"]))
        # only wms services have styles (sometimes)
        layername = serviceLayer["title"]
        if 'style' in serviceLayer:
            itemLayername = QStandardItem(
                "%s [%s]" % (serviceLayer["title"], serviceLayer["style"]))
            layername = "%s [%s]" % (serviceLayer["title"],
                                     serviceLayer["style"])
        else:
            itemLayername = QStandardItem("%s" % (serviceLayer["title"]))
        itemLayername.setToolTip(
            "%s - %s" %
            (serviceLayer["type"].upper(), serviceLayer["servicetitle"]))
        # itemFilter is the item used to search filter in. That is why layername is a combi of layername + filter here
        itemFilter = QStandardItem(
            "%s %s %s %s" %
            (serviceLayer["type"], layername, serviceLayer["servicetitle"],
             serviceLayer["abstract"]))
        itemServicetitle = QStandardItem("%s" % (serviceLayer["servicetitle"]))
        itemServicetitle.setToolTip(
            "%s - %s" % (serviceLayer["type"].upper(), serviceLayer["title"]))
        self.sourceModel.appendRow(
            [itemLayername, itemType, itemServicetitle, itemFilter])

    # run method that performs all the real work
    def run(self, hiddenDialog=False):

        # enable possible remote pycharm debugging
        #import pydevd
        #pydevd.settrace('localhost', port=5678, stdoutToServer=True, stderrToServer=True)

        # last viewed/selected tab
        if QSettings().contains("/pdokservicesplugin/currenttab"):
            if Qgis.QGIS_VERSION_INT < 10900:
                # qgis <= 1.8
                self.dlg.tabs.widget(QSettings().value(
                    "/pdokservicesplugin/currenttab").toInt()[0])
            else:
                self.dlg.tabs.widget(
                    int(QSettings().value("/pdokservicesplugin/currenttab")))

        if self.servicesLoaded == False:
            pdokjson = os.path.join(self.plugin_dir, "pdok.json")
            with open(pdokjson, 'r', encoding='utf-8') as f:
                self.pdok = json.load(f)
                print(f'self.pdok type = {type(self.pdok)}')

            self.proxyModel = QSortFilterProxyModel()
            self.sourceModel = QStandardItemModel()
            self.proxyModel.setSourceModel(self.sourceModel)
            # filter == search on itemFilter column:
            self.proxyModel.setFilterKeyColumn(3)
            self.dlg.servicesView.setModel(self.proxyModel)
            self.dlg.servicesView.setEditTriggers(
                QAbstractItemView.NoEditTriggers)

            self.geocoderProxyModel = QSortFilterProxyModel()
            self.geocoderSourceModel = QStandardItemModel()

            self.geocoderProxyModel.setSourceModel(self.geocoderSourceModel)
            self.geocoderProxyModel.setFilterKeyColumn(0)
            self.dlg.geocoderResultView.setModel(self.geocoderProxyModel)
            self.dlg.geocoderResultView.setEditTriggers(
                QAbstractItemView.NoEditTriggers)

            #{"services":[
            #   {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"},
            #   {"naam":"WMS NHI","url":"http://geodata.nationaalgeoregister.nl/nhi/ows","layers":["dmlinks","dmnodes"],"type":"wms"}
            # ]}
            #
            for service in self.pdok["services"]:
                # service[layer] was an array
                if isinstance(service["layers"], str):
                    self.addSourceRow(service)

            self.dlg.layerSearch.textChanged.connect(self.filterLayers)
            self.dlg.layerSearch.setPlaceholderText(
                "woord uit laagnaam, type of service ")
            self.dlg.servicesView.selectionModel().selectionChanged.connect(
                self.showService)
            self.dlg.servicesView.doubleClicked.connect(self.loadService)

            self.dlg.servicesView.setContextMenuPolicy(Qt.CustomContextMenu)
            self.dlg.servicesView.customContextMenuRequested.connect(
                self.make_favourite)

            # actually I want to load a service when doubleclicked on header
            # but as I cannot get this to work, let's disable clicking it then
            self.dlg.servicesView.verticalHeader().setSectionsClickable(False)
            self.dlg.servicesView.horizontalHeader().setSectionsClickable(
                False)

            #self.dlg.geocoderResultView.doubleClicked.connect(self.zoomToAddress)
            self.dlg.geocoderResultView.selectionModel(
            ).selectionChanged.connect(self.zoomToAddress)

            # hide itemFilter column:
            self.dlg.servicesView.hideColumn(3)
            self.servicesLoaded = True

        self.sourceModel.setHeaderData(2, Qt.Horizontal, "Service")
        self.sourceModel.setHeaderData(1, Qt.Horizontal, "Type")
        self.sourceModel.setHeaderData(0, Qt.Horizontal, "Laagnaam [style]")
        self.sourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft)
        self.sourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft)
        self.sourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft)
        #self.dlg.servicesView.verticalHeader().hide()
        #self.dlg.servicesView.resizeColumnsToContents()
        self.dlg.servicesView.setColumnWidth(
            0, 300)  # set name to 300px (there are some huge layernames)
        self.dlg.servicesView.horizontalHeader().setStretchLastSection(True)
        # show the dialog ?
        if not hiddenDialog:
            self.dlg.show()
        # Run the dialog event loop
        #result = self.dlg.exec_()
        if Qgis.QGIS_VERSION_INT < 10900:
            # qgis <= 1.8
            QSettings().setValue("/pdokservicesplugin/currenttab",
                                 QVariant(self.dlg.tabs.currentIndex()))
        else:
            QSettings().setValue("/pdokservicesplugin/currenttab",
                                 self.dlg.tabs.currentIndex())
        self.removePointer()

    def make_favourite(self, position):
        menu = QMenu()
        create_fav1_action = menu.addAction("Maak Deze Laag Favoriet 1")
        create_fav2_action = menu.addAction("Maak Deze Laag Favoriet 2")
        action = menu.exec_(self.dlg.servicesView.mapToGlobal(position))
        if action == create_fav1_action:
            QSettings().setValue("/pdokservicesplugin/favourite_1",
                                 self.currentLayer)
            self.set_favourite_action(self.favourite_1_action, 1)
        elif action == create_fav2_action:
            QSettings().setValue("/pdokservicesplugin/favourite_2",
                                 self.currentLayer)
            self.set_favourite_action(self.favourite_2_action, 2)

    def setupfq(self):
        """
        Setup the fq checkboxes in the gui, by looking into the settings for the
        'pdokservicesplugin/checkedfqs' key, which contains a list of type strings
        like ['weg','adres']
        """
        checked_fqs = self.getSettingsValue('checkedfqs', [])
        #self.info('setup fq: {}'.format(checked_fqs))
        if len(checked_fqs
               ) > 0:  # else there is not saved state... take gui defaults
            self.dlg.ui.cbx_gem.setChecked('gemeente' in checked_fqs)
            self.dlg.ui.cbx_wpl.setChecked('woonplaats' in checked_fqs)
            self.dlg.ui.cbx_weg.setChecked('weg' in checked_fqs)
            self.dlg.ui.cbx_pcd.setChecked('postcode' in checked_fqs)
            self.dlg.ui.cbx_adr.setChecked('adres' in checked_fqs)
            self.dlg.ui.cbx_pcl.setChecked('perceel' in checked_fqs)
            self.dlg.ui.cbx_hmp.setChecked('hectometerpaal' in checked_fqs)

    def createfq(self):
        """
        This creates a fq-string (Filter Query, see https://github.com/PDOK/locatieserver/wiki/Zoekvoorbeelden-Locatieserver)
        Based on the checkboxes in the dialog.
        Defaults to ''
        Example: 'fq=+type:adres+type:gemeente'  (only gemeente AND addresses)
        :return:
        """
        fqlist = []
        if self.dlg.ui.cbx_gem.isChecked():
            fqlist.append('gemeente')
        if self.dlg.ui.cbx_wpl.isChecked():
            fqlist.append('woonplaats')
        if self.dlg.ui.cbx_weg.isChecked():
            fqlist.append('weg')
        if self.dlg.ui.cbx_pcd.isChecked():
            fqlist.append('postcode')
        if self.dlg.ui.cbx_adr.isChecked():
            fqlist.append('adres')
        if self.dlg.ui.cbx_pcl.isChecked():
            fqlist.append('perceel')
        if self.dlg.ui.cbx_hmp.isChecked():
            fqlist.append('hectometerpaal')
        self.setSettingsValue('checkedfqs', fqlist)
        #self.info(self.getSettingsValue('checkedfqs', ['leeg?']))
        fq = ''
        if len(fqlist) > 0:
            fq = '&fq=+type:' + '+type:'.join(fqlist)
        return fq

    def suggest(self):
        self.dlg.ui.lookupinfo.setHtml('')
        search_text = self.dlg.geocoderSearch.text()
        if len(search_text) <= 1:
            # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
            #     "meer input aub: {}".format(search_text)
            #     ), QMessageBox.Ok, QMessageBox.Ok)
            return
        # QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
        #     "zoeken: {}".format(search_text)
        # ), QMessageBox.Ok, QMessageBox.Ok)
        results = self.pdokgeocoder.suggest(search_text, self.createfq())
        if len(results) == 0:
            # ignore, as we are suggesting, maybe more characters will reveal something...
            return
        for result in results:
            #print address
            adrestekst = QStandardItem("%s" % (result["adrestekst"]))
            adrestekst.setData(result, Qt.UserRole)
            type = QStandardItem("%s" % (result["type"]))
            id = QStandardItem("%s" % (result["id"]))
            score = QStandardItem("%s" % (result["score"]))
            adrestekst.setData(result, Qt.UserRole)
            self.geocoderSourceModel.appendRow([adrestekst, type])
        self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat")
        self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Type")
        self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(
            Qt.AlignLeft)
        self.dlg.geocoderResultView.resizeColumnsToContents()
        self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(
            True)

    def geocode(self):
        self.dlg.geocoderSearch.setText(self.toolbarSearch.text())
        self.suggest()
        if self.dlg.geocoderResultView.model().rowCount() > 0:
            self.dlg.geocoderResultView.selectRow(0)
            self.zoomToAddress()
        else:
            QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
                "Niets gevonden.\nProbeer een andere spelling, of alleen postcode/huisnummer?\n\nSelecteer meer (Locatieserver) 'typen' in de PdokServicesPlugin dialoog.\n\nOf gebruik de 'PDOK geocoder'-tab in de PdokServicesPlugin dialoog."
                ), QMessageBox.Ok, QMessageBox.Ok)

    # def geocode(self):
    #     self.dlg.ui.lookupinfo.setHtml('')
    #     search_text = self.toolbarSearch.text()
    #     addresses = self.pdokgeocoder.search(search_text)
    #     if len(addresses) == 0:
    #         QMessageBox.warning(self.iface.mainWindow(), "PDOK plugin", ( \
    #             "Niets gevonden. Probeer een andere spelling of alleen postcode/huisnummer."
    #             ), QMessageBox.Ok, QMessageBox.Ok)
    #         return
    #     for address in addresses:
    #         #print address
    #         adrestekst = QStandardItem("%s" % (address["adrestekst"]))
    #         adrestekst.setData(address, Qt.UserRole)
    #         straat = QStandardItem("%s" % (address["straat"]))
    #         nummer = QStandardItem("%s" % (address["nummer"]))
    #         postcode = QStandardItem("%s" % (address["postcode"]))
    #         plaats = QStandardItem("%s" % (address["plaats"]))
    #         gemeente = QStandardItem("%s" % (address["gemeente"]))
    #         provincie = QStandardItem("%s" % (address["provincie"]))
    #         self.geocoderSourceModel.appendRow([adrestekst, straat, nummer, postcode, plaats, gemeente, provincie])
    #
    #     self.dlg.geocoderResultView.selectRow(0)
    #     self.zoomToAddress()
    #
    #     self.geocoderSourceModel.setHeaderData(0, Qt.Horizontal, "Resultaat")
    #     self.geocoderSourceModel.setHeaderData(1, Qt.Horizontal, "Straat")
    #     self.geocoderSourceModel.setHeaderData(2, Qt.Horizontal, "Nr")
    #     self.geocoderSourceModel.setHeaderData(3, Qt.Horizontal, "Postcode")
    #     self.geocoderSourceModel.setHeaderData(4, Qt.Horizontal, "Plaats")
    #     self.geocoderSourceModel.setHeaderData(5, Qt.Horizontal, "Gemeente")
    #     self.geocoderSourceModel.setHeaderData(6, Qt.Horizontal, "Provincie")
    #
    #     self.geocoderSourceModel.horizontalHeaderItem(0).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(1).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(2).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(3).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(4).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(5).setTextAlignment(Qt.AlignLeft)
    #     self.geocoderSourceModel.horizontalHeaderItem(6).setTextAlignment(Qt.AlignLeft)
    #
    #     self.dlg.geocoderResultView.resizeColumnsToContents()
    #     self.dlg.geocoderResultView.horizontalHeader().setStretchLastSection(True)

    def zoomToAddress(self):
        # get x,y from data of record
        self.removePointer()

        data = self.dlg.geocoderResultView.selectedIndexes()[0].data(
            Qt.UserRole)

        if 'centroide_rd' in data:  # free OR lookup service
            geom = QgsGeometry.fromWkt(data['centroide_rd'])
            adrestekst = data['adrestekst']
        else:
            # no centroid yet, probably only object id, retrieve it via lookup service
            id = data['id']
            data = self.pdokgeocoder.lookup(id)
            geom = QgsGeometry.fromWkt(data['centroide_rd'])
            adrestekst = data['adrestekst']
            lookup_data = data['data']
            lis = ''
            for key in lookup_data.keys():
                lis = lis + '<li>{}: {}</li>'.format(key, lookup_data[key])
            self.dlg.ui.lookupinfo.setHtml('<h4>{}</h4><lu>{}</lu>'.format(
                adrestekst, lis))

        # just always transform from 28992 to mapcanvas crs
        crs = self.iface.mapCanvas().mapSettings().destinationCrs()
        crs28992 = QgsCoordinateReferenceSystem()
        crs28992.createFromId(28992)
        crsTransform = QgsCoordinateTransform(crs28992, crs,
                                              QgsProject.instance())
        z = 1587
        if adrestekst.lower().startswith('adres'):
            z = 794
        elif adrestekst.lower().startswith('perceel'):
            z = 794
        elif adrestekst.lower().startswith('hectometer'):
            z = 1587
        elif adrestekst.lower().startswith('straat'):
            z = 3175
        elif adrestekst.lower().startswith('postcode'):
            z = 6350
        elif adrestekst.lower().startswith('woonplaats'):
            z = 25398
        elif adrestekst.lower().startswith('gemeente'):
            z = 50797
        elif adrestekst.lower().startswith('provincie'):
            z = 812750
        geom.transform(crsTransform)
        center = geom.asPoint()
        self.setPointer(center)
        # zoom to with center is actually setting a point rectangle and then zoom
        rect = QgsRectangle(center, center)
        self.iface.mapCanvas().setExtent(rect)
        self.iface.mapCanvas().zoomScale(z)
        self.iface.mapCanvas().refresh()

    def setPointer(self, point):
        self.removePointer()
        self.pointer = QgsVertexMarker(self.iface.mapCanvas())
        self.pointer.setColor(QColor(255, 255, 0))
        self.pointer.setIconSize(10)
        self.pointer.setPenWidth(5)
        self.pointer.setCenter(point)
        self.clean_action.setEnabled(True)

    def removePointer(self):
        if self.pointer is not None and self.pointer.scene() is not None:
            self.iface.mapCanvas().scene().removeItem(self.pointer)
            self.pointer = None
            self.clean_action.setEnabled(False)

    def info(self, msg=""):
        QgsMessageLog.logMessage('{}'.format(msg), 'PDOK-services Plugin',
                                 Qgis.Info)
예제 #14
0
    def initGui(self):
        """startup"""

        parent = self.iface.mainWindow()

        ######## action, button

        icon = QIcon("%s/%s" % (config.PLUGIN_DIR, "images/xyz.png"))
        icon_bbox = QIcon("%s/%s" % (config.PLUGIN_DIR, "images/bbox.svg"))
        self.action_connect = QAction(icon, "New XYZ Hub Connection", parent)
        self.action_connect.setWhatsThis(
            QCoreApplication.translate(PLUGIN_NAME, "WhatsThis message"))
        self.action_connect.setStatusTip(
            QCoreApplication.translate(PLUGIN_NAME, "status tip message"))

        self.action_clear_cache = QAction("Clear cache", parent)
        self.action_upload = QAction("Upload to New XYZ Geospace", parent)
        self.action_basemap = QAction("Add HERE Map Tile", parent)

        self.action_magic_sync = QAction("Magic Sync (EXPERIMENTAL)", parent)
        self.action_manage = QAction("Manage XYZ Geospace (EXPERIMENTAL)",
                                     parent)
        self.action_edit = QAction("Edit/Delete XYZ Geospace (EXPERIMENTAL)",
                                   parent)

        if self.iface.activeLayer() is None:
            # self.action_upload.setEnabled(False)
            self.action_edit.setEnabled(False)
            self.action_magic_sync.setEnabled(False)

        # self.action_magic_sync.setVisible(False) # disable magic sync

        ######## CONNECT action, button

        self.action_connect.triggered.connect(self.open_connection_dialog)
        self.action_manage.triggered.connect(self.open_manage_dialog)
        self.action_edit.triggered.connect(self.open_edit_dialog)
        self.action_upload.triggered.connect(self.open_upload_dialog)
        self.action_magic_sync.triggered.connect(self.open_magic_sync_dialog)
        self.action_clear_cache.triggered.connect(self.open_clear_cache_dialog)
        self.action_basemap.triggered.connect(self.open_basemap_dialog)

        ######## Add the toolbar + button
        self.toolbar = self.iface.addToolBar(PLUGIN_NAME)
        self.toolbar.setObjectName("XYZ Hub Connector")

        tool_btn = QToolButton(self.toolbar)

        self.actions = [
            self.action_connect, self.action_upload, self.action_basemap,
            self.action_clear_cache
        ]  # , self.action_magic_sync, self.action_manage, self.action_edit
        for a in self.actions:
            tool_btn.addAction(a)
            self.iface.addPluginToWebMenu(self.web_menu, a)

        tool_btn.setDefaultAction(self.action_connect)
        tool_btn.setPopupMode(tool_btn.MenuButtonPopup)

        self.xyz_widget_action = self.toolbar.addWidget(tool_btn)

        self.action_help = None

        self.action_reload = QAction(icon_bbox, "Reload BBox", parent)
        self.action_reload.triggered.connect(self.layer_reload_bbox)
        self.action_reload.setVisible(False)  # disable
        self.toolbar.addAction(self.action_reload)

        progress = QProgressBar()
        progress.setMinimum(0)
        progress.setMaximum(0)
        progress.reset()
        progress.hide()
        # progress = self.iface.statusBarIface().children()[2] # will be hidden by qgis
        self.iface.statusBarIface().addPermanentWidget(progress)
        self.pb = progress
예제 #15
0
class UnderMap:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = join(
            self.plugin_dir,
            'i18n',
            'UnderMap_{}.qm'.format(locale))

        if exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Create the dialog (after translation) and keep reference
        self.dlg = UnderMapDialog()
        self.addop = AjouterOperateurDialog()
        self.addpdf = DialogAddPDF()
        self.splitpdf = DialogSplitPDF()
        self.importpoints = DialogImportPoint()
        self.zoomto = DialogZoomToFeature()

        # Initialise buttton
        self.init_button = QToolButton()
        self.init_button.setMenu(QMenu())
        self.init_button.setPopupMode(QToolButton.MenuButtonPopup)

        # toolBar
        self.toolbar = self.iface.addToolBar('UnderMap')
        self.toolbar.setObjectName('UnderMap')

        # actions
        self.initialisePDFAction = None
        self.reportAction = None
        self.addOperatorAction = None
        self.initialiseFDPAction = None
        self.initialiseEmpriseAction = None
        self.addPDFAction = None
        self.splitPDFAction = None
        self.importPointsAction = None
        self.mergeFeaturesAction = None
        self.manageBufferAction = None
        self.saveAsGeoJsonAndTfwAction = None
        self.controlAction = None
        self.zoomToAction = None

        QgsSettings().setValue("qgis/digitizing/reuseLastValues", True)
        # For enable/disable the addpdf editor icon
        self.iface.currentLayerChanged.connect(self.layer_changed)

        # For load layer on qgis
        self.iface.projectRead.connect(self.load_layer)

    @staticmethod
    def tr(message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('UnderMap', message)

    # noinspection PyPep8Naming
    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # the actions
        self.initialisePDFAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'initialpdf.png')),
            'Initialiser PDF',
            self.iface.mainWindow())

        self.addOperatorAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'ajouterOperateur.png')),
            'Ajouter un exploitant',
            self.iface.mainWindow())

        self.reportAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'report.png')),
            'Générer le rapport',
            self.iface.mainWindow())

        self.initialiseFDPAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'fdp.png')),
            'Initialiser un FDP',
            self.iface.mainWindow())

        self.initialiseEmpriseAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'icon.png')),
            'Initialiser une emprise',
            self.iface.mainWindow())

        self.addPDFAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'add_pdf.png')),
            'Ajouter pdf',
            self.iface.mainWindow())

        self.splitPDFAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'add_pdf.png')),
            'Découper un PDF',
            self.iface.mainWindow())

        self.importPointsAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'point.png')),
            'Importer les points de calage',
            self.iface.mainWindow())

        self.mergeFeaturesAction = QAction(
            QIcon(join(dirname(__file__), 'resources', '')),
            'Fusionner les entités',
            self.iface.mainWindow())

        self.manageBufferAction = QAction(
            QIcon(join(dirname(__file__), 'resources', '')),
            'Génerer les buffers',
            self.iface.mainWindow())

        self.saveAsGeoJsonAndTfwAction = QAction(
            QIcon(join(dirname(__file__), 'resources', '')),
            'Exporter les GeoJSON et les tfw',
            self.iface.mainWindow())

        self.controlAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'opacity.png')),
            'Contrôler',
            self.iface.mainWindow())

        self.zoomToAction = QAction(
            QIcon(join(dirname(__file__), 'resources', 'zoom-in.png')),
            'Zoom',
            self.iface.mainWindow())

        # actions dialogs
        self.initialisePDFAction.triggered.connect(self.initialise_PDF)
        self.addOperatorAction.triggered.connect(self.add_operator)
        self.initialiseFDPAction.triggered.connect(self.initialise_FDP)
        self.initialiseEmpriseAction.triggered.connect(self.initialise_emprise)
        self.reportAction.triggered.connect(self.export_report)
        self.addPDFAction.triggered.connect(self.add_pdf)
        self.splitPDFAction.triggered.connect(self.split_pdf)
        self.importPointsAction.triggered.connect(self.import_points)
        self.mergeFeaturesAction.triggered.connect(self.merge_features_layer)
        self.manageBufferAction.triggered.connect(self.manage_buffer)
        self.saveAsGeoJsonAndTfwAction.triggered.connect(self.save_geojson_tfw)
        self.controlAction.triggered.connect(self.control)
        self.zoomToAction.triggered.connect(self.zoom_to_feature)

        # add actions on menu
        self.init_button.menu().addAction(self.initialisePDFAction)
        self.init_button.menu().addAction(self.addOperatorAction)
        self.init_button.setDefaultAction(self.initialisePDFAction)
        # add separator

        # self.initialiseFDPAction.insertSeparator(self.initialisePDFAction)
        self.init_button.menu().addAction(self.initialiseFDPAction)
        self.init_button.menu().addAction(self.initialiseEmpriseAction)
        self.init_button.menu().addAction(self.splitPDFAction)
        self.init_button.menu().addAction(self.mergeFeaturesAction)
        self.init_button.menu().addAction(self.manageBufferAction)
        self.init_button.menu().addAction(self.saveAsGeoJsonAndTfwAction)

        # add actions and menu in toolbar
        self.toolbar.addWidget(self.init_button)
        self.toolbar.addAction(self.reportAction)
        self.toolbar.addAction(self.addPDFAction)
        self.toolbar.addAction(self.importPointsAction)
        self.toolbar.addAction(self.controlAction)
        self.toolbar.addAction(self.zoomToAction)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        self.iface.mainWindow().removeToolBar(self.toolbar)
        self.iface.currentLayerChanged.disconnect(self.layer_changed)

    def layer_changed(self, layer):

        try:
            layers = get_layers_in_group("RSX")
        except AttributeError:
            return
        if not hasattr(layer, 'name'):
            enable_addpdf = False

        elif layer.name() not in layers:
            enable_addpdf = False

        elif not hasattr(layer, 'providerType'):
            enable_addpdf = False
        elif layer.providerType() == 'wms':
            enable_addpdf = False
        elif not layer.geometryType() == 1:
            enable_addpdf = False
        else:
            enable_addpdf = True
        self.addPDFAction.setEnabled(enable_addpdf)

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass

    def add_operator(self):
        self.addop.exec_()

    def add_pdf(self):
        self.addpdf.exec_()

    def split_pdf(self):
        self.splitpdf.exec_()

    def import_points(self):
        self.importpoints.exec_()

    def zoom_to_feature(self):
        self.zoomto.exec_()

    def manage_buffer(self):
        project_path = get_project_path()
        manage_buffer(project_path)
        self.iface.messageBar().pushInfo('Undermap', "La génération des buffers a bien reussi."
                                                            )

    def control(self):

        transparency_raster()

    def initialise_PDF(self):
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None,"Avertisment","Veulliez ouvrir un projet qgis")
            return
        else:
            dir_selected = QFileDialog.getExistingDirectory(None, "Sélectionner un dossier", project_path,  QFileDialog.ShowDirsOnly)
            if dir_selected == '':
                self.iface.messageBar().pushWarning('Undermap', "Aucun dossier séléctionné")
                return
            else:
                initialise_pdf(dir_selected)
                QgsProject.instance().write()

    def initialise_FDP(self):
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None, "Avertisment", "Veulliez ouvrir un projet qgis")
            return
        else:
            fileSelected = QFileDialog.getOpenFileName(None, "Sélectionnez un fichier", project_path, "*.dxf")
            if fileSelected == ('', ''):
                self.iface.messageBar().pushWarning('Undermap', "Aucun fichier dxf séléctionné")
                return
            else:
                initialise_fdp(fileSelected)

    def initialise_emprise(self):
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None, "Avertissement", "Veuillez ouvrir un projet QGIS et l’enregistrer")
            return
        else:
            filter = "DXF(*.dxf);;KML(*.kml);;SHAPE(*.shp)"
            fileSelected = QFileDialog.getOpenFileName(None, "Sélectionnez un fichier", project_path, filter)
            if fileSelected == ('', ''):
                self.iface.messageBar().pushWarning('Undermap', "Aucun fichier séléctionné")
                return
            else:
                initialise_emprise(fileSelected)

    def export_report(self):
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None, "Avertisment", "Veuillez ouvrir un projet qgis")
            return
        else:
            if export_xlsx_report(project_path):
                self.iface.messageBar().pushInfo('Undermap', "La génération du rapport a bien reussi."
                                                            )
                os.startfile(join(project_path, QgsProject.instance().baseName()+'.xlsx'))
            else:
                QMessageBox.warning(None, 'Undermap', "QGIS ne peut pas écrire "
                                                         "le rapport car le fichier"
                                                             " {} est ouvert "
                                                         "dans une autre application"
                                                        .format(join(project_path, QgsProject.instance()
                                                        .baseName()+'.xlsx')))

    def save_geojson_tfw(self):
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None, "Avertisment", "Veuillez ouvrir un projet qgis")
            return
        else:
            if export_as_geojson(project_path):
                 if export_tfw(project_path):
                    self.iface.messageBar().pushInfo('Undermap', "l'export de GeoJSON et les fichiers"
                                                                 " tfw est bien reussi"
                                                     )
            delete_unused_folder(project_path)

    def merge_features_layer(self):

        from matplotlib import pyplot as plt
        project_path = get_project_path()
        if project_path == './':
            QMessageBox.warning(None, "Avertisment", "Veuillez ouvrir un projet qgis")
            return
        else:
            merge_features_connected_layers(project_path)
            plt.pause(5)
            overwrite_layers_merged(project_path)
            delete_unused_folder(project_path)

    def load_layer(self):
        project_path = get_project_path()
        load_unloaded_data(project_path)
예제 #16
0
class WaysCalc:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # 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]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'WaysCalc_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&WaysCalc')
        # TODO: We are going to let the user set this up in a future iteration
        # self.toolbar = self.iface.addToolBar(u'WaysCalc')
        # self.toolbar.setObjectName(u'WaysCalc')

        #print "** INITIALIZING WaysCalc"

        self.pluginIsActive = False
        self.dockwidget_inters_ways = None
        self.dockwidget_inters_allways = None
        # self.settings = None

        self.IW = None #IntersectionWays
        self.IAW = None #IntersectionAllWays


    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('WaysCalc', message)


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # выпадающая кнопка для пересекающихся маршрутов
        self.toolButton = QToolButton()
        self.toolButton.setMenu(QMenu())
        # setPopupMode: DelayedPopup, MenuButtonPopup, InstantPopup
        self.toolButton.setPopupMode(QToolButton.InstantPopup)
        self.toolButton.setAutoRaise(True)
        self.toolButton_action = self.iface.addToolBarWidget(self.toolButton)

        self.action_intersection = QAction(
                QIcon(":/plugins/_Ways_calc/icon.png"),
                u'Поиск пересечений для линейного объекта',
                self.iface.mainWindow())
        self.action_initLayerWays = QAction(
                u"Выбор слоя для поиска пересечений",
                self.iface.mainWindow())
        self.action_allintersection = QAction(
                QIcon(":/plugins/_Ways_calc/icon.png"),
                u'Поиск пересечений всех линейных объектов',
                self.iface.mainWindow())

        self.iface.addPluginToMenu(u"WaysCalc", self.action_intersection)
        self.iface.addPluginToMenu(u"WaysCalc", self.action_initLayerWays)
        self.iface.addPluginToMenu(u"WaysCalc", self.action_allintersection)
        # self.iface.addToolBarIcon(self.action_intersection)
        m = self.toolButton.menu()
        m.addAction(self.action_intersection)
        m.addAction(self.action_initLayerWays)
        m.addSeparator()
        m.addAction(self.action_allintersection)
        self.toolButton.setDefaultAction(self.action_intersection)

        self.action_intersection.triggered.connect(self.run_intersection) # пересекающиеся маршруты
        self.action_allintersection.triggered.connect(self.run_allintersection) # пересекающиеся все маршруты
        self.action_initLayerWays.triggered.connect(self.run_initLayerWays) # выбор слоя сравнения

        self.pointEmitterIntersection = QgsMapToolEmitPoint(self.iface.mapCanvas())
        self.pointEmitterIntersection.setAction(self.action_intersection)
        self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked)
        self.iface.mapCanvas().currentLayerChanged.connect(self.onCurrentLayerChanged)

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""
        # disconnects
        try:
            self.dockwidget_inters_ways.closingPlugin.disconnect(self.onClosePlugin)
        except:
            pass
        try:
            self.dockwidget_inters_allways.closingPlugin.disconnect(self.onClosePlugin)
        except:
            pass
        self.pluginIsActive = False


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        self.iface.removePluginMenu(u"WaysCalc", self.action_intersection)
        self.iface.removePluginMenu(u"WaysCalc", self.action_allintersection)
        self.iface.removePluginMenu(u"WaysCalc", self.action_initLayerWays)
        self.iface.removeToolBarIcon(self.action_intersection)
        self.iface.removeToolBarIcon(self.action_intersection)
        self.iface.removeToolBarIcon(self.toolButton_action)

        self.action_intersection.triggered.disconnect(self.run_intersection) # пересекающиеся маршруты
        self.action_allintersection.triggered.disconnect(self.run_allintersection) # пересекающиеся все маршруты
        self.action_initLayerWays.triggered.disconnect(self.run_initLayerWays) # выбор слоя сравнения
        self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked)
        self.iface.mapCanvas().currentLayerChanged.disconnect(self.onCurrentLayerChanged)

        if self.IW is not None:
            self.IW.onUnLoadModule()


    def init_dock_inters_ways(self, dock):
        """Run method that loads and starts the plugin"""

        # if not self.pluginIsActive:
        self.pluginIsActive = True
        if self.dockwidget_inters_ways == None:
            self.dockwidget_inters_ways = WaysCalcDockWidget()
            self.dockwidget_inters_ways.closingPlugin.connect(self.onClosePlugin)

            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_ways)
            self.dockwidget_inters_ways.hide()
            self.dockwidget_inters_ways.setWindowTitle(u'WaysCalc: Поиск пересечений для линейного объекта')


    def init_dock_inters_allways(self, dock):
        """Run method that loads and starts the plugin"""

        # if not self.pluginIsActive:
        self.pluginIsActive = True
        if self.dockwidget_inters_allways == None:
            self.dockwidget_inters_allways = WaysCalcDockWidget()
            self.dockwidget_inters_allways.closingPlugin.connect(self.onClosePlugin)

            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_allways)
            self.dockwidget_inters_allways.hide()
            self.dockwidget_inters_allways.setWindowTitle(u'WaysCalc: Поиск пересечений всех линейных объектов')



    def onCurrentLayerChanged(self):
        self.iface.mapCanvas().unsetMapTool(self.pointEmitterIntersection)


    #--------------------------------------------------------------------------

    # def loadSettings(self):
    #     with open(os.path.join(self.plugin_dir, "settings.json"), "r") as read_file:
    #         self.settings = json.load(read_file)


    #--------INTERSECTION WAYS-------------------------------------------------
    def run_initLayerWays(self):
        if self.IW is None:
            self.init_IW()
        self.IW.initLayerWays()     

    def run_intersection(self):
        self.toolButton.setDefaultAction(self.action_intersection)
        self.init_dock_inters_ways(self.dockwidget_inters_ways)
        if self.IW is None:
            self.init_IW()
        if self.IW.checkLayers():    
            self.iface.mapCanvas().setMapTool(self.pointEmitterIntersection)


    def pointEmitterIntersectioncanvasClicked(self, point, button):
        self.IW.insersection_take_way(point)


    def init_IW(self):
        self.IW = IntersectionWays(self.iface, self.dockwidget_inters_ways)

    #-------- END INTERSECTION WAYS---------------------------------------------


    def init_IAW(self):
        self.IAW = IntersectionAllWays(self.iface, self.dockwidget_inters_allways)

    def run_allintersection(self):
        self.init_dock_inters_allways(self.dockwidget_inters_allways)
        if self.IAW is None:
            self.init_IAW()
        self.IAW.showClickedFeaturesList()
예제 #17
0
class AeroGen:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # 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]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'AeroGen_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr('&AeroGen')

        # add plugin icon into plugin toolbar
        self.toolButton = QToolButton()

        #print "** INITIALIZING AeroGen"

        self.pluginIsActive = False
        self.dockwidget = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('AeroGen', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolButton.setDefaultAction(action)
            self.iface.addToolBarWidget(self.toolButton)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/AeroGen/icon.png'
        self.add_action(icon_path,
                        text=self.tr('AeroGen'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING AeroGen"

        # disconnects
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        # self.dockwidget = None

        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        #print "** UNLOAD AeroGen"

        for action in self.actions:
            self.iface.removePluginMenu(self.tr('&AeroGen'), action)
            self.iface.removeToolBarIcon(action)

    #--------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            #print "** STARTING AeroGen"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget == None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = AeroGenDockWidget()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockwidget)
            self.dockwidget.show()
class LatLonTools:
    digitizerDialog = None
    convertCoordinateDialog = None
    mapTool = None
    showMapTool = None
    copyExtentTool = None

    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.crossRb = QgsRubberBand(self.canvas, QgsWkbTypes.LineGeometry)
        self.crossRb.setColor(Qt.red)
        self.provider = LatLonToolsProvider()
        self.toolbar = self.iface.addToolBar('Lat Lon Tools Toolbar')
        self.toolbar.setObjectName('LatLonToolsToolbar')

    def initGui(self):
        '''Initialize Lot Lon Tools GUI.'''
        # Initialize the Settings Dialog box
        self.settingsDialog = SettingsWidget(self, self.iface,
                                             self.iface.mainWindow())

        # Add Interface for Coordinate Capturing
        icon = QIcon(os.path.dirname(__file__) + "/images/copyicon.svg")
        self.copyAction = QAction(icon, "Copy/Display Coordinate",
                                  self.iface.mainWindow())
        self.copyAction.setObjectName('latLonToolsCopy')
        self.copyAction.triggered.connect(self.startCapture)
        self.copyAction.setCheckable(True)
        self.toolbar.addAction(self.copyAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.copyAction)

        # Add Interface for External Map
        icon = QIcon(os.path.dirname(__file__) + "/images/mapicon.png")
        self.externMapAction = QAction(icon, "Show in External Map",
                                       self.iface.mainWindow())
        self.externMapAction.setObjectName('latLonToolsExternalMap')
        self.externMapAction.triggered.connect(self.setShowMapTool)
        self.externMapAction.setCheckable(True)
        self.toolbar.addAction(self.externMapAction)
        self.iface.addPluginToMenu("Lat Lon Tools", self.externMapAction)

        # Add Interface for Zoom to Coordinate
        icon = QIcon(os.path.dirname(__file__) + "/images/zoomicon.svg")
        self.zoomToAction = QAction(icon, "Zoom To Coordinate",
                                    self.iface.mainWindow())
        self.zoomToAction.setObjectName('latLonToolsZoom')
        self.zoomToAction.triggered.connect(self.showZoomToDialog)
        self.toolbar.addAction(self.zoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.zoomToAction)

        self.zoomToDialog = ZoomToLatLon(self, self.iface,
                                         self.iface.mainWindow())
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.zoomToDialog)
        self.zoomToDialog.hide()

        # Add Interface for Multi point zoom
        icon = QIcon(os.path.dirname(__file__) + '/images/multizoom.svg')
        self.multiZoomToAction = QAction(icon, "Multi-location Zoom",
                                         self.iface.mainWindow())
        self.multiZoomToAction.setObjectName('latLonToolsMultiZoom')
        self.multiZoomToAction.triggered.connect(self.multiZoomTo)
        self.toolbar.addAction(self.multiZoomToAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.multiZoomToAction)

        self.multiZoomDialog = MultiZoomWidget(self, self.settingsDialog,
                                               self.iface.mainWindow())
        self.multiZoomDialog.hide()
        self.multiZoomDialog.setFloating(True)

        menu = QMenu()
        # Add Interface for copying the canvas extent
        icon = QIcon(os.path.dirname(__file__) + "/images/copycanvas.svg")
        self.copyCanvasAction = menu.addAction(icon, 'Copy Canvas Extent',
                                               self.copyCanvas)
        self.copyCanvasAction.setObjectName('latLonToolsCopyCanvasExtent')
        # Add Interface for copying an interactive extent
        icon = QIcon(os.path.dirname(__file__) + "/images/copyextent.svg")
        self.copyExtentAction = menu.addAction(icon,
                                               'Copy Selected Area Extent',
                                               self.copyExtent)
        self.copyExtentAction.setCheckable(True)
        self.copyExtentAction.setObjectName(
            'latLonToolsCopySelectedAreaExtent')
        # Add Interface for copying a layer extent
        icon = QIcon(os.path.dirname(__file__) + "/images/copylayerextent.svg")
        self.copyLayerExtentAction = menu.addAction(icon, 'Copy Layer Extent',
                                                    self.copyLayerExtent)
        self.copyLayerExtentAction.setObjectName('latLonToolsCopyLayerExtent')
        # Add Interface for copying the extent of selected features
        icon = QIcon(
            os.path.dirname(__file__) + "/images/copyselectedlayerextent.svg")
        self.copySelectedFeaturesExtentAction = menu.addAction(
            icon, 'Copy Selected Features Extent',
            self.copySelectedFeaturesExtent)
        self.copySelectedFeaturesExtentAction.setObjectName(
            'latLonToolsCopySelectedFeaturesExtent')

        # Add the copy extent tools to the menu
        icon = QIcon(os.path.dirname(__file__) + '/images/copylayerextent.svg')
        self.copyExtentsAction = QAction(icon, 'Copy Extents to Clipboard',
                                         self.iface.mainWindow())
        self.copyExtentsAction.setMenu(menu)
        self.iface.addPluginToMenu('Lat Lon Tools', self.copyExtentsAction)

        # Add the copy extent tools to the toolbar
        self.copyExtentButton = QToolButton()
        self.copyExtentButton.setMenu(menu)
        self.copyExtentButton.setDefaultAction(self.copyCanvasAction)
        self.copyExtentButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.copyExtentButton.triggered.connect(self.copyExtentTriggered)
        self.copyExtentToolbar = self.toolbar.addWidget(self.copyExtentButton)

        # Create the coordinate converter menu
        icon = QIcon(':/images/themes/default/mIconProjectionEnabled.svg')
        self.convertCoordinatesAction = QAction(icon, "Coordinate Conversion",
                                                self.iface.mainWindow())
        self.convertCoordinatesAction.setObjectName(
            'latLonToolsCoordinateConversion')
        self.convertCoordinatesAction.triggered.connect(
            self.convertCoordinatesTool)
        self.toolbar.addAction(self.convertCoordinatesAction)
        self.iface.addPluginToMenu("Lat Lon Tools",
                                   self.convertCoordinatesAction)

        # Create the conversions menu
        menu = QMenu()
        icon = QIcon(os.path.dirname(__file__) + '/images/field2geom.svg')
        action = menu.addAction(icon, "Fields to point layer", self.field2geom)
        action.setObjectName('latLonToolsField2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/geom2field.svg')
        action = menu.addAction(icon, "Point layer to fields", self.geom2Field)
        action.setObjectName('latLonToolsGeom2Field')
        icon = QIcon(os.path.dirname(__file__) + '/images/pluscodes.svg')
        action = menu.addAction(icon, "Plus Codes to point layer",
                                self.PlusCodestoLayer)
        action.setObjectName('latLonToolsPlusCodes2Geom')
        action = menu.addAction(icon, "Point layer to Plus Codes",
                                self.toPlusCodes)
        action.setObjectName('latLonToolsGeom2PlusCodes')
        icon = QIcon(os.path.dirname(__file__) + '/images/mgrs2point.svg')
        action = menu.addAction(icon, "MGRS to point layer", self.MGRStoLayer)
        action.setObjectName('latLonToolsMGRS2Geom')
        icon = QIcon(os.path.dirname(__file__) + '/images/point2mgrs.svg')
        action = menu.addAction(icon, "Point layer to MGRS", self.toMGRS)
        action.setObjectName('latLonToolsGeom2MGRS')
        self.conversionsAction = QAction(icon, "Conversions",
                                         self.iface.mainWindow())
        self.conversionsAction.setMenu(menu)
        self.iface.addPluginToMenu('Lat Lon Tools', self.conversionsAction)

        # Add to Digitize Toolbar
        icon = QIcon(os.path.dirname(__file__) + '/images/latLonDigitize.svg')
        self.digitizeAction = QAction(icon, "Lat Lon Digitize",
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('latLonToolsDigitize')
        self.digitizeAction.triggered.connect(self.digitizeClicked)
        self.digitizeAction.setEnabled(False)
        self.toolbar.addAction(self.digitizeAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.digitizeAction)

        # Initialize the Settings Dialog Box
        settingsicon = QIcon(':/images/themes/default/mActionOptions.svg')
        self.settingsAction = QAction(settingsicon, "Settings",
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('latLonToolsSettings')
        self.settingsAction.setToolTip('Lat Lon Tools Settings')
        self.settingsAction.triggered.connect(self.settings)
        self.toolbar.addAction(self.settingsAction)
        self.iface.addPluginToMenu('Lat Lon Tools', self.settingsAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.svg')
        self.helpAction = QAction(icon, "Help", self.iface.mainWindow())
        self.helpAction.setObjectName('latLonToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('Lat Lon Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.resetTools)
        self.enableDigitizeTool()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)
        InitLatLonFunctions()

    def resetTools(self, newtool, oldtool):
        '''Uncheck the Copy Lat Lon tool'''
        try:
            if self.mapTool and (oldtool is self.mapTool):
                self.copyAction.setChecked(False)
            if self.showMapTool and (oldtool is self.showMapTool):
                self.externMapAction.setChecked(False)
            if newtool is self.mapTool:
                self.copyAction.setChecked(True)
            if newtool is self.showMapTool:
                self.externMapAction.setChecked(True)
        except Exception:
            pass

    def unload(self):
        '''Unload LatLonTools from the QGIS interface'''
        self.zoomToDialog.removeMarker()
        self.multiZoomDialog.removeMarkers()
        if self.mapTool:
            self.canvas.unsetMapTool(self.mapTool)
        if self.showMapTool:
            self.canvas.unsetMapTool(self.showMapTool)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.copyExtentsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.externMapAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.zoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.multiZoomToAction)
        self.iface.removePluginMenu('Lat Lon Tools',
                                    self.convertCoordinatesAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.conversionsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.settingsAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.helpAction)
        self.iface.removePluginMenu('Lat Lon Tools', self.digitizeAction)
        self.iface.removeDockWidget(self.zoomToDialog)
        self.iface.removeDockWidget(self.multiZoomDialog)
        # Remove Toolbar Icons
        self.iface.removeToolBarIcon(self.copyAction)
        self.iface.removeToolBarIcon(self.copyExtentToolbar)
        self.iface.removeToolBarIcon(self.zoomToAction)
        self.iface.removeToolBarIcon(self.externMapAction)
        self.iface.removeToolBarIcon(self.multiZoomToAction)
        self.iface.removeToolBarIcon(self.convertCoordinatesAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        del self.toolbar

        if self.convertCoordinateDialog:
            self.iface.removeDockWidget(self.convertCoordinateDialog)
            self.convertCoordinateDialog = None

        self.zoomToDialog = None
        self.multiZoomDialog = None
        self.settingsDialog = None
        self.showMapTool = None
        self.mapTool = None
        self.digitizerDialog = None
        QgsApplication.processingRegistry().removeProvider(self.provider)
        UnloadLatLonFunctions()

    def startCapture(self):
        '''Set the focus of the copy coordinate tool'''
        if self.mapTool is None:
            from .copyLatLonTool import CopyLatLonTool
            self.mapTool = CopyLatLonTool(self.settingsDialog, self.iface)
        self.canvas.setMapTool(self.mapTool)

    def copyExtentTriggered(self, action):
        self.copyExtentButton.setDefaultAction(action)

    def copyExtent(self):
        if self.copyExtentTool is None:
            from .captureExtent import CaptureExtentTool
            self.copyExtentTool = CaptureExtentTool(self.iface, self)
            self.copyExtentTool.setAction(self.copyExtentAction)
        self.canvas.setMapTool(self.copyExtentTool)

    def copyLayerExtent(self):
        layer = self.iface.activeLayer()
        if not layer or not layer.isValid():
            return
        if isinstance(layer, QgsVectorLayer) and (layer.featureCount() == 0):
            self.iface.messageBar().pushMessage(
                "",
                "This layer has no features - A bounding box cannot be calculated.",
                level=Qgis.Warning,
                duration=4)
            return
        src_crs = layer.crs()
        extent = layer.extent()
        if settings.bBoxCrs == 0:
            dst_crs = epsg4326
        else:
            dst_crs = self.canvas.mapSettings().destinationCrs()

        outStr = getExtentString(extent, src_crs, dst_crs)
        clipboard = QApplication.clipboard()
        clipboard.setText(outStr)
        self.iface.messageBar().pushMessage(
            "",
            "'{}' copied to the clipboard".format(outStr),
            level=Qgis.Info,
            duration=4)

    def copySelectedFeaturesExtent(self):
        layer = self.iface.activeLayer()
        if not layer or not layer.isValid():
            return
        if isinstance(layer, QgsVectorLayer) and (layer.featureCount() == 0):
            self.iface.messageBar().pushMessage(
                "",
                "This layer has no features - A bounding box cannot be calculated.",
                level=Qgis.Warning,
                duration=4)
            return
        if isinstance(layer, QgsVectorLayer):
            extent = layer.boundingBoxOfSelected()
            if extent.isNull():
                self.iface.messageBar().pushMessage(
                    "",
                    "No features were selected.",
                    level=Qgis.Warning,
                    duration=4)
                return
        else:
            extent = layer.extent()
        src_crs = layer.crs()
        if settings.bBoxCrs == 0:
            dst_crs = epsg4326
        else:
            dst_crs = self.canvas.mapSettings().destinationCrs()

        outStr = getExtentString(extent, src_crs, dst_crs)
        clipboard = QApplication.clipboard()
        clipboard.setText(outStr)
        self.iface.messageBar().pushMessage(
            "",
            "'{}' copied to the clipboard".format(outStr),
            level=Qgis.Info,
            duration=4)

    def copyCanvas(self):
        extent = self.iface.mapCanvas().extent()
        canvas_crs = self.canvas.mapSettings().destinationCrs()
        if settings.bBoxCrs == 0:
            dst_crs = epsg4326
        else:
            dst_crs = canvas_crs

        outStr = getExtentString(extent, canvas_crs, dst_crs)
        clipboard = QApplication.clipboard()
        clipboard.setText(outStr)
        self.iface.messageBar().pushMessage(
            "",
            "'{}' copied to the clipboard".format(outStr),
            level=Qgis.Info,
            duration=4)

    def setShowMapTool(self):
        '''Set the focus of the external map tool.'''
        if self.showMapTool is None:
            from .showOnMapTool import ShowOnMapTool
            self.showMapTool = ShowOnMapTool(self.iface)
        self.canvas.setMapTool(self.showMapTool)

    def showZoomToDialog(self):
        '''Show the zoom to docked widget.'''
        self.zoomToDialog.show()

    def convertCoordinatesTool(self):
        '''Display the Convert Coordinate Tool Dialog box.'''
        if self.convertCoordinateDialog is None:
            from .coordinateConverter import CoordinateConverterWidget
            self.convertCoordinateDialog = CoordinateConverterWidget(
                self, self.settingsDialog, self.iface, self.iface.mainWindow())
            self.convertCoordinateDialog.setFloating(True)
            self.iface.addDockWidget(Qt.RightDockWidgetArea,
                                     self.convertCoordinateDialog)
        self.convertCoordinateDialog.show()

    def multiZoomTo(self):
        '''Display the Multi-zoom to dialog box'''
        self.multiZoomDialog.show()

    def field2geom(self):
        '''Convert layer containing a point x & y coordinate to a new point layer'''
        processing.execAlgorithmDialog('latlontools:field2geom', {})

    def geom2Field(self):
        '''Convert layer geometry to a text string'''
        processing.execAlgorithmDialog('latlontools:geom2field', {})

    def toMGRS(self):
        '''Display the to MGRS  dialog box'''
        processing.execAlgorithmDialog('latlontools:point2mgrs', {})

    def MGRStoLayer(self):
        '''Display the to MGRS  dialog box'''
        processing.execAlgorithmDialog('latlontools:mgrs2point', {})

    def toPlusCodes(self):
        processing.execAlgorithmDialog('latlontools:point2pluscodes', {})

    def PlusCodestoLayer(self):
        processing.execAlgorithmDialog('latlontools:pluscodes2point', {})

    def settings(self):
        '''Show the settings dialog box'''
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        import webbrowser
        url = QUrl.fromLocalFile(os.path.dirname(__file__) +
                                 "/index.html").toString()
        webbrowser.open(url, new=2)

    def settingsChanged(self):
        # Settings may have changed so we need to make sure the zoomToDialog window is configured properly
        self.zoomToDialog.configure()
        self.multiZoomDialog.settingsChanged()

    def zoomTo(self, src_crs, lat, lon):
        canvas_crs = self.canvas.mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(src_crs, canvas_crs,
                                           QgsProject.instance())
        x, y = transform.transform(float(lon), float(lat))

        rect = QgsRectangle(x, y, x, y)
        self.canvas.setExtent(rect)

        pt = QgsPointXY(x, y)
        self.highlight(pt)
        self.canvas.refresh()
        return pt

    def highlight(self, point):
        currExt = self.canvas.extent()

        leftPt = QgsPoint(currExt.xMinimum(), point.y())
        rightPt = QgsPoint(currExt.xMaximum(), point.y())

        topPt = QgsPoint(point.x(), currExt.yMaximum())
        bottomPt = QgsPoint(point.x(), currExt.yMinimum())

        horizLine = QgsGeometry.fromPolyline([leftPt, rightPt])
        vertLine = QgsGeometry.fromPolyline([topPt, bottomPt])

        self.crossRb.reset(QgsWkbTypes.LineGeometry)
        self.crossRb.addGeometry(horizLine, None)
        self.crossRb.addGeometry(vertLine, None)

        QTimer.singleShot(700, self.resetRubberbands)

    def resetRubberbands(self):
        self.crossRb.reset()

    def digitizeClicked(self):
        if self.digitizerDialog is None:
            from .digitizer import DigitizerWidget
            self.digitizerDialog = DigitizerWidget(self, self.iface,
                                                   self.iface.mainWindow())
        self.digitizerDialog.show()

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if layer is not None:
            try:
                layer.editingStarted.disconnect(self.layerEditingChanged)
            except Exception:
                pass
            try:
                layer.editingStopped.disconnect(self.layerEditingChanged)
            except Exception:
                pass

            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)

        self.enableDigitizeTool()

    def layerEditingChanged(self):
        self.enableDigitizeTool()

    def enableDigitizeTool(self):
        self.digitizeAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if layer is not None and isinstance(layer, QgsVectorLayer) and (
                layer.geometryType()
                == QgsWkbTypes.PointGeometry) and layer.isEditable():
            self.digitizeAction.setEnabled(True)
        else:
            if self.digitizerDialog is not None:
                self.digitizerDialog.close()
예제 #19
0
class GeoGigPlugin(object):
    def __init__(self, iface):
        self.iface = iface
        config.iface = iface
        readSettings()
        config.initConfigParams()

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            trackLayer(layer)
        try:
            from qgistester.tests import addTestModule
            from geogig.tests import testplugin
            addTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        QSettings().setValue("/qgis/walForSqlite3", False)

    def unload(self):
        navigatorInstance.setVisible(False)
        try:
            QgsMapLayerRegistry.instance().layerWasAdded.disconnect(trackLayer)
            QgsMapLayerRegistry.instance().layerRemoved.disconnect(
                layerRemoved)
        except:
            pass

        self.menu.deleteLater()
        self.toolButton.deleteLater()

        self.iface.removePluginMenu("&GeoGig", self.explorerAction)
        self.iface.removePluginMenu("&GeoGig", self.toolAction)

        layers = list(QgsMapLayerRegistry.instance().mapLayers().values())
        for layer in layers:
            removeLayerActions(layer)
        removeNonexistentTrackedLayers()
        removeTempFolder()

        try:
            from qgistester.tests import removeTestModule
            from geogig.tests import testplugin
            removeTestModule(testplugin, "GeoGig Light")
        except Exception as e:
            pass

        try:
            from lessons import removeLessonsFolder
            removeLessonsFolder(folder, "geogig")
        except:
            pass

        removeHelpMenu("GeoGig")
        removeAboutMenu("GeoGig")
        removeSettingsMenu("GeoGig")

    def initGui(self):
        readTrackedLayers()

        QgsMapLayerRegistry.instance().layerWasAdded.connect(trackLayer)
        QgsMapLayerRegistry.instance().layerRemoved.connect(layerRemoved)

        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/geogig.png")
        self.explorerAction = navigatorInstance.toggleViewAction()
        self.explorerAction.setIcon(icon)
        self.explorerAction.setText("GeoGig Navigator")
        icon = QIcon(os.path.dirname(__file__) + "/ui/resources/identify.png")
        self.toolAction = QAction(icon, "GeoGig Feature Info Tool",
                                  self.iface.mainWindow())
        self.toolAction.setCheckable(True)
        self.toolAction.triggered.connect(self.setTool)

        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setTitle("GeoGig")
        self.menu.addAction(self.explorerAction)
        self.menu.addAction(self.toolAction)
        bar = self.iface.layerToolBar()
        self.toolButton = QToolButton()
        self.toolButton.setMenu(self.menu)
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButton.setDefaultAction(self.explorerAction)
        bar.addWidget(self.toolButton)
        self.iface.addPluginToMenu("&GeoGig", self.explorerAction)
        self.iface.addPluginToMenu("&GeoGig", self.toolAction)

        addSettingsMenu("GeoGig")
        addHelpMenu("GeoGig")
        addAboutMenu("GeoGig")

        self.mapTool = MapToolGeoGigInfo(self.iface.mapCanvas())

        #This crashes QGIS, so we comment it out until finding a solution
        #self.mapTool.setAction(self.toolAction)

        self.iface.addDockWidget(Qt.RightDockWidgetArea, navigatorInstance)

        try:
            from lessons import addLessonsFolder, addGroup
            folder = os.path.join(os.path.dirname(__file__), "_lessons")
            addLessonsFolder(folder, "geogig")
            group_description = os.path.join(folder, "group.md")
            addGroup("GeoGig lessons", group_description)
        except Exception as e:
            pass

    def setWarning(self, msg):
        QMessageBox.warning(None, 'Could not complete GeoGig command', msg,
                            QMessageBox.Ok)

    def setTool(self):
        self.toolAction.setChecked(True)
        self.iface.mapCanvas().setMapTool(self.mapTool)
예제 #20
0
class ShapeTools(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settingsDialog = None
        self.xyLineDialog = None
        self.geodesicDensifyDialog = None
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        self.previousLayer = None
        self.toolbar = self.iface.addToolBar('Shape Tools Toolbar')
        self.toolbar.setObjectName('ShapeToolsToolbar')
        self.provider = ShapeToolsProvider()
        # Initialize the plugin path directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        try:
            locale = QSettings().value("locale/userLocale", "en",
                                       type=str)[0:2]
        except Exception:
            locale = "en"
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'shapeTools_{}.qm'.format(locale))
        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)
        self.lineDigitizerTool = LineDigitizerTool(self.iface)

        # Initialize the create shape menu items
        menu = QMenu()
        # Initialize Create Arc Wedge tool
        icon = QIcon(self.plugin_dir + '/images/arc.png')
        self.createArcAction = menu.addAction(icon, tr('Create arc wedge'),
                                              self.createArc)
        self.createArcAction.setObjectName('stCreateArcWedge')
        icon = QIcon(self.plugin_dir + '/images/donut.png')
        self.createDonutAction = menu.addAction(icon, tr('Create donut'),
                                                self.createDonut)
        self.createDonutAction.setObjectName('stCreateDonut')
        icon = QIcon(self.plugin_dir + '/images/ellipse.png')
        self.createEllipseAction = menu.addAction(icon, tr('Create ellipse'),
                                                  self.createEllipse)
        self.createEllipseAction.setObjectName('stCreateEllipse')
        icon = QIcon(self.plugin_dir + '/images/rose.png')
        self.createEllipseRoseAction = menu.addAction(
            icon, tr('Create ellipse rose'), self.createEllipseRose)
        self.createEllipseRoseAction.setObjectName('stCreateEllipseRose')
        icon = QIcon(self.plugin_dir + '/images/epicycloid.png')
        self.createEpicycloidAction = menu.addAction(icon,
                                                     tr('Create epicycloid'),
                                                     self.createEpicycloid)
        self.createEpicycloidAction.setObjectName('stCreateEpicycloid')
        icon = QIcon(self.plugin_dir + '/images/heart.png')
        self.createHeartAction = menu.addAction(icon, tr('Create heart'),
                                                self.createHeart)
        self.createHeartAction.setObjectName('stCreateHeart')
        icon = QIcon(self.plugin_dir + '/images/hypocycloid.png')
        self.createHypocycloidAction = menu.addAction(icon,
                                                      tr('Create hypocycloid'),
                                                      self.createHypocycloid)
        self.createHypocycloidAction.setObjectName('stCreateHypocycloid')
        icon = QIcon(self.plugin_dir + '/images/line.png')
        self.createLOBAction = menu.addAction(icon,
                                              tr('Create line of bearing'),
                                              self.createLOB)
        self.createLOBAction.setObjectName('stCreateLineOfBearing')
        icon = QIcon(self.plugin_dir + '/images/pie.png')
        self.createPieAction = menu.addAction(icon, tr('Create pie wedge'),
                                              self.createPie)
        self.createPieAction.setObjectName('stCreatePie')
        icon = QIcon(self.plugin_dir + '/images/polyfoil.png')
        self.createPolyfoilAction = menu.addAction(icon, tr('Create polyfoil'),
                                                   self.createPolyfoil)
        self.createPolyfoilAction.setObjectName('stCreatePolyfoil')
        icon = QIcon(self.plugin_dir + '/images/polygon.png')
        self.createPolygonAction = menu.addAction(icon, tr('Create polygon'),
                                                  self.createPolygon)
        self.createPolygonAction.setObjectName('stCreatePolygon')
        icon = QIcon(self.plugin_dir + '/images/radialLines.png')
        self.createPolygonAction = menu.addAction(icon,
                                                  tr('Create radial lines'),
                                                  self.createRadialLines)
        self.createPolygonAction.setObjectName('stCreateRadialLines')
        icon = QIcon(self.plugin_dir + '/images/star.png')
        self.createStarAction = menu.addAction(icon, tr('Create star'),
                                               self.createStar)
        self.createStarAction.setObjectName('stCreateStar')
        # Add the shape creation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/shapes.png')
        self.createShapesAction = QAction(icon, tr('Create shapes'),
                                          self.iface.mainWindow())
        self.createShapesAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.createShapesAction)
        # Add the shape creation tools to the toolbar
        self.createShapeButton = QToolButton()
        self.createShapeButton.setMenu(menu)
        self.createShapeButton.setDefaultAction(self.createDonutAction)
        self.createShapeButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.createShapeButton.triggered.connect(self.createShapeTriggered)
        self.createShapeToolbar = self.toolbar.addWidget(
            self.createShapeButton)

        # Initialize the XY to Line menu item
        icon = QIcon(self.plugin_dir + '/images/xyline.svg')
        self.xyLineAction = QAction(icon, tr('XY to line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(self.plugin_dir + '/images/geodesicDensifier.svg')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic shape densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize the Geodesic decimation menu items
        menu = QMenu()
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.svg')
        self.lineDecimateAction = menu.addAction(icon,
                                                 tr('Geodesic line decimate'),
                                                 self.lineDecimateTool)
        self.lineDecimateAction.setObjectName('stGeodesicLineDecimate')
        icon = QIcon(self.plugin_dir + '/images/geodesicPointDecimate.svg')
        self.pointDecimateAction = menu.addAction(
            icon, tr('Geodesic point decimate'), self.pointDecimateTool)
        self.pointDecimateAction.setObjectName('stGeodesicPointDecimate')
        # Add the decimation tools to the menu
        icon = QIcon(self.plugin_dir + '/images/geodesicLineDecimate.svg')
        self.simplifyGeomAction = QAction(
            icon, tr('Geodesic geometry simplification'),
            self.iface.mainWindow())
        self.simplifyGeomAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.simplifyGeomAction)
        # Add the shape creation tools to the toolbar
        self.simplifyButton = QToolButton()
        self.simplifyButton.setMenu(menu)
        self.simplifyButton.setDefaultAction(self.lineDecimateAction)
        self.simplifyButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.simplifyButton.triggered.connect(self.simplifyTriggered)
        self.simplifyToolbar = self.toolbar.addWidget(self.simplifyButton)

        # Initialize the Geodesic line break menu item
        icon = QIcon(self.plugin_dir + '/images/idlbreak.svg')
        self.geodesicLineBreakAction = QAction(
            icon, tr('Geodesic line break at -180,180'),
            self.iface.mainWindow())
        self.geodesicLineBreakAction.setObjectName('stGeodesicLineBreak')
        self.geodesicLineBreakAction.triggered.connect(
            self.geodesicLineBreakTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicLineBreakAction)
        self.toolbar.addAction(self.geodesicLineBreakAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(self.plugin_dir + '/images/measure.svg')
        self.measureAction = QAction(icon, tr('Geodesic measure tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize Geodesic Measurement layer
        icon = QIcon(self.plugin_dir + '/images/measureLine.svg')
        self.measureLayerAction = QAction(icon,
                                          tr('Geodesic measurement layer'),
                                          self.iface.mainWindow())
        self.measureLayerAction.setObjectName('stGeodesicLineBreak')
        self.measureLayerAction.triggered.connect(self.measureLayerTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.measureLayerAction)
        self.toolbar.addAction(self.measureLayerAction)

        menu = QMenu()
        # Initialize Geodesic transformation tool
        icon = QIcon(self.plugin_dir + '/images/transformShape.svg')
        self.transformationsAction = menu.addAction(
            icon, tr('Geodesic transformations'), self.transformTool)
        self.transformationsAction.setObjectName('stGeodesicTransformations')

        icon = QIcon(self.plugin_dir + '/images/flip.svg')
        self.flipRotateAction = menu.addAction(icon,
                                               tr('Geodesic flip and rotate'),
                                               self.flipRotateTool)
        self.flipRotateAction.setObjectName('stGeodesicFlipRotate')

        icon = QIcon(self.plugin_dir + '/images/flipHorizontal.svg')
        self.flipHorizontalAction = menu.addAction(icon, tr('Flip horizontal'),
                                                   self.flipHorizontalTool)
        self.flipHorizontalAction.setObjectName('stGeodesicFlipHorizontal')
        self.flipHorizontalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/flipVertical.svg')
        self.flipVerticalAction = menu.addAction(icon, tr('Flip vertical'),
                                                 self.flipVerticalTool)
        self.flipVerticalAction.setObjectName('stGeodesicFlipVertical')
        self.flipVerticalAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotate180.svg')
        self.rotate180Action = menu.addAction(icon, tr('Rotate 180\xb0'),
                                              self.rotate180Tool)
        self.rotate180Action.setObjectName('stGeodesicRotate180')
        self.rotate180Action.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotatecw.svg')
        self.rotate90CWAction = menu.addAction(icon, tr('Rotate 90\xb0 CW'),
                                               self.rotate90CWTool)
        self.rotate90CWAction.setObjectName('stGeodesicRotate90CW')
        self.rotate90CWAction.setEnabled(False)
        icon = QIcon(self.plugin_dir + '/images/rotateccw.svg')
        self.rotate90CCWAction = menu.addAction(icon, tr('Rotate 90\xb0 CCW'),
                                                self.rotate90CCWTool)
        self.rotate90CCWAction.setObjectName('stGeodesicRotate90CCW')
        self.rotate90CCWAction.setEnabled(False)
        self.transformsAction = QAction(icon, tr('Geodesic transforms'),
                                        self.iface.mainWindow())
        self.transformsAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools', self.transformsAction)

        self.transformationButton = QToolButton()
        self.transformationButton.setMenu(menu)
        self.transformationButton.setDefaultAction(self.transformationsAction)
        self.transformationButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.transformationButton.triggered.connect(self.toolButtonTriggered)
        self.tranformToolbar = self.toolbar.addWidget(
            self.transformationButton)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(self.plugin_dir + '/images/dazdigitize.svg')
        self.digitizeAction = QAction(icon, tr('Azimuth distance digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Initialize the multi point azimuth Digitize function
        icon = QIcon(self.plugin_dir + '/images/linedigitize.svg')
        self.lineDigitizeAction = QAction(
            icon, tr('Azimuth distance sequence digitizer'),
            self.iface.mainWindow())
        self.lineDigitizeAction.setObjectName('stLineDigitizer')
        self.lineDigitizeAction.triggered.connect(self.setShowLineDigitizeTool)
        self.lineDigitizeAction.setCheckable(True)
        self.lineDigitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools',
                                         self.lineDigitizeAction)
        self.toolbar.addAction(self.lineDigitizeAction)

        # Settings
        icon = QIcon(':/images/themes/default/mActionOptions.svg')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(self.plugin_dir + '/images/help.svg')
        self.helpAction = QAction(icon, tr('Shape Tools help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableTools()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, GeodesicMeasureTool):
                self.measureAction.setChecked(False)
                self.geodesicMeasureTool.endInteractiveLine()
            if not isinstance(tool, AzDigitizerTool):
                self.digitizeAction.setChecked(False)
            if not isinstance(tool, LineDigitizerTool):
                self.lineDigitizeAction.setChecked(False)
        except Exception:
            pass

    def unload(self):
        self.canvas.unsetMapTool(self.azDigitizerTool)
        self.canvas.unsetMapTool(self.lineDigitizerTool)

        # remove from menu
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.createShapesAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.xyLineAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicDensifyAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.simplifyGeomAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicLineBreakAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.measureAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.measureLayerAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.transformsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.digitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.lineDigitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.settingsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.helpAction)
        # Remove from toolbar
        self.iface.removeToolBarIcon(self.createShapeToolbar)
        self.iface.removeToolBarIcon(self.xyLineAction)
        self.iface.removeToolBarIcon(self.geodesicDensifyAction)
        self.iface.removeToolBarIcon(self.simplifyToolbar)
        self.iface.removeToolBarIcon(self.geodesicLineBreakAction)
        self.iface.removeToolBarIcon(self.measureAction)
        self.iface.removeToolBarIcon(self.measureLayerAction)
        self.iface.removeToolBarIcon(self.transformationsAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        self.iface.removeToolBarIcon(self.lineDigitizeAction)
        self.iface.removeToolBarIcon(self.tranformToolbar)
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        # remove the toolbar
        del self.toolbar

        QgsApplication.processingRegistry().removeProvider(self.provider)

    def toolButtonTriggered(self, action):
        self.transformationButton.setDefaultAction(action)

    def createShapeTriggered(self, action):
        self.createShapeButton.setDefaultAction(action)

    def simplifyTriggered(self, action):
        self.simplifyButton.setDefaultAction(action)

    def setShowAzDigitizerTool(self):
        self.digitizeAction.setChecked(True)
        self.canvas.setMapTool(self.azDigitizerTool)

    def setShowLineDigitizeTool(self):
        self.lineDigitizeAction.setChecked(True)
        self.canvas.setMapTool(self.lineDigitizerTool)

    def xyLineTool(self):
        processing.execAlgorithmDialog('shapetools:xy2line', {})

    def geodesicDensifyTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicdensifier', {})

    def pointDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicpointdecimate', {})

    def lineDecimateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesiclinedecimate', {})

    def geodesicLineBreakTool(self):
        processing.execAlgorithmDialog('shapetools:linebreak', {})

    def measureTool(self):
        self.measureAction.setChecked(True)
        self.canvas.setMapTool(self.geodesicMeasureTool)

    def createArc(sefl):
        processing.execAlgorithmDialog('shapetools:createarc', {})

    def createDonut(sefl):
        processing.execAlgorithmDialog('shapetools:createdonut', {})

    def createEllipse(sefl):
        processing.execAlgorithmDialog('shapetools:createellipse', {})

    def createEllipseRose(sefl):
        processing.execAlgorithmDialog('shapetools:createrose', {})

    def createEpicycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createepicycloid', {})

    def createHeart(sefl):
        processing.execAlgorithmDialog('shapetools:createheart', {})

    def createHypocycloid(sefl):
        processing.execAlgorithmDialog('shapetools:createhypocycloid', {})

    def createLOB(sefl):
        processing.execAlgorithmDialog('shapetools:createlob', {})

    def createPie(sefl):
        processing.execAlgorithmDialog('shapetools:createpie', {})

    def createPolyfoil(sefl):
        processing.execAlgorithmDialog('shapetools:createpolyfoil', {})

    def createPolygon(sefl):
        processing.execAlgorithmDialog('shapetools:createpolygon', {})

    def createRadialLines(sefl):
        processing.execAlgorithmDialog('shapetools:createradiallines', {})

    def createStar(sefl):
        processing.execAlgorithmDialog('shapetools:createstar', {})

    def measureLayerTool(self):
        processing.execAlgorithmDialog('shapetools:measurelayer', {})

    def transformTool(self):
        processing.execAlgorithmDialog('shapetools:geodesictransformations',
                                       {})

    def flipRotateTool(self):
        processing.execAlgorithmDialog('shapetools:geodesicflip', {})

    def flipHorizontalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 0)

    def flipVerticalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 1)

    def rotate180Tool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 2)

    def rotate90CWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 3)

    def rotate90CCWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 4)

    def settings(self):
        if self.settingsDialog is None:
            self.settingsDialog = SettingsWidget(self.iface,
                                                 self.iface.mainWindow())
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(self.plugin_dir + '/index.html').toString()
        webbrowser.open(url, new=2)

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if self.previousLayer is not None:
            try:
                self.previousLayer.editingStarted.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
            try:
                self.previousLayer.editingStopped.disconnect(
                    self.layerEditingChanged)
            except Exception:
                pass
        self.previousLayer = None
        if layer is not None:
            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                self.previousLayer = layer
        self.enableTools()

    def layerEditingChanged(self):
        self.enableTools()

    def enableTools(self):
        self.digitizeAction.setEnabled(False)
        self.lineDigitizeAction.setEnabled(False)
        self.flipHorizontalAction.setEnabled(False)
        self.flipVerticalAction.setEnabled(False)
        self.rotate180Action.setEnabled(False)
        self.rotate90CWAction.setEnabled(False)
        self.rotate90CCWAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if not layer or not layer.isValid() or (
                layer.type() !=
                QgsMapLayer.VectorLayer) or not layer.isEditable():
            return
        wkbtype = layer.wkbType()
        geomtype = QgsWkbTypes.geometryType(wkbtype)
        self.lineDigitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.PointGeometry or geomtype == QgsWkbTypes.LineGeometry:
            self.digitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.LineGeometry or geomtype == QgsWkbTypes.PolygonGeometry:
            self.flipHorizontalAction.setEnabled(True)
            self.flipVerticalAction.setEnabled(True)
            self.rotate180Action.setEnabled(True)
            self.rotate90CWAction.setEnabled(True)
            self.rotate90CCWAction.setEnabled(True)
class ShapeTools(object):
    def __init__(self, iface):
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.settingsDialog = None
        self.shapeDialog = None
        self.xyLineDialog = None
        self.geodesicDensifyDialog = None
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        self.previousLayer = None
        self.toolbar = self.iface.addToolBar('Shape Tools Toolbar')
        self.toolbar.setObjectName('ShapeToolsToolbar')
        self.provider = ShapeToolsProvider()

    def initGui(self):
        self.azDigitizerTool = AzDigitizerTool(self.iface)
        self.lineDigitizerTool = LineDigitizerTool(self.iface)

        # Initialize the create shape menu item
        icon = QIcon(os.path.dirname(__file__) + '/images/shapes.png')
        self.shapeAction = QAction(icon, tr('Create shapes'),
                                   self.iface.mainWindow())
        self.shapeAction.setObjectName('stCreateShapes')
        self.shapeAction.triggered.connect(self.shapeTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.shapeAction)
        self.toolbar.addAction(self.shapeAction)

        # Initialize the XY to Line menu item
        icon = QIcon(os.path.dirname(__file__) + '/images/xyline.png')
        self.xyLineAction = QAction(icon, tr('XY to Line'),
                                    self.iface.mainWindow())
        self.xyLineAction.setObjectName('stXYtoLine')
        self.xyLineAction.triggered.connect(self.xyLineTool)
        self.iface.addPluginToVectorMenu('Shape Tools', self.xyLineAction)
        self.toolbar.addAction(self.xyLineAction)

        # Initialize the Geodesic Densifier menu item
        icon = QIcon(
            os.path.dirname(__file__) + '/images/geodesicDensifier.png')
        self.geodesicDensifyAction = QAction(icon,
                                             tr('Geodesic shape densifier'),
                                             self.iface.mainWindow())
        self.geodesicDensifyAction.setObjectName('stGeodesicDensifier')
        self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicDensifyAction)
        self.toolbar.addAction(self.geodesicDensifyAction)

        # Initialize the Geodesic line break menu item
        icon = QIcon(os.path.dirname(__file__) + '/images/idlbreak.png')
        self.geodesicLineBreakAction = QAction(
            icon, tr('Geodesic line break at -180,180'),
            self.iface.mainWindow())
        self.geodesicLineBreakAction.setObjectName('stGeodesicLineBreak')
        self.geodesicLineBreakAction.triggered.connect(
            self.geodesicLineBreakTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.geodesicLineBreakAction)
        self.toolbar.addAction(self.geodesicLineBreakAction)

        # Initialize Geodesic Measure Tool
        self.geodesicMeasureTool = GeodesicMeasureTool(self.iface,
                                                       self.iface.mainWindow())
        icon = QIcon(os.path.dirname(__file__) + '/images/measure.png')
        self.measureAction = QAction(icon, tr('Geodesic measure tool'),
                                     self.iface.mainWindow())
        self.measureAction.setObjectName('stGeodesicMeasureTool')
        self.measureAction.triggered.connect(self.measureTool)
        self.measureAction.setCheckable(True)
        self.iface.addPluginToVectorMenu('Shape Tools', self.measureAction)
        self.toolbar.addAction(self.measureAction)

        # Initialize Geodesic Measurement layer
        icon = QIcon(os.path.dirname(__file__) + '/images/measureLine.png')
        self.measureLayerAction = QAction(icon,
                                          tr('Geodesic measurement layer'),
                                          self.iface.mainWindow())
        self.measureLayerAction.setObjectName('stGeodesicLineBreak')
        self.measureLayerAction.triggered.connect(self.measureLayerTool)
        self.iface.addPluginToVectorMenu('Shape Tools',
                                         self.measureLayerAction)
        self.toolbar.addAction(self.measureLayerAction)

        menu = QMenu()
        # Initialize Geodesic transformation tool
        icon = QIcon(os.path.dirname(__file__) + '/images/transformShape.png')
        self.transformationsAction = menu.addAction(
            icon, tr('Geodesic transformations'), self.transformTool)
        self.transformationsAction.setObjectName('stGeodesicTransformations')

        icon = QIcon(os.path.dirname(__file__) + '/images/flip.png')
        self.flipRotateAction = menu.addAction(icon,
                                               tr('Geodesic flip and rotate'),
                                               self.flipRotateTool)
        self.flipRotateAction.setObjectName('stGeodesicFlipRotate')

        icon = QIcon(os.path.dirname(__file__) + '/images/flipHorizontal.png')
        self.flipHorizontalAction = menu.addAction(icon, tr('Flip horizontal'),
                                                   self.flipHorizontalTool)
        self.flipHorizontalAction.setObjectName('stGeodesicFlipHorizontal')
        self.flipHorizontalAction.setEnabled(False)
        icon = QIcon(os.path.dirname(__file__) + '/images/flipVertical.png')
        self.flipVerticalAction = menu.addAction(icon, tr('Flip vertical'),
                                                 self.flipVerticalTool)
        self.flipVerticalAction.setObjectName('stGeodesicFlipVertical')
        self.flipVerticalAction.setEnabled(False)
        icon = QIcon(os.path.dirname(__file__) + '/images/rotate180.png')
        self.rotate180Action = menu.addAction(icon, tr('Rotate 180\xb0'),
                                              self.rotate180Tool)
        self.rotate180Action.setObjectName('stGeodesicRotate180')
        self.rotate180Action.setEnabled(False)
        icon = QIcon(os.path.dirname(__file__) + '/images/rotatecw.png')
        self.rotate90CWAction = menu.addAction(icon, tr('Rotate 90\xb0 CW'),
                                               self.rotate90CWTool)
        self.rotate90CWAction.setObjectName('stGeodesicRotate90CW')
        self.rotate90CWAction.setEnabled(False)
        icon = QIcon(os.path.dirname(__file__) + '/images/rotateccw.png')
        self.rotate90CCWAction = menu.addAction(icon, tr('Rotate 90\xb0 CCW'),
                                                self.rotate90CCWTool)
        self.rotate90CCWAction.setObjectName('stGeodesicRotate90CCW')
        self.rotate90CCWAction.setEnabled(False)
        self.transformsAction = QAction(icon, tr('Geodesic Transforms'),
                                        self.iface.mainWindow())
        self.transformsAction.setMenu(menu)
        self.iface.addPluginToVectorMenu('Shape Tools', self.transformsAction)

        self.transformationButton = QToolButton()
        self.transformationButton.setMenu(menu)
        self.transformationButton.setDefaultAction(self.transformationsAction)
        self.transformationButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.transformationButton.triggered.connect(self.toolButtonTriggered)
        self.tranformToolbar = self.toolbar.addWidget(
            self.transformationButton)

        # Initialize the Azimuth Distance Digitize function
        icon = QIcon(os.path.dirname(__file__) + '/images/dazdigitize.png')
        self.digitizeAction = QAction(icon, tr('Azimuth distance digitizer'),
                                      self.iface.mainWindow())
        self.digitizeAction.setObjectName('stAzDistanceDigitizer')
        self.digitizeAction.triggered.connect(self.setShowAzDigitizerTool)
        self.digitizeAction.setCheckable(True)
        self.digitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools', self.digitizeAction)
        self.toolbar.addAction(self.digitizeAction)

        # Initialize the multi point azimuth Digitize function
        icon = QIcon(os.path.dirname(__file__) + '/images/linedigitize.png')
        self.lineDigitizeAction = QAction(
            icon, tr('Azimuth distance sequence digitizer'),
            self.iface.mainWindow())
        self.lineDigitizeAction.setObjectName('stLineDigitizer')
        self.lineDigitizeAction.triggered.connect(self.setShowLineDigitizeTool)
        self.lineDigitizeAction.setCheckable(True)
        self.lineDigitizeAction.setEnabled(False)
        self.iface.addPluginToVectorMenu(u'Shape Tools',
                                         self.lineDigitizeAction)
        self.toolbar.addAction(self.lineDigitizeAction)

        # Settings
        icon = QIcon(os.path.dirname(__file__) + '/images/settings.png')
        self.settingsAction = QAction(icon, tr('Settings'),
                                      self.iface.mainWindow())
        self.settingsAction.setObjectName('shapeToolsSettings')
        self.settingsAction.triggered.connect(self.settings)
        self.iface.addPluginToVectorMenu('Shape Tools', self.settingsAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/images/help.png')
        self.helpAction = QAction(icon, tr('Shape Tools help'),
                                  self.iface.mainWindow())
        self.helpAction.setObjectName('shapeToolsHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToVectorMenu('Shape Tools', self.helpAction)

        self.iface.currentLayerChanged.connect(self.currentLayerChanged)
        self.canvas.mapToolSet.connect(self.unsetTool)
        self.enableTools()

        # Add the processing provider
        QgsApplication.processingRegistry().addProvider(self.provider)

    def unsetTool(self, tool):
        try:
            if not isinstance(tool, GeodesicMeasureTool):
                self.measureAction.setChecked(False)
                self.geodesicMeasureTool.closeDialog()
            if not isinstance(tool, AzDigitizerTool):
                self.digitizeAction.setChecked(False)
            if not isinstance(tool, LineDigitizerTool):
                self.lineDigitizeAction.setChecked(False)
        except:
            pass

    def unload(self):
        self.canvas.unsetMapTool(self.azDigitizerTool)
        self.canvas.unsetMapTool(self.lineDigitizerTool)

        # remove from menu
        self.iface.removePluginVectorMenu('Shape Tools', self.shapeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.xyLineAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicDensifyAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.geodesicLineBreakAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.measureAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.measureLayerAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.transformsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.digitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools',
                                          self.lineDigitizeAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.settingsAction)
        self.iface.removePluginVectorMenu('Shape Tools', self.helpAction)
        # Remove from toolbar
        self.iface.removeToolBarIcon(self.shapeAction)
        self.iface.removeToolBarIcon(self.xyLineAction)
        self.iface.removeToolBarIcon(self.geodesicDensifyAction)
        self.iface.removeToolBarIcon(self.geodesicLineBreakAction)
        self.iface.removeToolBarIcon(self.measureAction)
        self.iface.removeToolBarIcon(self.measureLayerAction)
        self.iface.removeToolBarIcon(self.transformationsAction)
        self.iface.removeToolBarIcon(self.digitizeAction)
        self.iface.removeToolBarIcon(self.lineDigitizeAction)
        self.iface.removeToolBarIcon(self.tranformToolbar)
        self.azDigitizerTool = None
        self.lineDigitizerTool = None
        # remove the toolbar
        del self.toolbar

        QgsApplication.processingRegistry().removeProvider(self.provider)

    def toolButtonTriggered(self, action):
        self.transformationButton.setDefaultAction(action)

    def shapeTool(self):
        if self.shapeDialog is None:
            self.shapeDialog = Vector2ShapeWidget(self.iface,
                                                  self.iface.mainWindow())
        self.shapeDialog.show()

    def setShowAzDigitizerTool(self):
        self.digitizeAction.setChecked(True)
        self.canvas.setMapTool(self.azDigitizerTool)

    def setShowLineDigitizeTool(self):
        self.lineDigitizeAction.setChecked(True)
        self.canvas.setMapTool(self.lineDigitizerTool)

    def xyLineTool(self):
        results = processing.execAlgorithmDialog('shapetools:xy2line', {})

    def geodesicDensifyTool(self):
        results = processing.execAlgorithmDialog(
            'shapetools:geodesicdensifier', {})

    def geodesicLineBreakTool(self):
        results = processing.execAlgorithmDialog('shapetools:linebreak', {})

    def measureTool(self):
        self.measureAction.setChecked(True)
        self.canvas.setMapTool(self.geodesicMeasureTool)

    def measureLayerTool(self):
        results = processing.execAlgorithmDialog('shapetools:measurelayer', {})

    def transformTool(self):
        results = processing.execAlgorithmDialog(
            'shapetools:geodesictransformations', {})

    def flipRotateTool(self):
        results = processing.execAlgorithmDialog('shapetools:geodesicflip', {})

    def flipHorizontalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 0)

    def flipVerticalTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 1)

    def rotate180Tool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 2)

    def rotate90CWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 3)

    def rotate90CCWTool(self):
        layer = self.iface.activeLayer()
        flipLayer(self.iface, layer, 4)

    def settings(self):
        if self.settingsDialog is None:
            self.settingsDialog = SettingsWidget(self.iface,
                                                 self.iface.mainWindow())
        self.settingsDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) +
                                 '/index.html').toString()
        webbrowser.open(url, new=2)

    def currentLayerChanged(self):
        layer = self.iface.activeLayer()
        if self.previousLayer != None:
            try:
                self.previousLayer.editingStarted.disconnect(
                    self.layerEditingChanged)
            except:
                pass
            try:
                self.previousLayer.editingStopped.disconnect(
                    self.layerEditingChanged)
            except:
                pass
        self.previousLayer = None
        if layer != None:
            if isinstance(layer, QgsVectorLayer):
                layer.editingStarted.connect(self.layerEditingChanged)
                layer.editingStopped.connect(self.layerEditingChanged)
                self.previousLayer = layer
        self.enableTools()

    def layerEditingChanged(self):
        self.enableTools()

    def enableTools(self):
        self.digitizeAction.setEnabled(False)
        self.lineDigitizeAction.setEnabled(False)
        self.flipHorizontalAction.setEnabled(False)
        self.flipVerticalAction.setEnabled(False)
        self.rotate180Action.setEnabled(False)
        self.rotate90CWAction.setEnabled(False)
        self.rotate90CCWAction.setEnabled(False)
        layer = self.iface.activeLayer()

        if not layer or not layer.isValid() or (
                layer.type() !=
                QgsMapLayer.VectorLayer) or not layer.isEditable():
            return
        wkbtype = layer.wkbType()
        geomtype = QgsWkbTypes.geometryType(wkbtype)
        self.lineDigitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.PointGeometry or geomtype == QgsWkbTypes.LineGeometry:
            self.digitizeAction.setEnabled(True)
        if geomtype == QgsWkbTypes.LineGeometry or geomtype == QgsWkbTypes.PolygonGeometry:
            self.flipHorizontalAction.setEnabled(True)
            self.flipVerticalAction.setEnabled(True)
            self.rotate180Action.setEnabled(True)
            self.rotate90CWAction.setEnabled(True)
            self.rotate90CCWAction.setEnabled(True)
예제 #22
0
class ModelerDialog(BASE, WIDGET):
    ALG_ITEM = 'ALG_ITEM'
    PROVIDER_ITEM = 'PROVIDER_ITEM'
    GROUP_ITEM = 'GROUP_ITEM'

    NAME_ROLE = Qt.UserRole
    TAG_ROLE = Qt.UserRole + 1
    TYPE_ROLE = Qt.UserRole + 2

    CANVAS_SIZE = 4000

    update_model = pyqtSignal()

    def __init__(self, model=None):
        super().__init__(None)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.setupUi(self)

        self._variables_scope = None

        # LOTS of bug reports when we include the dock creation in the UI file
        # see e.g. #16428, #19068
        # So just roll it all by hand......!
        self.propertiesDock = QgsDockWidget(self)
        self.propertiesDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.propertiesDock.setObjectName("propertiesDock")
        propertiesDockContents = QWidget()
        self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents)
        self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0)
        self.verticalDockLayout_1.setSpacing(0)
        self.scrollArea_1 = QgsScrollArea(propertiesDockContents)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.scrollArea_1.sizePolicy().hasHeightForWidth())
        self.scrollArea_1.setSizePolicy(sizePolicy)
        self.scrollArea_1.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_1.setFrameShape(QFrame.NoFrame)
        self.scrollArea_1.setFrameShadow(QFrame.Plain)
        self.scrollArea_1.setWidgetResizable(True)
        self.scrollAreaWidgetContents_1 = QWidget()
        self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1)
        self.gridLayout.setContentsMargins(6, 6, 6, 6)
        self.gridLayout.setSpacing(4)
        self.label_1 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1)
        self.textName = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textName, 0, 1, 1, 1)
        self.label_2 = QLabel(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
        self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1)
        self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1)
        self.label_1.setText(self.tr("Name"))
        self.textName.setToolTip(self.tr("Enter model name here"))
        self.label_2.setText(self.tr("Group"))
        self.textGroup.setToolTip(self.tr("Enter group name here"))
        self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1)
        self.verticalDockLayout_1.addWidget(self.scrollArea_1)
        self.propertiesDock.setWidget(propertiesDockContents)
        self.propertiesDock.setWindowTitle(self.tr("Model Properties"))

        self.inputsDock = QgsDockWidget(self)
        self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                    | QDockWidget.DockWidgetMovable)
        self.inputsDock.setObjectName("inputsDock")
        self.inputsDockContents = QWidget()
        self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_2 = QgsScrollArea(self.inputsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_2.sizePolicy().hasHeightForWidth())
        self.scrollArea_2.setSizePolicy(sizePolicy)
        self.scrollArea_2.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_2.setFrameShape(QFrame.NoFrame)
        self.scrollArea_2.setFrameShadow(QFrame.Plain)
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollAreaWidgetContents_2 = QWidget()
        self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setSpacing(0)
        self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2)
        self.inputsTree.setAlternatingRowColors(True)
        self.inputsTree.header().setVisible(False)
        self.verticalLayout.addWidget(self.inputsTree)
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_3.addWidget(self.scrollArea_2)
        self.inputsDock.setWidget(self.inputsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock)
        self.inputsDock.setWindowTitle(self.tr("Inputs"))

        self.algorithmsDock = QgsDockWidget(self)
        self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.algorithmsDock.setObjectName("algorithmsDock")
        self.algorithmsDockContents = QWidget()
        self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents)
        sizePolicy.setHeightForWidth(
            self.scrollArea_3.sizePolicy().hasHeightForWidth())
        self.scrollArea_3.setSizePolicy(sizePolicy)
        self.scrollArea_3.setFocusPolicy(Qt.WheelFocus)
        self.scrollArea_3.setFrameShape(QFrame.NoFrame)
        self.scrollArea_3.setFrameShadow(QFrame.Plain)
        self.scrollArea_3.setWidgetResizable(True)
        self.scrollAreaWidgetContents_3 = QWidget()
        self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setSpacing(4)
        self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3)
        self.verticalLayout_2.addWidget(self.searchBox)
        self.algorithmTree = QgsProcessingToolboxTreeView(
            None, QgsApplication.processingRegistry())
        self.algorithmTree.setAlternatingRowColors(True)
        self.algorithmTree.header().setVisible(False)
        self.verticalLayout_2.addWidget(self.algorithmTree)
        self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)
        self.verticalLayout_4.addWidget(self.scrollArea_3)
        self.algorithmsDock.setWidget(self.algorithmsDockContents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock)
        self.algorithmsDock.setWindowTitle(self.tr("Algorithms"))
        self.searchBox.setToolTip(
            self.tr("Enter algorithm name to filter list"))
        self.searchBox.setShowSearchIcon(True)

        self.variables_dock = QgsDockWidget(self)
        self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable
                                        | QDockWidget.DockWidgetMovable)
        self.variables_dock.setObjectName("variablesDock")
        self.variables_dock_contents = QWidget()
        vl_v = QVBoxLayout()
        vl_v.setContentsMargins(0, 0, 0, 0)
        self.variables_editor = QgsVariableEditorWidget()
        vl_v.addWidget(self.variables_editor)
        self.variables_dock_contents.setLayout(vl_v)
        self.variables_dock.setWidget(self.variables_dock_contents)
        self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock)
        self.variables_dock.setWindowTitle(self.tr("Variables"))
        self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock)
        self.tabifyDockWidget(self.propertiesDock, self.variables_dock)
        self.variables_editor.scopeChanged.connect(self.variables_changed)

        self.bar = QgsMessageBar()
        self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
        self.centralWidget().layout().insertWidget(0, self.bar)

        try:
            self.setDockOptions(self.dockOptions()
                                | QMainWindow.GroupedDragging)
        except:
            pass

        if iface is not None:
            self.mToolbar.setIconSize(iface.iconSize())
            self.setStyleSheet(iface.mainWindow().styleSheet())

        self.toolbutton_export_to_script = QToolButton()
        self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup)
        self.export_to_script_algorithm_action = QAction(
            QCoreApplication.translate('ModelerDialog',
                                       'Export as Script Algorithm…'))
        self.toolbutton_export_to_script.addActions(
            [self.export_to_script_algorithm_action])
        self.toolbutton_export_to_script.setDefaultAction(
            self.export_to_script_algorithm_action)
        self.mToolbar.insertWidget(self.mActionExportImage,
                                   self.toolbutton_export_to_script)
        self.export_to_script_algorithm_action.triggered.connect(
            self.export_as_script_algorithm)

        self.mActionOpen.setIcon(
            QgsApplication.getThemeIcon('/mActionFileOpen.svg'))
        self.mActionSave.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSave.svg'))
        self.mActionSaveAs.setIcon(
            QgsApplication.getThemeIcon('/mActionFileSaveAs.svg'))
        self.mActionSaveInProject.setIcon(
            QgsApplication.getThemeIcon('/mAddToProject.svg'))
        self.mActionZoomActual.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomActual.svg'))
        self.mActionZoomIn.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomIn.svg'))
        self.mActionZoomOut.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomOut.svg'))
        self.mActionExportImage.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg'))
        self.mActionZoomToItems.setIcon(
            QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg'))
        self.mActionExportPdf.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg'))
        self.mActionExportSvg.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg'))
        self.toolbutton_export_to_script.setIcon(
            QgsApplication.getThemeIcon('/mActionSaveAsPython.svg'))
        self.mActionEditHelp.setIcon(
            QgsApplication.getThemeIcon('/mActionEditHelpContent.svg'))
        self.mActionRun.setIcon(
            QgsApplication.getThemeIcon('/mActionStart.svg'))

        self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock)
        self.tabifyDockWidget(self.inputsDock, self.algorithmsDock)
        self.inputsDock.raise_()

        self.setWindowFlags(Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint
                            | Qt.WindowCloseButtonHint)

        settings = QgsSettings()
        self.restoreState(
            settings.value("/Processing/stateModeler", QByteArray()))
        self.restoreGeometry(
            settings.value("/Processing/geometryModeler", QByteArray()))

        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(
            QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))

        self.view.setScene(self.scene)
        self.view.setAcceptDrops(True)
        self.view.ensureVisible(0, 0, 10, 10)
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96,
                        QgsApplication.desktop().logicalDpiX() / 96)

        def _dragEnterEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.acceptProposedAction()
            else:
                event.ignore()

        def _dropEvent(event):
            def alg_dropped(algorithm_id, pos):
                alg = QgsApplication.processingRegistry().createAlgorithmById(
                    algorithm_id)
                if alg is not None:
                    self._addAlgorithm(alg, pos)
                else:
                    assert False, algorithm_id

            def input_dropped(id, pos):
                if id in [
                        param.id() for param in QgsApplication.instance().
                        processingRegistry().parameterTypes()
                ]:
                    self.addInputOfType(itemId, pos)

            if event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                data = event.mimeData().data(
                    'application/x-vnd.qgis.qgis.algorithmid')
                stream = QDataStream(data, QIODevice.ReadOnly)
                algorithm_id = stream.readQString()
                QTimer.singleShot(
                    0,
                    lambda id=algorithm_id, pos=self.view.mapToScene(event.pos(
                    )): alg_dropped(id, pos))
                event.accept()
            elif event.mimeData().hasText():
                itemId = event.mimeData().text()
                QTimer.singleShot(0,
                                  lambda id=itemId, pos=self.view.mapToScene(
                                      event.pos()): input_dropped(id, pos))
                event.accept()
            else:
                event.ignore()

        def _dragMoveEvent(event):
            if event.mimeData().hasText() or event.mimeData().hasFormat(
                    'application/x-vnd.qgis.qgis.algorithmid'):
                event.accept()
            else:
                event.ignore()

        def _wheelEvent(event):
            self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)

            settings = QgsSettings()
            factor = settings.value('/qgis/zoom_favor', 2.0)

            # "Normal" mouse has an angle delta of 120, precision mouses provide data
            # faster, in smaller steps
            factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y())

            if (event.modifiers() == Qt.ControlModifier):
                factor = 1.0 + (factor - 1.0) / 20.0

            if event.angleDelta().y() < 0:
                factor = 1 / factor

            self.view.scale(factor, factor)

        def _enterEvent(e):
            QGraphicsView.enterEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mouseReleaseEvent(e):
            QGraphicsView.mouseReleaseEvent(self.view, e)
            self.view.viewport().setCursor(Qt.ArrowCursor)

        def _mousePressEvent(e):
            if e.button() == Qt.MidButton:
                self.previousMousePos = e.pos()
            else:
                QGraphicsView.mousePressEvent(self.view, e)

        def _mouseMoveEvent(e):
            if e.buttons() == Qt.MidButton:
                offset = self.previousMousePos - e.pos()
                self.previousMousePos = e.pos()

                self.view.verticalScrollBar().setValue(
                    self.view.verticalScrollBar().value() + offset.y())
                self.view.horizontalScrollBar().setValue(
                    self.view.horizontalScrollBar().value() + offset.x())
            else:
                QGraphicsView.mouseMoveEvent(self.view, e)

        self.view.setDragMode(QGraphicsView.ScrollHandDrag)
        self.view.dragEnterEvent = _dragEnterEvent
        self.view.dropEvent = _dropEvent
        self.view.dragMoveEvent = _dragMoveEvent
        self.view.wheelEvent = _wheelEvent
        self.view.enterEvent = _enterEvent
        self.view.mousePressEvent = _mousePressEvent
        self.view.mouseMoveEvent = _mouseMoveEvent

        def _mimeDataInput(items):
            mimeData = QMimeData()
            text = items[0].data(0, Qt.UserRole)
            mimeData.setText(text)
            return mimeData

        self.inputsTree.mimeData = _mimeDataInput

        self.inputsTree.setDragDropMode(QTreeWidget.DragOnly)
        self.inputsTree.setDropIndicatorShown(True)

        self.algorithms_model = ModelerToolboxModel(
            self, QgsApplication.processingRegistry())
        self.algorithmTree.setToolboxProxyModel(self.algorithms_model)
        self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly)
        self.algorithmTree.setDropIndicatorShown(True)

        filters = QgsProcessingToolboxProxyModel.Filters(
            QgsProcessingToolboxProxyModel.FilterModeler)
        if ProcessingConfig.getSetting(
                ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES):
            filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues
        self.algorithmTree.setFilters(filters)

        if hasattr(self.searchBox, 'setPlaceholderText'):
            self.searchBox.setPlaceholderText(
                QCoreApplication.translate('ModelerDialog', 'Search…'))
        if hasattr(self.textName, 'setPlaceholderText'):
            self.textName.setPlaceholderText(self.tr('Enter model name here'))
        if hasattr(self.textGroup, 'setPlaceholderText'):
            self.textGroup.setPlaceholderText(self.tr('Enter group name here'))

        # Connect signals and slots
        self.inputsTree.doubleClicked.connect(self.addInput)
        self.searchBox.textChanged.connect(self.algorithmTree.setFilterString)
        self.algorithmTree.doubleClicked.connect(self.addAlgorithm)

        # Ctrl+= should also trigger a zoom in action
        ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self)
        ctrlEquals.activated.connect(self.zoomIn)

        self.mActionOpen.triggered.connect(self.openModel)
        self.mActionSave.triggered.connect(self.save)
        self.mActionSaveAs.triggered.connect(self.saveAs)
        self.mActionSaveInProject.triggered.connect(self.saveInProject)
        self.mActionZoomIn.triggered.connect(self.zoomIn)
        self.mActionZoomOut.triggered.connect(self.zoomOut)
        self.mActionZoomActual.triggered.connect(self.zoomActual)
        self.mActionZoomToItems.triggered.connect(self.zoomToItems)
        self.mActionExportImage.triggered.connect(self.exportAsImage)
        self.mActionExportPdf.triggered.connect(self.exportAsPdf)
        self.mActionExportSvg.triggered.connect(self.exportAsSvg)
        #self.mActionExportPython.triggered.connect(self.exportAsPython)
        self.mActionEditHelp.triggered.connect(self.editHelp)
        self.mActionRun.triggered.connect(self.runModel)

        if model is not None:
            self.model = model.create()
            self.model.setSourceFilePath(model.sourceFilePath())
            self.textGroup.setText(self.model.group())
            self.textName.setText(self.model.displayName())
            self.repaintModel()

        else:
            self.model = QgsProcessingModelAlgorithm()
            self.model.setProvider(
                QgsApplication.processingRegistry().providerById('model'))
        self.update_variables_gui()

        self.fillInputsTree()

        self.view.centerOn(0, 0)
        self.help = None

        self.hasChanged = False

    def closeEvent(self, evt):
        settings = QgsSettings()
        settings.setValue("/Processing/stateModeler", self.saveState())
        settings.setValue("/Processing/geometryModeler", self.saveGeometry())

        if self.hasChanged:
            ret = QMessageBox.question(
                self, self.tr('Save Model?'),
                self.
                tr('There are unsaved changes in this model. Do you want to keep those?'
                   ),
                QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Discard,
                QMessageBox.Cancel)

            if ret == QMessageBox.Save:
                self.saveModel(False)
                evt.accept()
            elif ret == QMessageBox.Discard:
                evt.accept()
            else:
                evt.ignore()
        else:
            evt.accept()

    def editHelp(self):
        alg = self.model
        dlg = HelpEditionDialog(alg)
        dlg.exec_()
        if dlg.descriptions:
            self.model.setHelpContent(dlg.descriptions)
            self.hasChanged = True

    def update_variables_gui(self):
        variables_scope = QgsExpressionContextScope(self.tr('Model Variables'))
        for k, v in self.model.variables().items():
            variables_scope.setVariable(k, v)
        variables_context = QgsExpressionContext()
        variables_context.appendScope(variables_scope)
        self.variables_editor.setContext(variables_context)
        self.variables_editor.setEditableScopeIndex(0)

    def variables_changed(self):
        self.model.setVariables(self.variables_editor.variablesInActiveScope())

    def runModel(self):
        if len(self.model.childAlgorithms()) == 0:
            self.bar.pushMessage(
                "",
                self.
                tr("Model doesn't contain any algorithm and/or parameter and can't be executed"
                   ),
                level=Qgis.Warning,
                duration=5)
            return

        dlg = AlgorithmDialog(self.model.create(), parent=iface.mainWindow())
        dlg.exec_()

    def save(self):
        self.saveModel(False)

    def saveAs(self):
        self.saveModel(True)

    def saveInProject(self):
        if not self.can_save():
            return

        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        self.model.setSourceFilePath(None)

        project_provider = QgsApplication.processingRegistry().providerById(
            PROJECT_PROVIDER_ID)
        project_provider.add_model(self.model)

        self.update_model.emit()
        self.bar.pushMessage("",
                             self.tr("Model was saved inside current project"),
                             level=Qgis.Success,
                             duration=5)

        self.hasChanged = False
        QgsProject.instance().setDirty(True)

    def zoomIn(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomOut(self):
        self.view.setTransformationAnchor(QGraphicsView.NoAnchor)
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))

        settings = QgsSettings()
        factor = settings.value('/qgis/zoom_favor', 2.0)
        factor = 1 / factor

        self.view.scale(factor, factor)
        self.view.centerOn(point)
        self.repaintModel()

    def zoomActual(self):
        point = self.view.mapToScene(
            QPoint(self.view.viewport().width() / 2,
                   self.view.viewport().height() / 2))
        self.view.resetTransform()
        self.view.scale(QgsApplication.desktop().logicalDpiX() / 96,
                        QgsApplication.desktop().logicalDpiX() / 96)
        self.view.centerOn(point)

    def zoomToItems(self):
        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        self.view.fitInView(totalRect, Qt.KeepAspectRatio)

    def exportAsImage(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As Image'), '',
            self.tr('PNG files (*.png *.PNG)'))
        if not filename:
            return

        if not filename.lower().endswith('.png'):
            filename += '.png'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        imgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        img = QImage(totalRect.width(), totalRect.height(),
                     QImage.Format_ARGB32_Premultiplied)
        img.fill(Qt.white)
        painter = QPainter()
        painter.setRenderHint(QPainter.Antialiasing)
        painter.begin(img)
        self.scene.render(painter, imgRect, totalRect)
        painter.end()

        img.save(filename)

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as image to <a href=\"{}\">{}</a>"
            ).format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsPdf(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As PDF'), '',
            self.tr('PDF files (*.pdf *.PDF)'))
        if not filename:
            return

        if not filename.lower().endswith('.pdf'):
            filename += '.pdf'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        printerRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        printer = QPrinter()
        printer.setOutputFormat(QPrinter.PdfFormat)
        printer.setOutputFileName(filename)
        printer.setPaperSize(QSizeF(printerRect.width(), printerRect.height()),
                             QPrinter.DevicePixel)
        printer.setFullPage(True)

        painter = QPainter(printer)
        self.scene.render(painter, printerRect, totalRect)
        painter.end()

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as PDF to <a href=\"{}\">{}</a>").
            format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsSvg(self):
        self.repaintModel(controls=False)
        filename, fileFilter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As SVG'), '',
            self.tr('SVG files (*.svg *.SVG)'))
        if not filename:
            return

        if not filename.lower().endswith('.svg'):
            filename += '.svg'

        totalRect = self.scene.itemsBoundingRect()
        totalRect.adjust(-10, -10, 10, 10)
        svgRect = QRectF(0, 0, totalRect.width(), totalRect.height())

        svg = QSvgGenerator()
        svg.setFileName(filename)
        svg.setSize(QSize(totalRect.width(), totalRect.height()))
        svg.setViewBox(svgRect)
        svg.setTitle(self.model.displayName())

        painter = QPainter(svg)
        self.scene.render(painter, svgRect, totalRect)
        painter.end()

        self.bar.pushMessage(
            "",
            self.tr(
                "Successfully exported model as SVG to <a href=\"{}\">{}</a>").
            format(
                QUrl.fromLocalFile(filename).toString(),
                QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)
        self.repaintModel(controls=True)

    def exportAsPython(self):
        filename, filter = QFileDialog.getSaveFileName(
            self, self.tr('Save Model As Python Script'), '',
            self.tr('Processing scripts (*.py *.PY)'))
        if not filename:
            return

        if not filename.lower().endswith('.py'):
            filename += '.py'

        text = self.model.asPythonCode()
        with codecs.open(filename, 'w', encoding='utf-8') as fout:
            fout.write(text)

        self.bar.pushMessage(
            "",
            self.
            tr("Successfully exported model as python script to <a href=\"{}\">{}</a>"
               ).format(
                   QUrl.fromLocalFile(filename).toString(),
                   QDir.toNativeSeparators(filename)),
            level=Qgis.Success,
            duration=5)

    def can_save(self):
        """
        Tests whether a model can be saved, or if it is not yet valid
        :return: bool
        """
        if str(self.textName.text()).strip() == '':
            self.bar.pushWarning(
                "", self.tr('Please a enter model name before saving'))
            return False

        return True

    def saveModel(self, saveAs):
        if not self.can_save():
            return
        self.model.setName(str(self.textName.text()))
        self.model.setGroup(str(self.textGroup.text()))
        if self.model.sourceFilePath() and not saveAs:
            filename = self.model.sourceFilePath()
        else:
            filename, filter = QFileDialog.getSaveFileName(
                self, self.tr('Save Model'),
                ModelerUtils.modelsFolders()[0],
                self.tr('Processing models (*.model3 *.MODEL3)'))
            if filename:
                if not filename.endswith('.model3'):
                    filename += '.model3'
                self.model.setSourceFilePath(filename)
        if filename:
            if not self.model.toFile(filename):
                if saveAs:
                    QMessageBox.warning(
                        self, self.tr('I/O error'),
                        self.tr('Unable to save edits. Reason:\n {0}').format(
                            str(sys.exc_info()[1])))
                else:
                    QMessageBox.warning(
                        self, self.tr("Can't save model"),
                        QCoreApplication.
                        translate('QgsPluginInstallerInstallingDialog', (
                            "This model can't be saved in its original location (probably you do not "
                            "have permission to do it). Please, use the 'Save as…' option."
                        )))
                return
            self.update_model.emit()
            if saveAs:
                self.bar.pushMessage(
                    "",
                    self.tr(
                        "Model was correctly saved to <a href=\"{}\">{}</a>").
                    format(
                        QUrl.fromLocalFile(filename).toString(),
                        QDir.toNativeSeparators(filename)),
                    level=Qgis.Success,
                    duration=5)
            else:
                self.bar.pushMessage("",
                                     self.tr("Model was correctly saved"),
                                     level=Qgis.Success,
                                     duration=5)

            self.hasChanged = False

    def openModel(self):
        filename, selected_filter = QFileDialog.getOpenFileName(
            self, self.tr('Open Model'),
            ModelerUtils.modelsFolders()[0],
            self.tr('Processing models (*.model3 *.MODEL3)'))
        if filename:
            self.loadModel(filename)

    def loadModel(self, filename):
        alg = QgsProcessingModelAlgorithm()
        if alg.fromFile(filename):
            self.model = alg
            self.model.setProvider(
                QgsApplication.processingRegistry().providerById('model'))
            self.textGroup.setText(alg.group())
            self.textName.setText(alg.name())
            self.repaintModel()

            self.update_variables_gui()

            self.view.centerOn(0, 0)
            self.hasChanged = False
        else:
            QgsMessageLog.logMessage(
                self.tr('Could not load model {0}').format(filename),
                self.tr('Processing'), Qgis.Critical)
            QMessageBox.critical(
                self, self.tr('Open Model'),
                self.tr('The selected model could not be loaded.\n'
                        'See the log for more information.'))

    def repaintModel(self, controls=True):
        self.scene = ModelerScene(self, dialog=self)
        self.scene.setSceneRect(
            QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE))
        self.scene.paintModel(self.model, controls)
        self.view.setScene(self.scene)

    def addInput(self):
        item = self.inputsTree.currentItem()
        param = item.data(0, Qt.UserRole)
        self.addInputOfType(param)

    def create_widget_context(self):
        """
        Returns a new widget context for use in the model editor
        """
        widget_context = QgsProcessingParameterWidgetContext()
        widget_context.setProject(QgsProject.instance())
        if iface is not None:
            widget_context.setMapCanvas(iface.mapCanvas())
        widget_context.setModel(self.model)
        return widget_context

    def autogenerate_parameter_name(self, parameter):
        """
        Automatically generates and sets a new parameter's name, based on the parameter's
        description and ensuring that it is unique for the model.
        """
        validChars = \
            'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
        safeName = ''.join(c for c in parameter.description()
                           if c in validChars)
        name = safeName.lower()
        i = 2
        while self.model.parameterDefinition(name):
            name = safeName.lower() + str(i)
            i += 1
        parameter.setName(safeName)

    def addInputOfType(self, paramType, pos=None):
        new_param = None
        if ModelerParameterDefinitionDialog.use_legacy_dialog(
                paramType=paramType):
            dlg = ModelerParameterDefinitionDialog(self.model, paramType)
            if dlg.exec_():
                new_param = dlg.param
        else:
            # yay, use new API!
            context = createContext()
            widget_context = self.create_widget_context()
            dlg = QgsProcessingParameterDefinitionDialog(
                type=paramType,
                context=context,
                widgetContext=widget_context,
                algorithm=self.model)
            if dlg.exec_():
                new_param = dlg.createParameter()
                self.autogenerate_parameter_name(new_param)

        if new_param is not None:
            if pos is None:
                pos = self.getPositionForParameterItem()
            if isinstance(pos, QPoint):
                pos = QPointF(pos)
            component = QgsProcessingModelParameter(new_param.name())
            component.setDescription(new_param.name())
            component.setPosition(pos)
            self.model.addModelParameter(new_param, component)
            self.repaintModel()
            # self.view.ensureVisible(self.scene.getLastParameterItem())
            self.hasChanged = True

    def getPositionForParameterItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if len(self.model.parameterComponents()) > 0:
            maxX = max([
                i.position().x()
                for i in list(self.model.parameterComponents().values())
            ])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
        else:
            newX = MARGIN + BOX_WIDTH / 2
        return QPointF(newX, MARGIN + BOX_HEIGHT / 2)

    def fillInputsTree(self):
        icon = QIcon(os.path.join(pluginPath, 'images', 'input.svg'))
        parametersItem = QTreeWidgetItem()
        parametersItem.setText(0, self.tr('Parameters'))
        sortedParams = sorted(
            QgsApplication.instance().processingRegistry().parameterTypes(),
            key=lambda pt: pt.name())
        for param in sortedParams:
            if param.flags() & QgsProcessingParameterType.ExposeToModeler:
                paramItem = QTreeWidgetItem()
                paramItem.setText(0, param.name())
                paramItem.setData(0, Qt.UserRole, param.id())
                paramItem.setIcon(0, icon)
                paramItem.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                                   | Qt.ItemIsDragEnabled)
                paramItem.setToolTip(0, param.description())
                parametersItem.addChild(paramItem)
        self.inputsTree.addTopLevelItem(parametersItem)
        parametersItem.setExpanded(True)

    def addAlgorithm(self):
        algorithm = self.algorithmTree.selectedAlgorithm()
        if algorithm is not None:
            alg = QgsApplication.processingRegistry().createAlgorithmById(
                algorithm.id())
            self._addAlgorithm(alg)

    def _addAlgorithm(self, alg, pos=None):
        dlg = ModelerParametersDialog(alg, self.model)
        if dlg.exec_():
            alg = dlg.createAlgorithm()
            if pos is None:
                alg.setPosition(self.getPositionForAlgorithmItem())
            else:
                alg.setPosition(pos)
            from processing.modeler.ModelerGraphicItem import ModelerGraphicItem
            for i, out in enumerate(alg.modelOutputs()):
                alg.modelOutput(out).setPosition(
                    alg.position() +
                    QPointF(ModelerGraphicItem.BOX_WIDTH, (i + 1.5) *
                            ModelerGraphicItem.BOX_HEIGHT))
            self.model.addChildAlgorithm(alg)
            self.repaintModel()
            self.hasChanged = True

    def getPositionForAlgorithmItem(self):
        MARGIN = 20
        BOX_WIDTH = 200
        BOX_HEIGHT = 80
        if self.model.childAlgorithms():
            maxX = max([
                alg.position().x()
                for alg in list(self.model.childAlgorithms().values())
            ])
            maxY = max([
                alg.position().y()
                for alg in list(self.model.childAlgorithms().values())
            ])
            newX = min(MARGIN + BOX_WIDTH + maxX, self.CANVAS_SIZE - BOX_WIDTH)
            newY = min(MARGIN + BOX_HEIGHT + maxY,
                       self.CANVAS_SIZE - BOX_HEIGHT)
        else:
            newX = MARGIN + BOX_WIDTH / 2
            newY = MARGIN * 2 + BOX_HEIGHT + BOX_HEIGHT / 2
        return QPointF(newX, newY)

    def export_as_script_algorithm(self):
        dlg = ScriptEditorDialog(None)

        dlg.editor.setText('\n'.join(
            self.model.asPythonCode(
                QgsProcessing.PythonQgsProcessingAlgorithmSubclass, 4)))
        dlg.show()
예제 #23
0
class QWeather:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # 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]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'QWeather_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&QWeather')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'QWeather')
        self.toolbar.setObjectName(u'QWeather')
        self.key1 = '9Q2gyTzBLVGVSTWdoJnM9Y29uc'

        self.toolButton = QToolButton()
        self.toolButton.setMenu(QMenu())
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolbar.addWidget(self.toolButton)

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('QWeather', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        # Create the dialog (after translation) and keep reference

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def _generate_signature(self, key, data):
        key_bytes = bytes(key, 'utf-8')
        data_bytes = bytes(data, 'utf-8')
        signature = hmac.new(key_bytes, data_bytes, hashlib.sha1).digest()
        return b64encode(signature).decode()

    def get_yahoo_weather(
            self,
            location,
            temp_type,
            app_id,
            consumer_key,
            consumer_secret,
            url='https://weather-ydn-yql.media.yahoo.com/forecastrss'):
        # Basic info
        method = 'GET'
        concat = '&'
        query = {'location': location, 'format': 'json', 'u': temp_type}
        oauth = {
            'oauth_consumer_key': consumer_key,
            'oauth_nonce': uuid.uuid4().hex,
            'oauth_signature_method': 'HMAC-SHA1',
            'oauth_timestamp': str(int(time.time())),
            'oauth_version': '1.0'
        }

        # Prepare signature string (merge all params and SORT them)
        merged_params = query.copy()
        merged_params.update(oauth)
        sorted_params = [
            k + '=' + urllib.parse.quote(merged_params[k], safe='')
            for k in sorted(merged_params.keys())
        ]
        signature_base_str = method + concat + urllib.parse.quote(
            url, safe='') + concat + urllib.parse.quote(
                concat.join(sorted_params), safe='')

        # Generate signature
        composite_key = urllib.parse.quote(consumer_secret, safe='') + concat
        oauth_signature = self._generate_signature(composite_key,
                                                   signature_base_str)

        # Prepare Authorization header
        oauth['oauth_signature'] = oauth_signature
        auth_header = (
            'OAuth ' +
            ', '.join(['{}="{}"'.format(k, v) for k, v in oauth.items()]))

        # Send request
        url = url + '?' + urllib.parse.urlencode(query)
        request = urllib.request.Request(url)
        request.add_header('Authorization', auth_header)
        request.add_header('X-Yahoo-App-Id', app_id)
        response = urllib.request.urlopen(request).read()
        return json.loads(response)

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        icon_path = ':/plugins/QWeather/weather.png'
        self.mainButton = QAction(QIcon(icon_path), "Weather Info",
                                  self.iface.mainWindow())
        self.mainButton.triggered.connect(self.run)

        icon_path = ':/plugins/QWeather/icons/reload.png'
        self.reloadButton = self.add_action(
            icon_path,
            text=self.tr(u'Reload QWeather layer'),
            callback=self.reloadWeather,
            parent=self.iface.mainWindow())

        self.style_temperature_btn = QAction(QIcon(''), "Temperature",
                                             self.iface.mainWindow())
        self.style_temperature_btn.setText("Temperature")
        self.style_temperature_btn.triggered.connect(self.style_temperature)

        self.style_direction_btn = QAction(QIcon(''), "Direction",
                                           self.iface.mainWindow())
        self.style_direction_btn.setText("Direction")
        self.style_direction_btn.triggered.connect(self.style_direction)

        self.style_humidity_btn = QAction(QIcon(''), "Humidity",
                                          self.iface.mainWindow())
        self.style_humidity_btn.setText("Humidity")
        self.style_humidity_btn.triggered.connect(self.style_humidity)

        menu = self.toolButton.menu()
        menu.addAction(self.mainButton)
        menu.addAction(self.style_temperature_btn)
        menu.addSeparator()
        menu.addAction(self.style_direction_btn)
        menu.addAction(self.style_humidity_btn)
        self.toolButton.setDefaultAction(self.mainButton)

        self.dlg = QWeatherDialog()
        #self.dlg.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint | Qt.WindowCloseButtonHint)
        self.key2 = 'VtZXJzZWNyZXQmc3Y9MCZ4PTZl'
        self.dlg.ok.clicked.connect(self.ok)
        self.dlg.closebutton.clicked.connect(self.close)
        self.dlg.toolButtonImport.clicked.connect(self.toolButtonImport)
        self.dlg.checkBox.clicked.connect(self.customBox)
        self.csvFile = None
        self.current = 'World Capitals'
        self.layerTemp = "QWeather"
        self.reload = False
        self.dlg.checkBox.setChecked(True)
        self.reloadButton.setEnabled(False)
        self.app_id = 'IyELbl3e'
        self.consumer_key = 'dj0yJmk' + self.key1 + '3' + self.key2
        self.consumer_secret = 'e9962f3287764230d163045f737f9ad81428cdcc'

    def style_humidity(self):
        try:
            self.QWeather.styleManager().setCurrentStyle('humidity')
        except:
            pass

    def style_temperature(self):
        try:
            self.QWeather.styleManager().setCurrentStyle('temperature')
        except:
            pass

    def style_direction(self):
        try:
            self.QWeather.styleManager().setCurrentStyle('direction')
        except:
            pass

    def reloadWeather(self):
        self.reload = True
        if self.csvFile is None:
            self.csvFile = os.path.join(self.plugin_dir, 'World Capitals.csv')
        self.dlg.imp.setText(self.csvFile)
        self.ok()

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&QWeather'), action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def customBox(self):
        if self.dlg.checkBox.isChecked():
            self.dlg.comboBox.setEnabled(False)
            self.dlg.toolButtonImport.setEnabled(True)
            self.dlg.imp.setEnabled(True)
        else:
            if 'Countries.csv' in self.dlg.imp.text():
                self.csvFile = os.path.join(self.plugin_dir,
                                            'World Capitals.csv')
                self.dlg.imp.setText(self.csvFile)

            self.dlg.comboBox.setEnabled(True)
            self.dlg.toolButtonImport.setEnabled(False)
            self.dlg.imp.setEnabled(False)

    def run(self):
        self.dlg.ok.setEnabled(True)
        self.dlg.closebutton.setEnabled(True)
        self.dlg.toolButtonImport.setEnabled(True)
        if self.csvFile is None:
            self.csvFile = os.path.join(self.plugin_dir, 'World Capitals.csv')
        self.dlg.imp.setText(self.csvFile)
        self.dlg.Celsius.setChecked(True)
        self.dlg.progressBar.setValue(0)

        self.customBox()

        self.dlg.comboBox.clear()
        db_list = [
            'World Capitals', 'Afghanistan', 'Aland', 'Albania', 'Algeria',
            'American Samoa', 'Andorra', 'Angola', 'Antarctica',
            'Antigua and Barbuda', 'Argentina', 'Armenia', 'Aruba',
            'Australia', 'Austria', 'Azerbaijan', 'Bahrain', 'Bangladesh',
            'Barbados', 'Belarus', 'Belgium', 'Belize', 'Benin', 'Bermuda',
            'Bhutan', 'Bolivia', 'Bosnia and Herzegovina', 'Botswana',
            'Brazil', 'Brunei', 'Bulgaria', 'Burkina Faso', 'Burundi',
            'Cambodia', 'Cameroon', 'Canada', 'Cape Verde', 'Cayman Islands',
            'Central African Republic', 'Chad', 'Chile', 'China', 'Colombia',
            'Comoros', 'Congo (Brazzaville)', 'Congo (Kinshasa)',
            'Cook Islands', 'Costa Rica', 'Croatia', 'Cuba', 'Curacao',
            'Cyprus', 'Czech Republic', 'Denmark', 'Djibouti', 'Dominica',
            'Dominican Republic', 'East Timor', 'Ecuador', 'Egypt',
            'El Salvador', 'Equatorial Guinea', 'Eritrea', 'Estonia',
            'Ethiopia', 'Falkland Islands', 'Faroe Islands',
            'Federated States of Micronesia', 'Fiji', 'Finland', 'France',
            'French Polynesia', 'Gabon', 'Georgia', 'Germany', 'Ghana',
            'Gibraltar', 'Greece', 'Greenland', 'Grenada', 'Guam', 'Guatemala',
            'Guinea', 'Guinea Bissau', 'Guyana', 'Haiti', 'Honduras',
            'Hong Kong S.A.R.', 'Hungary', 'Iceland', 'India', 'Indonesia',
            'Iran', 'Iraq', 'Ireland', 'Isle of Man', 'Israel', 'Italy',
            'Ivory Coast', 'Jamaica', 'Japan', 'Jordan', 'Kazakhstan', 'Kenya',
            'Kiribati', 'Kosovo', 'Kuwait', 'Kyrgyzstan', 'Laos', 'Latvia',
            'Lebanon', 'Lesotho', 'Liberia', 'Libya', 'Liechtenstein',
            'Lithuania', 'Luxembourg', 'Macau S.A.R', 'Macedonia',
            'Madagascar', 'Malawi', 'Malaysia', 'Maldives', 'Mali', 'Malta',
            'Marshall Islands', 'Mauritania', 'Mauritius', 'Mexico', 'Moldova',
            'Monaco', 'Mongolia', 'Montenegro', 'Morocco', 'Mozambique',
            'Myanmar', 'Namibia', 'Nepal', 'Netherlands', 'New Caledonia',
            'New Zealand', 'Nicaragua', 'Niger', 'Nigeria', 'North Korea',
            'Northern Mariana Islands', 'Norway', 'Oman', 'Pakistan', 'Palau',
            'Palestine', 'Panama', 'Papua New Guinea', 'Paraguay', 'Peru',
            'Philippines', 'Poland', 'Portugal', 'Puerto Rico', 'Qatar',
            'Romania', 'Russia', 'Rwanda', 'Saint Kitts and Nevis',
            'Saint Lucia', 'Saint Vincent and the Grenadines', 'Samoa',
            'San Marino', 'Sao Tome and Principe', 'Saudi Arabia', 'Senegal',
            'Serbia', 'Seychelles', 'Sierra Leone', 'Singapore', 'Slovakia',
            'Slovenia', 'Solomon Islands', 'Somalia', 'Somaliland',
            'South Africa', 'South Georgia and the Islands', 'South Korea',
            'South Sudan', 'Spain', 'Sri Lanka', 'Sudan', 'Suriname',
            'Svalbard and Jan Mayen Islands', 'Swaziland', 'Sweden',
            'Switzerland', 'Syria', 'Taiwan', 'Tajikistan', 'Tanzania',
            'Thailand', 'The Bahamas', 'The Gambia', 'Togo', 'Tonga',
            'Trinidad and Tobago', 'Tunisia', 'Turkey', 'Turkmenistan',
            'Turks and Caicos Islands', 'Tuvalu', 'Uganda', 'Ukraine',
            'United Arab Emirates', 'United Kingdom',
            'United States Virgin Islands', 'USA', 'Uruguay', 'Uzbekistan',
            'Vanuatu', 'Vatican (Holy Sea)', 'Venezuela', 'Vietnam',
            'Western Sahara', 'Yemen', 'Zambia', 'Zimbabwe'
        ]

        self.dlg.comboBox.addItems(db_list)
        self.dlg.comboBox.setCurrentText(self.current)
        if self.dlg.isVisible():
            self.dlg.close()
            self.dlg.show()
        else:
            self.dlg.show()

    def close(self):
        self.dlg.close()

    def toolButtonImport(self):
        self.csvFile = QFileDialog.getOpenFileName(
            None, "Choose the file",
            os.path.join(os.path.join(os.path.expanduser('~')), 'Desktop'),
            "(*.csv)")
        if self.csvFile[0] == "":
            self.csvFile = os.path.join(self.plugin_dir, 'World Capitals.csv')
            self.dlg.imp.setText(self.csvFile)
            return

        self.csvFile = self.csvFile[0]
        self.dlg.imp.setText(self.csvFile)

    def selectOutp(self):
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Warning)
        msgBox.setWindowTitle('Warning')
        msgBox.setText('Please define a csv file with locations.')
        msgBox.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint
                              | Qt.WindowCloseButtonHint)
        msgBox.exec_()
        return True

    def call_import_temps_task(self):
        self.taskWeather = QgsTask.fromFunction(u'QWeather',
                                                self.import_temps_task,
                                                on_finished=self.completed,
                                                wait_time=4)
        QgsApplication.taskManager().addTask(self.taskWeather)

    def import_temps_task(self, task, wait_time):
        for i, location in enumerate(self.all_cities):
            try:
                time.sleep(.1)
                perc = (i / len(self.all_cities)) * 100
                self.taskWeather.setProgress(perc)
                self.dlg.progressBar.setValue(perc)
                data = self.get_yahoo_weather(
                    location.replace("'", ""),
                    self.unit,
                    self.app_id,
                    self.consumer_key,
                    self.consumer_secret,
                    url='https://weather-ydn-yql.media.yahoo.com/forecastrss')

                if data['location'] == {}:
                    continue
                fields = {}
                fieldnames = [
                    'country', 'city', 'region', 'temperature',
                    'temperature_unit', 'date', 'direction', 'direction_unit',
                    'speed', 'speed_unit', 'humidity', 'humidity_unit',
                    'pressure', 'pressure_unit', 'visibility',
                    'visibility_unit', 'sunrise', 'sunset', 'icon', 'lat',
                    'lon'
                ]
                for field_init in fieldnames:
                    fields[field_init] = []
                try:
                    fields['city'] = data['location']['city']
                    fields['temperature'] = str(data['current_observation']
                                                ['condition']['temperature'])
                    if not fields['temperature'].isnumeric():
                        continue
                    fields['country'] = data['location']['country'].replace(
                        'ô', 'o').replace('´', '')
                    fields['region'] = data['location']['region'].replace(
                        '´', '')
                    fields['direction'] = str(
                        data['current_observation']['wind']['direction'])
                    fields['direction_unit'] = self.unitDirection
                    fields['speed'] = str(
                        data['current_observation']['wind']['speed'])
                    fields['speed_unit'] = self.unitSpeed
                    fields['humidity'] = str(
                        data['current_observation']['atmosphere']['humidity'])
                    fields['humidity_unit'] = self.unitHumidity
                    fields['pressure'] = str(
                        data['current_observation']['atmosphere']['pressure'])
                    fields['pressure_unit'] = self.unitPressure
                    fields['visibility'] = str(data['current_observation']
                                               ['atmosphere']['visibility'])
                    fields['visibility_unit'] = self.unitVisibility
                    fields['sunrise'] = str(
                        data['current_observation']['astronomy']['sunrise'])
                    fields['sunset'] = str(
                        data['current_observation']['astronomy']['sunset'])
                    Lon = data['location']['long']
                    Lat = data['location']['lat']
                    fields['lon'] = str(Lon)
                    fields['lat'] = str(Lat)
                    fields['date'] = time.ctime(
                        int(str(data['current_observation']['pubDate'])))
                    try:
                        fields['icon'] = data['current_observation'][
                            'condition']['text']
                    except:
                        fields['icon'] = ' '
                except:
                    pass

                fields['temperature_unit'] = self.unit
                geo_info = {
                    "type": "Feature",
                    "properties": fields,
                    "geometry": {
                        "coordinates": [Lon, Lat],
                        "type": "Point"
                    }
                }
                self.geoinfo.append(geo_info)

                if self.taskWeather.isCanceled():
                    self.stopped(self.taskWeather)
                    self.taskWeather.destroyed()
                    return None
            except:
                pass
        return True

    def stopped(self, task):
        QgsMessageLog.logMessage(
            'Task "{name}" was canceled'.format(name=task.description()),
            'QWeather', Qgis.Info)

    def completed(self, exception, result=None):
        geojson = {
            "type": "FeatureCollection",
            "name": self.layerTemp,
            "crs": {
                "type": "name",
                "properties": {
                    "name": "crs:OGC:1.3:CRS84"
                }
            },
            "features": self.geoinfo
        }

        with open(self.outQWeatherGeoJson, 'w') as geofile:
            json.dump(geojson, geofile)

        if len(QgsProject.instance().mapLayersByName(self.layerTemp)) == 0:
            self.addQWeatherLayer()
        else:
            for x in self.iface.mapCanvas().layers():
                if x.name() == self.layerTemp:
                    self.QWeather = x
                    QgsProject.instance().removeMapLayer(self.QWeather.id())
                    self.addQWeatherLayer()
        try:
            self.QWeather.selectAll()
            self.iface.mapCanvas().zoomToSelected()
            self.QWeather.removeSelection()
        except:
            pass

        ###########################################

        self.dlg.ok.setEnabled(True)
        self.dlg.closebutton.setEnabled(True)
        if not self.dlg.checkBox.isChecked():
            self.dlg.toolButtonImport.setEnabled(False)
        else:
            self.dlg.toolButtonImport.setEnabled(True)

        self.reloadButton.setEnabled(True)
        self.dlg.progressBar.setValue(100)
        self.dlg.close()

    def addQWeatherLayer(self):
        # load qml to current style
        self.QWeather = self.iface.addVectorLayer(self.outQWeatherGeoJson,
                                                  self.layerTemp, "ogr")
        style_manager = self.QWeather.styleManager()
        # read valid style from layer
        style = QgsMapLayerStyle()
        style.readFromLayer(self.QWeather)
        self.QWeather.loadNamedStyle(
            os.path.join(self.plugin_dir, "icons", self.style2 + ".qml"))
        style_manager.renameStyle("default", "direction")

        style_name = "humidity"
        # add style with new name
        style_manager.addStyle(style_name, style)
        # set new style as current
        style_manager.setCurrentStyle(style_name)
        self.QWeather.loadNamedStyle(
            os.path.join(self.plugin_dir, "icons", "humidity.qml"))
        style_manager.renameStyle(style_name, style_name)

        style = QgsMapLayerStyle()
        style.readFromLayer(self.QWeather)
        style_name = self.style
        # add style with new name
        style_manager.addStyle(style_name, style)
        # set new style as current
        style_manager.setCurrentStyle(style_name)
        self.QWeather.loadNamedStyle(
            os.path.join(self.plugin_dir, "icons", self.style + ".qml"))
        style_manager.renameStyle(self.style, "temperature")

    def ok(self):
        if not self.reload:
            if self.dlg.imp.text() == '':
                if self.selectOutp():
                    return
            elif not os.path.isabs(self.dlg.imp.text()):
                if self.selectOutp():
                    return
        else:
            self.reload = False

        self.csvFile = self.dlg.imp.text()
        status = False
        if not self.dlg.checkBox.isChecked():
            self.current = self.dlg.comboBox.currentText()
            status = self.current.upper() == 'WORLD CAPITALS'
            if status:
                self.csvFile = os.path.join(self.plugin_dir,
                                            'World Capitals.csv')

        if not self.dlg.checkBox.isChecked() and not status:
            self.csvFile = os.path.join(self.plugin_dir, 'Countries.csv')
            with open(self.csvFile, 'r') as f_all:
                self.all_cities = []
                for line in f_all:
                    mm = line.rstrip(', ').upper()
                    if self.current.upper() in mm:
                        self.all_cities.append(mm[:-1])
        else:
            try:
                with open(self.csvFile, 'r') as f:
                    self.all_cities = [line.rstrip('\n').upper() for line in f]
            except:
                msgBox = QMessageBox()
                msgBox.setIcon(QMessageBox.Warning)
                msgBox.setWindowTitle('QWeather')
                msgBox.setText('Please define a csv file path.')
                msgBox.setWindowFlags(Qt.CustomizeWindowHint
                                      | Qt.WindowStaysOnTopHint
                                      | Qt.WindowCloseButtonHint)
                msgBox.exec_()
                return

        self.outQWeatherGeoJson = os.path.join(self.plugin_dir,
                                               'QWeather.geojson')
        basename = os.path.basename(self.outQWeatherGeoJson)
        self.layerTemp = basename[:-8]

        try:
            f = open(self.outQWeatherGeoJson, "w")
            f.close()
        except:
            self.selectOutp()

        self.dlg.ok.setEnabled(False)
        self.dlg.closebutton.setEnabled(False)
        self.dlg.toolButtonImport.setEnabled(False)

        if not self.iface.actionSelectRectangle().isChecked():
            self.iface.actionSelectRectangle().trigger()
        if not self.iface.actionMapTips().isChecked():
            self.iface.actionMapTips().trigger()

        if len(self.all_cities) > 1000:
            msgBox = QMessageBox()
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setWindowTitle('Warning')
            msgBox.setText('Maximum locations must be below from 1000.')
            msgBox.setWindowFlags(Qt.CustomizeWindowHint
                                  | Qt.WindowStaysOnTopHint
                                  | Qt.WindowCloseButtonHint)
            msgBox.exec_()
            ###########################################
            self.dlg.progressBar.setValue(100)
            self.dlg.progressBar.setValue(0)
            self.dlg.ok.setEnabled(True)
            self.dlg.closebutton.setEnabled(True)
            self.dlg.toolButtonImport.setEnabled(True)
            return

        # do stuff
        if self.dlg.Celsius.isChecked():
            self.unit = 'C'
            self.unitDirection = "degrees"
            self.unitSpeed = "km/h"
            self.unitHumidity = "%"
            self.unitVisibility = "km"
            self.unitPressure = "hPa"
            self.style = 'weather_c'
            self.style2 = 'direction_c'

        else:
            self.unit = 'F'
            self.unitDirection = "degrees"
            self.unitSpeed = "mph"
            self.unitHumidity = "%"
            self.unitVisibility = "mi"
            self.unitPressure = "psi"
            self.style = 'weather_f'
            self.style2 = 'direction_f'

        self.geoinfo = []
        self.call_import_temps_task()
예제 #24
0
class PyArchInitPlugin(object):
    HOME = os.environ['PYARCHINIT_HOME']

    PARAMS_DICT = {
        'SERVER': '',
        'HOST': '',
        'DATABASE': '',
        'PASSWORD': '',
        'PORT': '',
        'USER': '',
        'THUMB_PATH': '',
        'EXPERIMENTAL': ''
    }

    path_rel = os.path.join(os.sep, str(HOME), 'pyarchinit_DB_folder',
                            'config.cfg')
    conf = open(path_rel, "r")
    data = conf.read()
    PARAMS_DICT = eval(data)

    # TODO: find a better way to settings config
    # if 'EXPERIMENTAL' in PARAMS_DICT:
    #     PARAMS_DICT['EXPERIMENTAL'] = 'No'
    #     f = open(path_rel, "w")
    #     f.write(str(PARAMS_DICT))
    #     f.close()

    def __init__(self, iface):
        self.iface = iface
        userPluginPath = os.path.dirname(__file__)
        systemPluginPath = QgsApplication.prefixPath(
        ) + "/python/plugins/pyarchinit"

        overrideLocale = QgsSettings().value("locale/overrideFlag",
                                             QVariant)  # .toBool()
        if not overrideLocale:
            localeFullName = QLocale.system().name()
        else:
            localeFullName = QgsSettings().value("locale/userLocale",
                                                 QVariant)  # .toString()

        if QFileInfo(userPluginPath).exists():
            translationPath = userPluginPath + "/i18n/pyarchinit_plugin_" + localeFullName + ".qm"
        else:
            translationPath = systemPluginPath + "/i18n/pyarchinit_plugin_" + localeFullName + ".qm"

        self.localePath = translationPath
        if QFileInfo(self.localePath).exists():
            self.translator = QTranslator()
            self.translator.load(self.localePath)
            QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        settings = QgsSettings()
        icon_paius = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'pai_us.png'))
        self.action = QAction(QIcon(icon_paius), "pyArchInit Main Panel",
                              self.iface.mainWindow())
        self.action.triggered.connect(self.showHideDockWidget)

        # dock widget
        self.dockWidget = PyarchinitPluginDialog(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget)

        # TOOLBAR
        self.toolBar = self.iface.addToolBar("pyArchInit")
        self.toolBar.setObjectName("pyArchInit")
        self.toolBar.addAction(self.action)

        self.dataToolButton = QToolButton(self.toolBar)
        self.dataToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        ######  Section dedicated to the basic data entry
        # add Actions data
        icon_site = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconSite.png'))
        self.actionSite = QAction(QIcon(icon_site), "Siti",
                                  self.iface.mainWindow())
        self.actionSite.setWhatsThis("Siti")
        self.actionSite.triggered.connect(self.runSite)

        icon_US = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconSus.png'))
        self.actionUS = QAction(QIcon((icon_US)), u"US",
                                self.iface.mainWindow())
        self.actionUS.setWhatsThis(u"US")
        self.actionUS.triggered.connect(self.runUS)

        icon_Finds = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'iconFinds.png'))
        self.actionInr = QAction(QIcon(icon_Finds), "Reperti",
                                 self.iface.mainWindow())
        self.actionInr.setWhatsThis("Reperti")
        self.actionInr.triggered.connect(self.runInr)

        icon_camp_exp = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'champion.png'))
        self.actionCampioni = QAction(QIcon(icon_camp_exp), "Campioni",
                                      self.iface.mainWindow())
        self.actionCampioni.setWhatsThis("Campioni")
        self.actionCampioni.triggered.connect(self.runCampioni)

        icon_Lapidei = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconAlma.png'))
        self.actionLapidei = QAction(QIcon(icon_Lapidei), "Lapidei",
                                     self.iface.mainWindow())
        self.actionLapidei.setWhatsThis("Lapidei")
        self.actionLapidei.triggered.connect(self.runLapidei)

        self.dataToolButton.addActions([
            self.actionSite, self.actionUS, self.actionInr,
            self.actionCampioni, self.actionLapidei
        ])
        self.dataToolButton.setDefaultAction(self.actionSite)

        self.toolBar.addWidget(self.dataToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the interpretations
        # add Actions interpretation
        self.interprToolButton = QToolButton(self.toolBar)
        self.interprToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_per = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconPer.png'))
        self.actionPer = QAction(QIcon(icon_per), "Periodizzazione",
                                 self.iface.mainWindow())
        self.actionPer.setWhatsThis("Periodizzazione")
        self.actionPer.triggered.connect(self.runPer)

        icon_Struttura = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'iconStrutt.png'))
        self.actionStruttura = QAction(QIcon(icon_Struttura), "Strutture",
                                       self.iface.mainWindow())
        self.actionPer.setWhatsThis("Strutture")
        self.actionStruttura.triggered.connect(self.runStruttura)

        self.interprToolButton.addActions(
            [self.actionStruttura, self.actionPer])
        self.interprToolButton.setDefaultAction(self.actionStruttura)

        self.toolBar.addWidget(self.interprToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the funerary archaeology
        # add Actions funerary archaeology
        self.funeraryToolButton = QToolButton(self.toolBar)
        self.funeraryToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_Schedaind = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconIND.png'))
        self.actionSchedaind = QAction(QIcon(icon_Schedaind), "Individui",
                                       self.iface.mainWindow())
        self.actionSchedaind.setWhatsThis("Individui")
        self.actionSchedaind.triggered.connect(self.runSchedaind)

        icon_Tafonomia = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'iconGrave.png'))
        self.actionTafonomia = QAction(QIcon(icon_Tafonomia),
                                       "Tafonomica/Sepolture",
                                       self.iface.mainWindow())
        self.actionTafonomia.setWhatsThis("Tafonomica/Sepolture")
        self.actionTafonomia.triggered.connect(self.runTafonomia)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            icon_Detsesso = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'iconSesso.png'))
            self.actionDetsesso = QAction(QIcon(icon_Detsesso),
                                          "Determinazione Sesso",
                                          self.iface.mainWindow())
            self.actionDetsesso.setWhatsThis("Determinazione del sesso")
            self.actionDetsesso.triggered.connect(self.runDetsesso)

            icon_Deteta = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'iconEta.png'))
            self.actionDeteta = QAction(QIcon(icon_Deteta),
                                        u"Determinazione dell'età",
                                        self.iface.mainWindow())
            self.actionSchedaind.setWhatsThis(u"Determinazione dell'età")
            self.actionDeteta.triggered.connect(self.runDeteta)

        self.funeraryToolButton.addActions(
            [self.actionSchedaind, self.actionTafonomia])
        self.funeraryToolButton.setDefaultAction(self.actionSchedaind)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.funeraryToolButton.addActions(
                [self.actionDetsesso, self.actionDeteta])

        self.toolBar.addWidget(self.funeraryToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to the topographical research
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.topoToolButton = QToolButton(self.toolBar)
            self.topoToolButton.setPopupMode(QToolButton.MenuButtonPopup)

            icon_UT = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'iconUT.png'))
            self.actionUT = QAction(QIcon(icon_UT), u"Unità Topografiche",
                                    self.iface.mainWindow())
            self.actionUT.setWhatsThis(u"Unità Topografiche")
            self.actionUT.triggered.connect(self.runUT)

            self.topoToolButton.addActions([self.actionUT])
            self.topoToolButton.setDefaultAction(self.actionUT)

            self.toolBar.addWidget(self.topoToolButton)

            self.toolBar.addSeparator()

        ######  Section dedicated to the documentation
        # add Actions documentation
        self.docToolButton = QToolButton(self.toolBar)
        self.docToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_documentazione = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'icondoc.png'))
        self.actionDocumentazione = QAction(QIcon(icon_documentazione),
                                            "Scheda Documentazione",
                                            self.iface.mainWindow())
        self.actionDocumentazione.setWhatsThis("Documentazione")
        self.actionDocumentazione.triggered.connect(self.runDocumentazione)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            icon_imageViewer = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'photo.png'))
            self.actionimageViewer = QAction(QIcon(icon_imageViewer),
                                             "Gestione immagini",
                                             self.iface.mainWindow())
            self.actionimageViewer.setWhatsThis("Gestione immagini")
            self.actionimageViewer.triggered.connect(self.runImageViewer)

            icon_Directory_export = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'directoryExp.png'))
            self.actionImages_Directory_export = QAction(
                QIcon(icon_Directory_export), "Esportazione immagini",
                self.iface.mainWindow())
            self.actionImages_Directory_export.setWhatsThis(
                "Esportazione immagini")
            self.actionImages_Directory_export.triggered.connect(
                self.runImages_directory_export)

            icon_pdf_exp = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'pdf-icon.png'))
            self.actionpdfExp = QAction(QIcon(icon_pdf_exp),
                                        "Esportazione PDF",
                                        self.iface.mainWindow())
            self.actionpdfExp.setWhatsThis("Esportazione PDF")
            self.actionpdfExp.triggered.connect(self.runPdfexp)

        self.docToolButton.addActions([self.actionDocumentazione])

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.docToolButton.addActions([
                self.actionpdfExp, self.actionimageViewer, self.actionpdfExp,
                self.actionImages_Directory_export
            ])

        self.docToolButton.setDefaultAction(self.actionDocumentazione)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.actionImages_Directory_export.setCheckable(True)
            self.actionpdfExp.setCheckable(True)
            self.actionimageViewer.setCheckable(True)

        self.toolBar.addWidget(self.docToolButton)

        self.toolBar.addSeparator()

        ######  Section dedicated to elaborations
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.elabToolButton = QToolButton(self.toolBar)
            self.elabToolButton.setPopupMode(QToolButton.MenuButtonPopup)

            # add Actions elaboration
            icon_Archeozoology = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'iconMegacero.png'))
            self.actionArcheozoology = QAction(QIcon(icon_Archeozoology),
                                               "Statistiche Archeozoologiche",
                                               self.iface.mainWindow())
            self.actionArcheozoology.setWhatsThis(
                "Statistiche Archeozoologiche")
            self.actionArcheozoology.triggered.connect(self.runArcheozoology)

            icon_GisTimeController = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons',
                             'iconTimeControll.png'))
            self.actionGisTimeController = QAction(
                QIcon(icon_GisTimeController), "Time Manager",
                self.iface.mainWindow())
            self.actionGisTimeController.setWhatsThis("Time Manager")
            self.actionGisTimeController.triggered.connect(
                self.runGisTimeController)

            icon_Comparision = '{}{}'.format(
                filepath,
                os.path.join(os.sep, 'resources', 'icons', 'comparision.png'))
            self.actionComparision = QAction(QIcon(icon_Comparision),
                                             "Comparazione immagini",
                                             self.iface.mainWindow())
            self.actionComparision.setWhatsThis("Comparazione immagini")
            self.actionComparision.triggered.connect(self.runComparision)

            self.elabToolButton.addActions([
                self.actionArcheozoology, self.actionComparision,
                self.actionGisTimeController
            ])
            self.elabToolButton.setDefaultAction(self.actionArcheozoology)

            self.toolBar.addWidget(self.elabToolButton)

            self.toolBar.addSeparator()

        ######  Section dedicated to the plugin management

        self.manageToolButton = QToolButton(self.toolBar)
        self.manageToolButton.setPopupMode(QToolButton.MenuButtonPopup)

        icon_thesaurus = '{}{}'.format(
            filepath,
            os.path.join(os.sep, 'resources', 'icons', 'thesaurusicon.png'))
        self.actionThesaurus = QAction(QIcon(icon_thesaurus),
                                       "Thesaurus sigle",
                                       self.iface.mainWindow())
        self.actionThesaurus.setWhatsThis("Thesaurus sigle")
        self.actionThesaurus.triggered.connect(self.runThesaurus)

        icon_Con = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconConn.png'))
        self.actionConf = QAction(QIcon(icon_Con), "Configurazione plugin",
                                  self.iface.mainWindow())
        self.actionConf.setWhatsThis("Configurazione plugin")
        self.actionConf.triggered.connect(self.runConf)

        icon_Dbmanagment = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons', 'backup.png'))
        self.actionDbmanagment = QAction(QIcon(icon_Dbmanagment),
                                         "Gestione database",
                                         self.iface.mainWindow())
        self.actionDbmanagment.setWhatsThis("Gestione database")
        self.actionDbmanagment.triggered.connect(self.runDbmanagment)

        icon_Info = '{}{}'.format(
            filepath, os.path.join(os.sep, 'resources', 'icons',
                                   'iconInfo.png'))
        self.actionInfo = QAction(QIcon(icon_Info), "Plugin info",
                                  self.iface.mainWindow())
        self.actionInfo.setWhatsThis("Plugin info")
        self.actionInfo.triggered.connect(self.runInfo)

        self.manageToolButton.addActions([
            self.actionConf, self.actionThesaurus, self.actionDbmanagment,
            self.actionInfo
        ])
        self.manageToolButton.setDefaultAction(self.actionConf)

        self.toolBar.addWidget(self.manageToolButton)

        self.toolBar.addSeparator()

        # menu
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionSite)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionUS)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionInr)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionCampioni)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionLapidei)

        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionStruttura)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionPer)

        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionSchedaind)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionTafonomia)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionDetsesso)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionDeteta)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionUT)

        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionDocumentazione)

        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionimageViewer)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionpdfExp)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionImages_Directory_export)

            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionArcheozoology)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionComparision)
            self.iface.addPluginToMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionGisTimeController)

        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionConf)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionThesaurus)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionDbmanagment)
        self.iface.addPluginToMenu("&pyArchInit - Archaeological GIS Tools",
                                   self.actionInfo)

        # MENU
        self.menu = QMenu("pyArchInit")
        # self.pyarchinitSite = pyarchinit_Site(self.iface)
        self.menu.addActions([
            self.actionSite, self.actionUS, self.actionInr,
            self.actionCampioni, self.actionLapidei
        ])
        self.menu.addSeparator()
        self.menu.addActions([self.actionPer, self.actionStruttura])
        self.menu.addSeparator()
        self.menu.addActions([self.actionTafonomia, self.actionSchedaind])
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.menu.addActions([self.actionDetsesso, self.actionDeteta])
        self.menu.addSeparator()
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.menu.addActions([self.actionUT])
        self.menu.addActions([self.actionDocumentazione])
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.menu.addActions([
                self.actionimageViewer, self.actionpdfExp,
                self.actionImages_Directory_export
            ])
        self.menu.addSeparator()
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.menu.addActions([
                self.actionArcheozoology, self.actionComparision,
                self.actionGisTimeController
            ])
        self.menu.addSeparator()
        self.menu.addActions([
            self.actionConf, self.actionThesaurus, self.actionDbmanagment,
            self.actionInfo
        ])
        menuBar = self.iface.mainWindow().menuBar()
        menuBar.addMenu(self.menu)

    ##
    def runSite(self):
        pluginGui = pyarchinit_Site(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runPer(self):
        pluginGui = pyarchinit_Periodizzazione(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runStruttura(self):
        pluginGui = pyarchinit_Struttura(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runUS(self):
        pluginGui = pyarchinit_US(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runInr(self):
        pluginGui = pyarchinit_Inventario_reperti(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runCampioni(self):
        pluginGui = pyarchinit_Campioni(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runLapidei(self):
        pluginGui = pyarchinit_Inventario_Lapidei(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runGisTimeController(self):
        pluginGui = pyarchinit_Gis_Time_Controller(self.iface)
        pluginGui.show()
        self.pluginGui = pluginGui  # save

    def runConf(self):
        pluginConfGui = pyArchInitDialog_Config()
        pluginConfGui.show()
        self.pluginGui = pluginConfGui  # save

    def runInfo(self):
        pluginInfoGui = pyArchInitDialog_Info()
        pluginInfoGui.show()
        self.pluginGui = pluginInfoGui  # save

    def runImageViewer(self):
        pluginImageView = Main()
        pluginImageView.show()
        self.pluginGui = pluginImageView  # save

    def runTafonomia(self):
        pluginTafonomia = pyarchinit_Tafonomia(self.iface)
        pluginTafonomia.show()
        self.pluginGui = pluginTafonomia  # save

    def runSchedaind(self):
        pluginIndividui = pyarchinit_Schedaind(self.iface)
        pluginIndividui.show()
        self.pluginGui = pluginIndividui  # save

    def runDetsesso(self):
        pluginSesso = pyarchinit_Detsesso(self.iface)
        pluginSesso.show()
        self.pluginGui = pluginSesso  # save

    def runDeteta(self):
        pluginEta = pyarchinit_Deteta(self.iface)
        pluginEta.show()
        self.pluginGui = pluginEta  # save

    def runArcheozoology(self):
        pluginArchezoology = pyarchinit_Archeozoology(self.iface)
        pluginArchezoology.show()
        self.pluginGui = pluginArchezoology  # save

    def runUT(self):
        pluginUT = pyarchinit_UT(self.iface)
        pluginUT.show()
        self.pluginGui = pluginUT  # save

    def runImages_directory_export(self):
        pluginImage_directory_export = pyarchinit_Images_directory_export()
        pluginImage_directory_export.show()
        self.pluginGui = pluginImage_directory_export  # save

    def runComparision(self):
        pluginComparision = Comparision()
        pluginComparision.show()
        self.pluginGui = pluginComparision  # save

    def runDbmanagment(self):
        pluginDbmanagment = pyarchinit_dbmanagment(self.iface)
        pluginDbmanagment.show()
        self.pluginGui = pluginDbmanagment  # save

    def runPdfexp(self):
        pluginPdfexp = pyarchinit_pdf_export(self.iface)
        pluginPdfexp.show()
        self.pluginGui = pluginPdfexp  # save

    def runThesaurus(self):
        pluginThesaurus = pyarchinit_Thesaurus(self.iface)
        pluginThesaurus.show()
        self.pluginGui = pluginThesaurus  # save

    def runDocumentazione(self):
        pluginDocumentazione = pyarchinit_Documentazione(self.iface)
        pluginDocumentazione.show()
        self.pluginGui = pluginDocumentazione  # save

    def unload(self):
        # Remove the plugin
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionSite)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionPer)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionStruttura)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionUS)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionInr)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionCampioni)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionLapidei)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionSchedaind)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionDocumentazione)
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionDetsesso)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionDeteta)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionTafonomia)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionArcheozoology)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionUT)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionimageViewer)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionImages_Directory_export)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools", self.actionpdfExp)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionComparision)
            self.iface.removePluginMenu(
                "&pyArchInit - Archaeological GIS Tools",
                self.actionGisTimeController)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionConf)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionThesaurus)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionInfo)
        self.iface.removePluginMenu("&pyArchInit - Archaeological GIS Tools",
                                    self.actionDbmanagment)

        self.iface.removeToolBarIcon(self.actionSite)
        self.iface.removeToolBarIcon(self.actionPer)
        self.iface.removeToolBarIcon(self.actionStruttura)
        self.iface.removeToolBarIcon(self.actionUS)
        self.iface.removeToolBarIcon(self.actionInr)
        self.iface.removeToolBarIcon(self.actionCampioni)
        self.iface.removeToolBarIcon(self.actionLapidei)
        self.iface.removeToolBarIcon(self.actionTafonomia)
        self.iface.removeToolBarIcon(self.actionSchedaind)
        self.iface.removeToolBarIcon(self.actionDocumentazione)
        if self.PARAMS_DICT['EXPERIMENTAL'] == 'Si':
            self.iface.removeToolBarIcon(self.actionDetsesso)
            self.iface.removeToolBarIcon(self.actionDeteta)
            self.iface.removeToolBarIcon(self.actionArcheozoology)
            self.iface.removeToolBarIcon(self.actionUT)
            # self.iface.removeToolBarIcon(self.actionUpd)
            self.iface.removeToolBarIcon(self.actionimageViewer)
            self.iface.removeToolBarIcon(self.actionImages_Directory_export)
            self.iface.removeToolBarIcon(self.actionpdfExp)
            self.iface.removeToolBarIcon(self.actionComparision)
            self.iface.removeToolBarIcon(self.actionGisTimeController)
        self.iface.removeToolBarIcon(self.actionConf)
        self.iface.removeToolBarIcon(self.actionThesaurus)
        self.iface.removeToolBarIcon(self.actionInfo)
        self.iface.removeToolBarIcon(self.actionDbmanagment)

        self.dockWidget.setVisible(False)
        self.iface.removeDockWidget(self.dockWidget)

        # remove tool bar
        del self.toolBar

    def showHideDockWidget(self):
        if self.dockWidget.isVisible():
            self.dockWidget.hide()
        else:
            self.dockWidget.show()
예제 #25
0
class Giswater(QObject):
    def __init__(self, iface):
        """ Constructor
        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """

        super(Giswater, self).__init__()

        # Initialize instance attributes
        self.iface = iface
        self.srid = None
        self.load_project = None
        self.dict_toolbars = {}
        self.dict_actions = {}
        self.actions_not_checkable = None
        self.available_layers = []
        self.btn_add_layers = None
        self.update_sql = None
        self.action = None
        self.action_info = None
        self.toolButton = None

    def initGui(self):
        """ Create the menu entries and toolbar icons inside the QGIS GUI """

        # Initialize plugin
        self.init_plugin()

        # Force project read (to work with PluginReloader)
        self.project_read(False)

    def init_plugin(self):
        """ Plugin main initialization function """

        # Initialize plugin global variables
        self.plugin_dir = os.path.dirname(__file__)
        global_vars.plugin_dir = self.plugin_dir
        global_vars.iface = self.iface
        self.plugin_name = get_value_from_metadata('name', 'giswater')
        self.icon_folder = self.plugin_dir + os.sep + 'icons' + os.sep

        global_vars.init_global(self.iface, self.iface.mapCanvas(),
                                self.plugin_dir, self.plugin_name)

        # Check if config file exists
        setting_file = os.path.join(self.plugin_dir, 'config',
                                    self.plugin_name + '.config')
        if not os.path.exists(setting_file):
            message = f"Config file not found at: {setting_file}"
            self.iface.messageBar().pushMessage("", message, 1, 20)
            return

        # Set plugin and QGIS settings: stored in the registry (on Windows) or .ini file (on Unix)
        global_vars.init_settings(setting_file)
        global_vars.init_qgis_settings(self.plugin_name)

        # Enable Python console and Log Messages panel if parameter 'enable_python_console' = True
        # python_enable_console = global_vars.settings.value('system_variables/enable_python_console', 'FALSE').upper()
        # if python_enable_console == 'TRUE':
        #     enable_python_console()

        # Define signals
        self.set_signals()

        # Set controller (no database connection yet)
        self.controller = DaoController(self.plugin_name,
                                        self.iface,
                                        create_logger=True)
        self.controller.set_plugin_dir(self.plugin_dir)
        global_vars.controller = self.controller

        # Set main information button (always visible)
        self.set_info_button()

        # Manage section 'actions_list' of config file
        self.manage_section_actions_list()

        # Manage section 'toolbars' of config file
        self.manage_section_toolbars()

    def set_signals(self):
        """ Define widget and event signals """

        try:
            self.iface.projectRead.connect(self.project_read)
            self.iface.newProjectCreated.connect(self.project_new)
            self.iface.actionSaveProject().triggered.connect(
                self.save_toolbars_position)
        except AttributeError:
            pass

    def set_info_button(self):
        """ Set main information button (always visible) """

        self.toolButton = QToolButton()
        self.action_info = self.iface.addToolBarWidget(self.toolButton)

        icon_path = self.icon_folder + '36.png'
        if os.path.exists(icon_path):
            icon = QIcon(icon_path)
            self.action = QAction(icon, "Show info", self.iface.mainWindow())
        else:
            self.action = QAction("Show info", self.iface.mainWindow())

        self.toolButton.setDefaultAction(self.action)
        self.update_sql = GwAdmin()
        self.action.triggered.connect(self.update_sql.init_sql)

    def unset_info_button(self):
        """ Unset main information button (when plugin is disabled or reloaded) """

        if self.action:
            self.action.triggered.disconnect()
        if self.action_info:
            self.iface.removeToolBarIcon(self.action_info)
        self.action = None
        self.action_info = None

    def manage_section_actions_list(self):
        """ Manage section 'actions_list' of config file """

        # Dynamically get parameters defined in section 'actions_list'
        section = 'actions_not_checkable'
        global_vars.settings.beginGroup(section)
        list_keys = global_vars.settings.allKeys()
        global_vars.settings.endGroup()
        for key in list_keys:
            list_values = global_vars.settings.value(f"{section}/{key}")
            if list_values:
                self.dict_actions[key] = list_values
            else:
                self.controller.show_warning(
                    f"Parameter not set in section '{section}' of config file: '{key}'"
                )

        # Get list of actions not checkable (normally because they open a form)
        aux = []
        for list_actions in self.dict_actions.values():
            for elem in list_actions:
                aux.append(elem)

        self.actions_not_checkable = sorted(aux)

    def manage_section_toolbars(self):
        """ Manage section 'toolbars' of config file """

        # Dynamically get parameters defined in section 'toolbars'
        section = 'toolbars'
        global_vars.settings.beginGroup(section)
        list_keys = global_vars.settings.allKeys()
        global_vars.settings.endGroup()
        for key in list_keys:
            list_values = global_vars.settings.value(f"{section}/{key}")
            if list_values:
                # Check if list_values has only one value
                if type(list_values) is str:
                    list_values = [list_values]
                self.dict_toolbars[key] = list_values
            else:
                self.controller.show_warning(
                    f"Parameter not set in section '{section}' of config file: '{key}'"
                )

    def project_new(self):
        """ Function executed when a user creates a new QGIS project """

        self.unload(False)

    def project_read(self, show_warning=True):
        """ Function executed when a user opens a QGIS project (*.qgs) """

        # Unload plugin before reading opened project
        self.unload(False)

        # Create class to manage code that performs project configuration
        self.load_project = LoadProject()
        self.load_project.project_read(show_warning)

    def save_toolbars_position(self):

        parser = configparser.ConfigParser(comment_prefixes=';',
                                           allow_no_value=True)
        main_folder = os.path.join(os.path.expanduser("~"), self.plugin_name)
        config_folder = main_folder + os.sep + "config" + os.sep
        if not os.path.exists(config_folder):
            os.makedirs(config_folder)
        path = config_folder + 'user.config'
        parser.read(path)

        # Get all QToolBar
        widget_list = self.iface.mainWindow().findChildren(QToolBar)
        x = 0
        own_toolbars = []
        # Get a list with own QToolBars
        for w in widget_list:
            if w.property('gw_name'):
                own_toolbars.append(w)

        # Order list of toolbar in function of X position
        own_toolbars = sorted(own_toolbars, key=lambda k: k.x())
        if len(own_toolbars) == 0:
            return

        sorted_toolbar_ids = [tb.property('gw_name') for tb in own_toolbars]

        # Check if section toolbars_position exists in file
        if 'toolbars_position' not in parser:
            parser = configparser.RawConfigParser()
            parser.add_section('toolbars_position')

        parser['toolbars_position']['toolbars_order'] = ",".join(
            sorted_toolbar_ids)

        with open(path, 'w') as configfile:
            parser.write(configfile)
            configfile.close()

    def unload(self, remove_modules=True):
        """ Removes plugin menu items and icons from QGIS GUI
            :param @remove_modules is True when plugin is disabled or reloaded
        """

        # Remove Giswater dockers
        self.remove_dockers()

        # Save toolbar position after unload plugin
        try:
            self.save_toolbars_position()
        except Exception as e:
            self.controller.log_warning(str(e))

        try:
            # Unlisten notify channel and stop thread
            if global_vars.settings.value('system_variables/use_notify').upper(
            ) == 'TRUE' and hasattr(self, 'notify'):
                list_channels = ['desktop', self.controller.current_user]
                self.notify.stop_listening(list_channels)

            if self.load_project:
                if self.load_project.actions:
                    for action in list(self.load_project.actions.values()):
                        self.iface.removePluginMenu(self.plugin_name, action)
                        self.iface.removeToolBarIcon(action)

            if self.load_project:
                if self.load_project.plugin_toolbars:
                    for plugin_toolbar in list(
                            self.load_project.plugin_toolbars.values()):
                        if plugin_toolbar.enabled:
                            plugin_toolbar.toolbar.setVisible(False)
                            del plugin_toolbar.toolbar

            if remove_modules:
                # Unset main information button (when plugin is disabled or reloaded)
                self.unset_info_button()

                # unload all loaded giswater related modules
                for mod_name, mod in list(sys.modules.items()):
                    if mod and hasattr(mod, '__file__') and mod.__file__:
                        if self.plugin_dir in mod.__file__:
                            del sys.modules[mod_name]

            else:
                self.set_info_button_visible()

        except Exception:
            pass
        finally:
            self.load_project = None

    def remove_dockers(self):
        """ Remove Giswater dockers """

        docker_search = self.iface.mainWindow().findChild(
            QDockWidget, 'dlg_search')
        if docker_search:
            self.iface.removeDockWidget(docker_search)

        docker_info = self.iface.mainWindow().findChild(QDockWidget, 'docker')
        if docker_info:
            self.iface.removeDockWidget(docker_info)

        if self.btn_add_layers:
            dockwidget = self.iface.mainWindow().findChild(
                QDockWidget, 'Layers')
            toolbar = dockwidget.findChildren(QToolBar)[0]
            # TODO improve this, now remove last action
            toolbar.removeAction(toolbar.actions()[len(toolbar.actions()) - 1])
            self.btn_add_layers = None
예제 #26
0
class GeometryShapes:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgisInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        self.canvas = iface.mapCanvas()

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'GeometryShapes_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Geometry Shapes')
        self.toolbar = self.iface.digitizeToolBar()
        self.popupMenu = QMenu()
        self.toolButton = QToolButton()
        self.toolButtonAction = None

        # Setup map tools
        self.tool = None
        self.rectTool = None
        self.ovalTool = None

        self.iface.currentLayerChanged["QgsMapLayer*"].connect(self.toggle)

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('GeometryShapes', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   insert_before=0,
                   checkable=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param insert_before: Action before which the button should be
            added to the toolbar. Defaults to None: append to end
        :type insert_before: QAction

        :param checkable: Flag indicating whether the action should
            be made checkable.
        :type checkable: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if checkable:
            action.setCheckable(True)

        if add_to_toolbar:
            self.toolbar.insertAction(insert_before, action)

        if add_to_menu:
            self.iface.addPluginToVectorMenu(self.menu, action)

        self.actions.append(action)
        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        icon_path = ':/plugins/GeometryShapes/mActionCapturePolygonRectangle.svg'
        self.add_action(icon_path,
                        text=self.tr(u'Draw rectangle geometry'),
                        callback=lambda checked: self.set_tool(checked, 0),
                        enabled_flag=False,
                        add_to_toolbar=False,
                        parent=self.iface.mainWindow())

        icon_path = ':/plugins/GeometryShapes/mActionCapturePolygonCircle.svg'
        self.add_action(icon_path,
                        text=self.tr(u'Draw oval geometry'),
                        callback=lambda checked: self.set_tool(checked, 1),
                        enabled_flag=False,
                        add_to_toolbar=False,
                        parent=self.iface.mainWindow())

        # Assemble popup button
        self.popupMenu.addAction(self.actions[0])
        self.popupMenu.addAction(self.actions[1])
        self.toolButton.setMenu(self.popupMenu)
        self.toolButton.setDefaultAction(self.actions[0])
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolButtonAction = self.toolbar.insertWidget(
            self.toolbar.actions()[4], self.toolButton)

        # Init button state
        self.toggle()

    def set_tool(self, checked, action):
        if not checked:
            self.canvas.unsetMapTool(self.tool)
            self.tool = None
            return

        if action == 0:
            self.tool = RectangleGeometryTool(self.canvas)
        else:
            self.tool = OvalGeometryTool(self.canvas)

        self.toolButton.setDefaultAction(self.actions[action])
        self.tool.setAction(self.actions[action])
        self.canvas.setMapTool(self.tool)

    # Some code here lifted from: https://gitlab.com/lbartoletti/CADDigitize/blob/master/CADDigitize.py
    # and copyright 2016 by Loïc BARTOLETTI
    def toggle(self):
        if version_info[0] >= 3:
            _polygon = QgsWkbTypes.PolygonGeometry
        else:
            _polygon = QGis.Polygon

        layer = self.canvas.currentLayer()
        # Decide whether the plugin button/menu is enabled or disabled
        if layer is None:
            self.actions[0].setEnabled(False)
            self.actions[1].setEnabled(False)
        else:
            try:
                # disconnect, will be reconnected
                layer.editingStarted.disconnect(self.toggle)
            except:
                pass
            try:
                # when it becomes active layer again
                layer.editingStopped.disconnect(self.toggle)
            except:
                pass

            if layer.type() == QgsMapLayer.VectorLayer and layer.geometryType(
            ) == _polygon:
                layer.editingStarted.connect(self.toggle)
                layer.editingStopped.connect(self.toggle)

            if layer.isEditable() and layer.geometryType() == _polygon:
                self.actions[0].setEnabled(True)
                self.actions[1].setEnabled(True)
            else:
                self.actions[0].setEnabled(False)
                self.actions[1].setEnabled(False)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginVectorMenu(self.tr(u'&Geometry Shapes'),
                                              action)
            try:
                action.triggered.disconnect()
            except (TypeError, AttributeError):
                pass

        self.popupMenu.clear()
        self.toolbar.removeAction(self.toolButtonAction)

        layer = self.canvas.currentLayer()
        if layer:
            try:
                layer.editingStarted.disconnect(self.toggle)
            except (TypeError, AttributeError):
                pass
            try:
                layer.editingStopped.disconnect(self.toggle)
            except (TypeError, AttributeError):
                pass
            try:
                self.iface.currentLayerChanged["QgsMapLayer*"].disconnect(
                    self.toggle)
            except (TypeError, AttributeError):
                pass
예제 #27
0
class vfkPlugin(object):
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # 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]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'vfk_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Create the dialog (after translation) and keep reference

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&VFK')
        # TODO: We are going to let the user set this up in a future iteration

        # add plugin icon into plugin toolbar
        self.toolButton = QToolButton()
        self.iface.addToolBarWidget(self.toolButton)

    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('vfk', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: unicode

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)

        self.toolButton.setDefaultAction(action)

        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            pass

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/vfkPluginIcon.png'
        self.add_action(icon_path,
                        text=u'Otevřít prohlížeč VFK',
                        callback=self.run,
                        whats_this=u'VFK Plugin',
                        parent=self.iface.mainWindow())

        self.myDockWidget = MainApp(self.iface)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(u'&VFK', action)
            self.iface.removePluginMenu(self.menu, action)
            self.iface.removeToolBarIcon(action)
            self.iface.unregisterMainWindowAction(action)

        if self.myDockWidget:
            self.myDockWidget.close()
        self.myDockWidget = None

    def run(self):
        """
        Run method that performs all the real work
        """
        # show the dialog
        if self.myDockWidget.isVisible():
            self.myDockWidget.hide()
        else:
            self.myDockWidget.close()
            self.myDockWidget = None
            self.myDockWidget = MainApp(self.iface)
            self.iface.addDockWidget(Qt.TopDockWidgetArea, self.myDockWidget)
            self.myDockWidget.show()
예제 #28
0
class DebugVSPlugin(QObject):
    def __init__(self, iface):
        super().__init__()
        self.iface = iface
        self.ptvsd = None
        try:
            import ptvsd
            self.ptvsd = ptvsd
        except:
            pass
        self.port = 5678
        self.host = 'localhost'
        self.actionsScript = []

        self.toolButton = QToolButton()
        self.toolButton.setMenu(QMenu())
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolBtnAction = self.iface.addToolBarWidget(self.toolButton)

        self.msgBar = iface.messageBar()
        self.pluginName = 'DebugVS'
        self.nameActionEnable = 'Enable Debug for Visual Studio'
        self.action = None
        # Check exist sys.argv - /ptvsd/.../pydevd_process_net_command
        if not hasattr(sys, 'argv'):
            sys.argv = []

    def initGui(self):
        # Action Run
        icon = QIcon(os.path.join(os.path.dirname(__file__), 'code.svg'))
        self.actionEnable = QAction(icon, self.nameActionEnable,
                                    self.iface.mainWindow())
        self.actionEnable.setToolTip(self.nameActionEnable)
        self.actionEnable.triggered.connect(self.enable)
        self.iface.addPluginToMenu(f"&{self.nameActionEnable}",
                                   self.actionEnable)
        # Action Load Script
        title = 'Load script'
        icon = QgsApplication.getThemeIcon('mActionScriptOpen.svg')
        self.actionLoad = QAction(icon, title, self.iface.mainWindow())
        self.actionLoad.setToolTip(title)
        self.actionLoad.triggered.connect(self.load)
        self.iface.addPluginToMenu(f"&{self.nameActionEnable}",
                                   self.actionLoad)
        #
        m = self.toolButton.menu()
        m.addAction(self.actionEnable)
        m.addAction(self.actionLoad)
        self.toolButton.setDefaultAction(self.actionEnable)

    def unload(self):
        for action in [self.actionEnable, self.actionLoad
                       ] + self.actionsScript:
            self.iface.removePluginMenu(f"&{self.nameActionEnable}", action)
            self.iface.removeToolBarIcon(action)
            self.iface.unregisterMainWindowAction(action)

        self.iface.removeToolBarIcon(self.toolBtnAction)

    def _addActionScript(self, filename):
        icon = QgsApplication.getThemeIcon('processingScript.svg')
        title = os.path.split(filename)[-1]
        action = QAction(icon, title, self.iface.mainWindow())
        action.setToolTip(filename)
        action.triggered.connect(self.run)
        m = self.toolButton.menu()
        m.addAction(action)

        self.actionsScript.append(action)

    def _existsActionScript(self, filename):
        filenames = [a.toolTip() for a in self.actionsScript]
        return filename in filenames

    def _checkEnable(self):
        if not self.ptvsd.is_attached():
            self.msgBar.popWidget()
            msg = f"{self.nameActionEnable} AND attach in Visual Studio Code"
            self.msgBar.pushWarning(self.pluginName, msg)
            return False
        return True

    @pyqtSlot(bool)
    def enable(self, checked):
        self.msgBar.popWidget()
        if self.ptvsd is None:
            self.msgBar.pushCritical(self.pluginName,
                                     "Need install ptvsd: pip3 install ptvsd")
            return
        msgPort = f'"request": "attach", "Port": {self.port}, "host": "{self.host}"'
        if self.ptvsd.is_attached():
            self.msgBar.pushWarning(
                self.pluginName,
                f"Remote Debug for Visual Studio is active({msgPort})")
            return
        t_, self.port = self.ptvsd.enable_attach(address=(self.host,
                                                          self.port))
        msgPort = f'"request": "attach", "Port": {self.port}, "host": "{self.host}"'
        self.msgBar.pushInfo(
            self.pluginName,
            f"Remote Debug for Visual Studio is running({msgPort})")

    @pyqtSlot(bool)
    def load(self, checked):
        if not self._checkEnable():
            return

        filename, _ = QFileDialog.getOpenFileName(None, 'Debug script', '',
                                                  'Python Files (*.py)')
        if not filename:
            return

        self.ptvsd.wait_for_attach()
        execfile_(filename)

        if not self._existsActionScript(filename):
            self._addActionScript(filename)

    @pyqtSlot(bool)
    def run(self, checked):
        if not self._checkEnable():
            return

        action = self.sender()
        filename = action.toolTip()

        self.ptvsd.wait_for_attach()
        execfile_(filename)
class WtyczkaAPP(AppModule, MetadataModule, ValidatorModule, SettingsModule):
    """QGIS Plugin Implementation."""

    def __init__(self, iface):

        # wczytanie modułów
        AppModule.__init__(self, iface)
        MetadataModule.__init__(self, iface)
        ValidatorModule.__init__(self, iface)
        SettingsModule.__init__(self, iface)

        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # zamykane okna do czyszczenia
        self.closableWindows = []
        for dialogObject in vars(self).values():
            if isinstance(dialogObject, CloseMessageDialog):
                self.closableWindows.append(dialogObject)
        for dialogObject in self.closableWindows:
            dialogObject.closed.connect(self.clearFormsOnClose)

        # Declare instance attributes
        self.actions = []

        self.listaPlikow = []
        # for el in utils.all_layout_widgets(self.wektorFormularzDialog.layout()):
        #     print(el.objectName())

        # definicja walidatora
        self.dataValidator = None


        # inicjacja walidatorów
        self.prepareXsdForApp()
        self.prepareXsdForMetadata()

    def clearFormsOnClose(self):
        """czyści formularze przy zamknięciu"""
        for dialogObject in self.closableWindows:
            # czyszczenie formularzy danych (APP)
            try:
                dialogObject.clearForm(dialogObject.form_scrollArea)
                dialogObject.setDefaultValues()
            except AttributeError:
                pass
            # # czyszczenie formularza metadanych
            # try:
            #     dialogObject.clearForm_btn_clicked()
            # except AttributeError:
            #     pass

    def createValidator(self, task):
        QgsMessageLog.logMessage('walidator start')
        self.dataValidator = validator.ValidatorLxml()
        QgsMessageLog.logMessage('walidator gotowy')

    def createMetadataValidator(self, task):
        QgsMessageLog.logMessage('walidator start')
        self.metadataValidator = validator.ValidatorLxml(schema_path=os.path.join(os.path.dirname(__file__), 'modules/validator', 'metadane.xsd'))
        QgsMessageLog.logMessage('walidator gotowy')


    def prepareXsdForApp(self):
        task = QgsTask.fromFunction('Wczytywanie schematu XSD dla APP', self.createValidator)
        if task.description() not in [task.description() for task in QgsApplication.taskManager().activeTasks()]:
            QgsApplication.taskManager().addTask(task)
            QgsMessageLog.logMessage('starting XSD reading task')

    def prepareXsdForMetadata(self):
        task = QgsTask.fromFunction('Wczytywanie schematu XSD dla metadanych', self.createMetadataValidator)
        if task.description() not in [task.description() for task in QgsApplication.taskManager().activeTasks()]:
            QgsApplication.taskManager().addTask(task)
            QgsMessageLog.logMessage('starting XSD reading task')
        # print('status1', task.status())
        # QgsApplication.taskManager().activeTasks()


    def addAction(self, icon_path, text, callback):
        m = self.toolButton.menu()
        action = QAction(
            icon=QIcon(icon_path),
            text=text,
            parent=self.iface.mainWindow()
        )
        action.triggered.connect(callback)
        self.actions.append(action)
        m.addAction(action)
        self.iface.addPluginToMenu(u'&' + PLUGIN_NAME, action)
        return action


    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        self.toolButton = QToolButton()
        self.toolButton.setDefaultAction(QAction(
            icon=QIcon(':/plugins/wtyczka_app/img/logo.png'),
            text=u'&' + PLUGIN_NAME,
            parent=self.iface.mainWindow()
        ))
        self.toolButton.clicked.connect(self.run_app)

        self.toolButton.setMenu(QMenu())
        self.toolButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.toolBtnAction = self.iface.addToolBarWidget(self.toolButton)

        self.addAction(icon_path=':/plugins/wtyczka_app/img/praca_z_app.png',
                       text=u'Praca z APP / zbiorem APP',
                       callback=self.run_app)

        self.addAction(icon_path=':/plugins/wtyczka_app/img/tworzenie.png',
                       text=u'Tworzenie / aktualizacja metadanych',
                       callback=self.run_metadata)

        self.addAction(icon_path=':/plugins/wtyczka_app/img/walidacja.png',
                       text=u'Walidacja GML / XML',
                       callback=self.run_validator)

        self.addAction(icon_path=':/plugins/wtyczka_app/img/ustawienia.png',
                       text=u'Ustawienia',
                       callback=self.run_settings)
        self.addAction(icon_path=':/plugins/wtyczka_app/img/info2.png',
                       text=u'Pomoc',
                       callback=self.run_help)



    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(u'&' + PLUGIN_NAME, action)
            self.iface.removeToolBarIcon(action)

        self.iface.removeToolBarIcon(self.toolBtnAction)

    """Action handlers"""
    # region action handlers
    def run_app(self):
        self.openNewDialog(self.pytanieAppDialog)

    def run_metadata(self):
        self.openNewDialog(self.metadaneDialog)
        self.metadaneDialog.prev_btn.setEnabled(False)

    def run_settings(self):
        self.openNewDialog(self.ustawieniaDialog)

    def run_help(self):
        self.openNewDialog(self.pomocDialog)

    def run_validator(self):
        self.openNewDialog(self.walidacjaDialog)
    # endregion