class ProcessingDirnoProviderPlugin:

    def __init__(self, iface):
        self.provider = DirnoAlgorithmProvider()
        self.iface = iface

    def initGui(self):
        Processing.addProvider(self.provider)
        self.profilAction = QAction(QIcon(os.path.dirname(__file__) + "/icons/iconProvider.png"), "Ajouter un profil", self.iface.mainWindow())
        self.profilAction.setObjectName("dirnoAction")
        self.profilAction.setWhatsThis("Dirno plugin")
        self.profilAction.setStatusTip("This is status tip")
        #QObject.connect(self.profilAction, SIGNAL("triggered()"), self.run)

        # add toolbar button and menu item
        #self.iface.addToolBarIcon(self.profilAction)
        self.iface.addPluginToMenu("&Dirno scripts", self.profilAction)
        self.profilAction.triggered.connect(self.launchDirnoAlgorithProfilDialog)

    def unload(self):
        Processing.removeProvider(self.provider)
        self.iface.removePluginMenu("&Dirno scripts", self.profilAction)
        #self.iface.removeToolBarIcon(self.profilAction)

    def launchDirnoAlgorithProfilDialog(self):
        return DirnoAlgorithmProfilDialog()
Example #2
0
class MapSwipePlugin:
    def __init__(self, iface):
        def translate():
            #
            # For create file 'qm'
            # 1) Define that files need for translation: mapswipetool.pro
            # 2) Create 'ts': pylupdate4 -verbose mapswipetool.pro
            # 3) Edit your translation: QtLinquist
            # 4) Create 'qm': lrelease *.ts
            #
            dirname = os.path.dirname(os.path.abspath(__file__))
            locale = QSettings().value("locale/userLocale")
            localePath = os.path.join(dirname, "i18n",
                                      "%s_%s.qm" % (name_src, locale))
            if os.path.exists(localePath):
                self.translator = QTranslator()
                self.translator.load(localePath)
                if qVersion() > '4.3.3':
                    QCoreApplication.installTranslator(self.translator)

        self.iface = iface
        self.canvas = iface.mapCanvas()
        self.action = None  # Define by initGui
        self.tool = MapSwipeTool(self.iface)
        self.prevTool = None  # Define by run

        name_src = "mapswipetool"
        translate()

    def initGui(self):
        title = "Map swipe tool"
        icon = QIcon(
            os.path.join(os.path.dirname(__file__), 'mapswipetool.png'))
        self.action = QAction(icon, title, self.iface.mainWindow())
        self.action.setObjectName("MapSwipeTool")
        self.action.setWhatsThis(title)
        self.action.setStatusTip(title)
        self.action.triggered.connect(self.run)
        self.menu = "&Map swipe tool"

        # Maptool
        self.action.setCheckable(True)
        self.tool.setAction(self.action)

        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(self.menu, self.action)

    def unload(self):
        self.canvas.unsetMapTool(self.tool)
        self.iface.removeToolBarIcon(self.action)
        self.iface.removePluginMenu(self.menu, self.action)
        del self.action

    @pyqtSlot()
    def run(self):
        if self.canvas.mapTool() != self.tool:
            self.prevTool = self.canvas.mapTool()
            self.canvas.setMapTool(self.tool)
        else:
            self.canvas.setMapTool(self.prevTool)
Example #3
0
 def addAction(self, action, checked=None, autoBuild=True):
     """
     Adds the inputed action to this widget's action group.  This will auto-\
     create a new group if no group is already defined.
     
     :param      action | <QAction> || <str>
     
     :return     <QAction>
     """
     # clear the holder
     actions = self._actionGroup.actions()
     if actions and actions[0].objectName() == 'place_holder':
         self._actionGroup.removeAction(actions[0])
         actions[0].deleteLater()
     
     # create an action from the name
     if not isinstance(action, QAction):
         action_name = str(action)
         action = QAction(action_name, self)
         action.setObjectName(action_name)
         action.setCheckable(self.isCheckable())
         
         # auto-check the first option
         if checked or (not self._actionGroup.actions() and checked is None):
             action.setChecked(True)
     
     self._actionGroup.addAction(action)
     
     if autoBuild:
         self.rebuild()
     
     return action
Example #4
0
class MapSwipePlugin:

  def __init__(self, iface):
    
    def translate():
      #
      # For create file 'qm'
      # 1) Define that files need for translation: mapswipetool.pro
      # 2) Create 'ts': pylupdate4 -verbose mapswipetool.pro
      # 3) Edit your translation: QtLinquist
      # 4) Create 'qm': lrelease *.ts 
      #
      dirname = os.path.dirname( os.path.abspath(__file__) )
      locale = QSettings().value("locale/userLocale")
      localePath = os.path.join( dirname, "i18n", "%s_%s.qm" % ( name_src, locale ) )
      if os.path.exists(localePath):
        self.translator = QTranslator()
        self.translator.load(localePath)
        if qVersion() > '4.3.3':
          QCoreApplication.installTranslator(self.translator)      

    self.iface = iface
    self.canvas = iface.mapCanvas() 
    self.action = None # Define by initGui
    self.tool = MapSwipeTool( self.iface )
    self.prevTool = None # Define by run

    name_src = "mapswipetool"
    translate()

  def initGui(self):
    title = "Map swipe tool"
    icon = QIcon( os.path.join( os.path.dirname(__file__), 'mapswipetool.png' ) )
    self.action = QAction( icon, title, self.iface.mainWindow() )
    self.action.setObjectName( "MapSwipeTool" )
    self.action.setWhatsThis( title )
    self.action.setStatusTip( title )
    self.action.triggered.connect( self.run )
    self.menu = "&Map swipe tool"

    # Maptool
    self.action.setCheckable( True )
    self.tool.setAction( self.action )

    self.iface.addToolBarIcon( self.action )
    self.iface.addPluginToMenu( self.menu, self.action )

  def unload(self):
    self.canvas.unsetMapTool( self.tool )
    self.iface.removeToolBarIcon( self.action )
    self.iface.removePluginMenu( self.menu, self.action )
    del self.action

  @pyqtSlot()
  def run(self):
    if self.canvas.mapTool() != self.tool:
      self.prevTool = self.canvas.mapTool()
      self.canvas.setMapTool( self.tool )
    else:
      self.canvas.setMapTool( self.prevTool )
Example #5
0
class Interpreter(MDockWidget):
    def __init__(self, mainWindow=None):
        MDockWidget.__init__(self, mainWindow)
        self.__mainWindow = mainWindow
        self.icon = QIcon(":interpreter.png")
        self.addAction(mainWindow)
        self.g_display()
        
    def g_display(self):
        self.setWidget(InterpreterView(self))
        self.setWindowTitle(QApplication.translate("Interpreter", "Interpreter", None, QApplication.UnicodeUTF8))
        
    def addAction(self, mainWindow):
        self.__action = QAction(self)
        self.__action.setCheckable(True)
        self.__action.setChecked(True)
        self.__action.setObjectName("actionCoreInformations")
        self.__action.setText(QApplication.translate("MainWindow", "DFF interpreter", None, QApplication.UnicodeUTF8))
        mainWindow.menuWindow.addAction(self.__action)
        self.connect(self.__action,  SIGNAL("triggered()"),  self.changeVisibleInformations)
    
    def changeVisibleInformations(self):
        if not self.isVisible() :
            self.setVisible(True)
            self.__action.setChecked(True)
        else :
            self.setVisible(False)
            self.__action.setChecked(False)
class ToggleActiveLayerPlugin:

  def __init__(self, iface):
    self.iface = iface
    self.canvas = iface.mapCanvas() 

    self.action = None
    self.tool = ToggleActiveLayerMapTool( self.iface )

  def initGui(self):
    title = "Toggle visibility of active layer"
    icon = QIcon( os.path.join( os.path.dirname(__file__), 'toggleactivelayer.png' ) )
    self.action = QAction( icon, title, self.iface.mainWindow() )
    self.action.setObjectName( "ToggleActiveLayerPlugin" )
    self.action.setWhatsThis( title )
    self.action.setStatusTip( title )
    self.action.triggered.connect( self.run )

    # Maptool
    self.action.setCheckable( True )
    self.tool.setAction( self.action )

    self.iface.addToolBarIcon( self.action )

  def unload(self):
    self.canvas.unsetMapTool( self.tool )
    self.iface.removeToolBarIcon( self.action )
    del self.action

  @pyqtSlot()
  def run(self):
    if self.canvas.mapTool() != self.tool:
      self.canvas.setMapTool( self.tool)
Example #7
0
    def createCaptureButtons(self, form, wasselected):
        tool = form.getMaptool()(self.canvas)
        action = QAction(QIcon(":/icons/capture"), "Capture", None)
        action.setObjectName("capture")
        action.setCheckable(True)
        action.toggled.connect(partial(self.setMapTool, tool))

        if isinstance(tool, PointTool):
            add = partial(self.addNewFeature, form)
            tool.geometryComplete.connect(add)
        else:
            tool.finished.connect(self.openForm)
            tool.error.connect(partial(self.showToolError, form.label))

        # Set the action as a data entry button so we can remove it later.
        action.setProperty("dataentry", True)

        self.actionGPSFeature.setVisible(not tool.isEditTool())

        self.projecttoolbar.insertAction(self.topspaceraction, action)
        self.projecttoolbar.insertAction(self.topspaceraction, self.actionGPSFeature)
        self.editgroup.addAction(action)
        self.layerbuttons.append(action)

        action.setChecked(wasselected)
Example #8
0
class DBManagerPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.dlg = None

    def initGui(self):
        self.action = QAction(
            QIcon(":/db_manager/icon"),
            QApplication.translate("DBManagerPlugin", "DB Manager"),
            self.iface.mainWindow())
        self.action.setObjectName("dbManager")
        QObject.connect(self.action, SIGNAL("triggered()"), self.run)
        # Add toolbar button and menu item
        if hasattr(self.iface, 'addDatabaseToolBarIcon'):
            self.iface.addDatabaseToolBarIcon(self.action)
        else:
            self.iface.addToolBarIcon(self.action)
        if hasattr(self.iface, 'addPluginToDatabaseMenu'):
            self.iface.addPluginToDatabaseMenu(
                QApplication.translate("DBManagerPlugin", "DB Manager"),
                self.action)
        else:
            self.iface.addPluginToMenu(
                QApplication.translate("DBManagerPlugin", "DB Manager"),
                self.action)

    def unload(self):
        # Remove the plugin menu item and icon
        if hasattr(self.iface, 'removePluginDatabaseMenu'):
            self.iface.removePluginDatabaseMenu(
                QApplication.translate("DBManagerPlugin", "DB Manager"),
                self.action)
        else:
            self.iface.removePluginMenu(
                QApplication.translate("DBManagerPlugin", "DB Manager"),
                self.action)
        if hasattr(self.iface, 'removeDatabaseToolBarIcon'):
            self.iface.removeDatabaseToolBarIcon(self.action)
        else:
            self.iface.removeToolBarIcon(self.action)

        if self.dlg is not None:
            self.dlg.close()

    def run(self):
        # keep opened only one instance
        if self.dlg is None:
            from db_manager import DBManager
            self.dlg = DBManager(self.iface)
            QObject.connect(self.dlg, SIGNAL("destroyed(QObject *)"),
                            self.onDestroyed)
        self.dlg.show()
        self.dlg.raise_()
        self.dlg.setWindowState(self.dlg.windowState() & ~Qt.WindowMinimized)
        self.dlg.activateWindow()

    def onDestroyed(self, obj):
        self.dlg = None
Example #9
0
    def getActions(self):
        """ @rtype: list of QAction """
        advanced_toggle_action = QAction("Show Advanced Options", self)
        advanced_toggle_action.setObjectName("AdvancedSimulationOptions")
        advanced_toggle_action.setCheckable(True)
        advanced_toggle_action.setChecked(False)
        advanced_toggle_action.toggled.connect(self.toggleAdvanced)

        return [advanced_toggle_action]
Example #10
0
    def cancelform(self, *args):
        dlg = PickActionDialog(msg="Discard form changes?")
        self.expandAction = QAction(QIcon(":/icons/expand"), "Expand Panel",
                                    self)
        discardaction = QAction("Discard", self, triggered=self._cancel_form)
        discardaction.setObjectName("discard")
        noaction = QAction("No", self)

        dlg.addactions([noaction, discardaction])
        dlg.exec_()
def applyButtons(profile):
    if profile.buttons is None:
        return

    for toolbar in customToolbarsWidgets[::-1]:
        toolbar.setVisible(False)
        iface.mainWindow().removeToolBar(toolbar)
        del toolbar

    del customToolbarsWidgets[:]

    currentToolbars = [el for el in iface.mainWindow().children()
                if isinstance(el, QToolBar)]

    customToolbars = defaultdict(list)
    toolbars = profile.buttons
    for toolbar in currentToolbars:
        if toolbar.objectName() in toolbars:
            hasVisibleActions = False
            actions = toolbar.actions()
            for i, action in enumerate(actions):
                objectName = action.objectName() or str(i)
                if objectName in toolbars[toolbar.objectName()]:
                    location = toolbars[toolbar.objectName()][objectName]
                    if location is not None:
                        newAction = QAction(action.icon(), action.text(), iface.mainWindow())
                        newAction.triggered.connect(action.trigger)
                        objectName = "%s_%i" % (location, len(customToolbars[location]))
                        newAction.setObjectName(objectName)
                        customToolbars[location].append(newAction)
                        action.setVisible(False)
                    else:
                        hasVisibleActions = True
                        action.setVisible(True)
                else:
                    if toolbars[toolbar.objectName()]:
                        action.setVisible(False)
                    else: #If toolbar definition is empty, means all buttons should be added
                        hasVisibleActions = True
                        action.setVisible(True)
                if isinstance(action, QWidgetAction) and not isinstance(action.defaultWidget(), QToolButton) and action.defaultWidget() is not None:
                    action.defaultWidget().setMinimumWidth(300)
                    #action.defaultWidget().setMaximumWidth(400)

            toolbar.setVisible(hasVisibleActions)

        else:
            toolbar.setVisible(False)

    for name, actions in customToolbars.iteritems():
        toolbar = iface.mainWindow().addToolBar(name)
        toolbar.setObjectName("toolbar_%s" % name)
        customToolbarsWidgets.append(toolbar)
        for action in actions:
            toolbar.addAction(action)
Example #12
0
class QGISTester:

  def __init__(self, iface):
    # Save reference to the QGIS interface
    self.iface = iface
    # initialize plugin directory
    self.plugin_dir = os.path.dirname(QFile.decodeName(__file__))
    # initialize locale
    locale = QSettings().value('locale/userLocale')[0:2]
    locale_path = os.path.join(self.plugin_dir, 'i18n', 'QGISTester_{}.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.menu = self.tr("&QGIS Tester")

  def tr(self, message):
    """Get the translation for a string using Qt translation API."""
    return QCoreApplication.translate('QGISTester', message)

  def initGui(self):
    # Create action that will start plugin configuration
    icon_path = os.path.join(self.plugin_dir, "icon.png")
    self.action = QAction(QIcon(icon_path), self.tr("Test your QGIS!"), self.iface.mainWindow())
    self.action.setObjectName("QGISTester_Test")

    # Connect the action to the run method
    self.action.triggered.connect(self.run)

    # Add toolbar button and menu item
    self.iface.addPluginToMenu(self.menu, self.action)
    if debug_mode:
      self.iface.addToolBarIcon(self.action)

  def unload(self):
    """Remove the plugin menu item and icon"""
    self.iface.removePluginMenu(self.menu, self.action)
    if debug_mode:
      self.iface.removeToolBarIcon(self.action)

  def run(self):
    # Import the code for the dialog
    from qgis_tester_dialog import QGISTesterDialog

    # Create the dialog
    dlg = QGISTesterDialog()
    # show the dialog
    dlg.show()
    # Run the dialog event loop
    dlg.exec_()
Example #13
0
class CatalogPLPlugin:

    icon = QIcon(os.path.join(os.path.dirname(__file__), 'catalogpl.png'))
    pluginName = "Catalog Planet Labs"

    def __init__(self, iface):

        self.iface = iface
        self.name = u"&Catalog Planet Labs"
        self.msgBar = iface.messageBar()
        self.action = None
        self.ctl = CatalogPL(self.iface, CatalogPLPlugin.icon)

        CatalogPL.copyExpression()

    def initGui(self):
        msgtrans = "Catalog Planet Labs"
        self.action = QAction(CatalogPLPlugin.icon, msgtrans,
                              self.iface.mainWindow())
        self.action.setObjectName("CatalogPL")
        self.action.setWhatsThis(msgtrans)
        self.action.setStatusTip(msgtrans)
        self.action.triggered.connect(self.run)
        self.ctl.enableRun.connect(self.action.setEnabled)

        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToRasterMenu(self.name, self.action)

    def unload(self):
        self.iface.removePluginMenu(self.name, self.action)
        self.iface.removeToolBarIcon(self.action)
        del self.action
        del self.ctl

    @pyqtSlot()
    def run(self):

        if self.iface.mapCanvas().layerCount() == 0:
            msg = "Need layer(s) in map"
            self.iface.messageBar().pushMessage(CatalogPLPlugin.pluginName,
                                                msg, QgsMessageBar.WARNING, 2)
            return

        if not self.ctl.isHostLive:
            self.ctl.hostLive()
            if not self.ctl.isHostLive:
                return

        if not self.ctl.hasRegisterKey:
            self.ctl.registerKey()
            if not self.ctl.hasRegisterKey:
                return

        self.ctl.downloadScenes()
Example #14
0
    def __createMenu(self):
        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction("Close", self.__quit)
        self.__view_menu = self.menuBar().addMenu("&View")

        """ @rtype: list of QAction """
        advanced_toggle_action = QAction("Show Advanced Options", self)
        advanced_toggle_action.setObjectName("AdvancedSimulationOptions")
        advanced_toggle_action.setCheckable(True)
        advanced_toggle_action.setChecked(False)
        advanced_toggle_action.toggled.connect(self.toggleAdvancedMode)

        self.__view_menu.addAction(advanced_toggle_action)
Example #15
0
    def clear(self, autoBuild=True):
        """
        Clears the actions for this widget.
        """
        for action in self._actionGroup.actions():
            self._actionGroup.removeAction(action)
        
        action = QAction('', self)
        action.setObjectName('place_holder')
#        self._currentAction = None
        self._actionGroup.addAction(action)
        if autoBuild:
            self.rebuild()
Example #16
0
class DBManagerPlugin:

    def __init__(self, iface):
        self.iface = iface
        self.dlg = None

    def initGui(self):
        self.action = QAction(QIcon(":/db_manager/icon"), QApplication.translate("DBManagerPlugin", "DB Manager"),
                              self.iface.mainWindow())
        self.action.setObjectName("dbManager")
        QObject.connect(self.action, SIGNAL("triggered()"), self.run)
        # Add toolbar button and menu item
        if hasattr(self.iface, 'addDatabaseToolBarIcon'):
            self.iface.addDatabaseToolBarIcon(self.action)
        else:
            self.iface.addToolBarIcon(self.action)
        if hasattr(self.iface, 'addPluginToDatabaseMenu'):
            self.iface.addPluginToDatabaseMenu(QApplication.translate("DBManagerPlugin", "DB Manager"), self.action)
        else:
            self.iface.addPluginToMenu(QApplication.translate("DBManagerPlugin", "DB Manager"), self.action)

    def unload(self):
        # Remove the plugin menu item and icon
        if hasattr(self.iface, 'removePluginDatabaseMenu'):
            self.iface.removePluginDatabaseMenu(QApplication.translate("DBManagerPlugin", "DB Manager"), self.action)
        else:
            self.iface.removePluginMenu(QApplication.translate("DBManagerPlugin", "DB Manager"), self.action)
        if hasattr(self.iface, 'removeDatabaseToolBarIcon'):
            self.iface.removeDatabaseToolBarIcon(self.action)
        else:
            self.iface.removeToolBarIcon(self.action)

        if self.dlg is not None:
            self.dlg.close()

    def run(self):
        # keep opened only one instance
        if self.dlg is None:
            from db_manager import DBManager

            self.dlg = DBManager(self.iface)
            QObject.connect(self.dlg, SIGNAL("destroyed(QObject *)"), self.onDestroyed)
        self.dlg.show()
        self.dlg.raise_()
        self.dlg.setWindowState(self.dlg.windowState() & ~Qt.WindowMinimized)
        self.dlg.activateWindow()

    def onDestroyed(self, obj):
        self.dlg = None
Example #17
0
class RasterLegendSensitivePlugin:
    def __init__(self, iface):

        self.iface = iface
        self.name = u"Raster legend &sensitive"
        self.dock = None

    def initGui(self):
        msg = "Raster legend sensitive"
        icon = QIcon(
            os.path.join(os.path.dirname(__file__),
                         'rasterlegendsensitive.svg'))
        self.action = QAction(icon, msg, self.iface.mainWindow())
        self.action.setObjectName("RasterLegendSensitive")
        self.action.setWhatsThis(msg)
        self.action.setStatusTip(msg)
        self.action.setCheckable(True)
        self.action.triggered.connect(self.run)

        self.iface.addRasterToolBarIcon(self.action)
        self.iface.addPluginToRasterMenu(self.name, self.action)

        self.dock = DockWidgetRasterLegendSensitive(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
        self.dock.visibilityChanged.connect(self.dockVisibilityChanged)

    def unload(self):
        self.iface.removeRasterToolBarIcon(self.action)
        self.iface.removePluginRasterMenu(self.name, self.action)

        self.dock.close()
        del self.dock
        self.dock = None

        del self.action

    @pyqtSlot()
    def run(self):
        if self.dock.isVisible():
            self.dock.hide()
        else:
            self.dock.show()

    @pyqtSlot(bool)
    def dockVisibilityChanged(self, visible):
        self.action.setChecked(visible)
        self.dock.visibility(visible)
Example #18
0
class GetFeatureSelected:
    def __init__(self, iface):

        self.iface = iface

    def initGui(self):

        # cria uma ação que iniciará a configuração do plugin
        path = self.iface.mainWindow()
        icon_path = ':/plugins/GetFeatureSelected/i.png'
        self.action = QAction(
            QIcon(icon_path),
            u"Pega as Feições de uma camada selecionada e envia seu(s)s id(s) no campo filtro",
            path)
        self.action.setObjectName("Get Feature Selected")
        self.action.setStatusTip(None)
        self.action.setWhatsThis(None)
        QObject.connect(self.action, SIGNAL("triggered()"),
                        self.GetFeatureSelected)
        # Adicionar o botão icone
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        # remove o item de ícone do QGIS GUI.
        self.iface.removeToolBarIcon(self.action)

    def GetFeatureSelected(self):

        canvas = self.iface.mapCanvas()
        layer = canvas.currentLayer()

        if layer:

            count = layer.selectedFeatureCount()

            selectedId = layer.selectedFeaturesIds()
            print selectedId
            expressao = '('
            for l in selectedId:

                expressao = expressao + str(l) + ','

            expressao = expressao[:-1]
            expressao = expressao + ')'
            layer.setSubsetString('"id" IN %s' % expressao)
            print layer.setSubsetString('"id" IN %s' % expressao)
class GeoJSONExportPlugin:
    """QGIS Plugin that export geojson into a remote place"""

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

    def initGui(self):
        """Initialize the GUI of the plugin"""
        self.action = QAction(
            QIcon(":/plugins/GeoJSONExportPlugin/img/icon.png"),
            "GeoJSON Export Plugin", self.iface.mainWindow())
        self.action.setObjectName("testAction")
        self.action.setWhatsThis("Configuration for test plugin")
        self.action.setStatusTip("This is status tip")
        QObject.connect(self.action, SIGNAL("triggered()"), self.run)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        """Unload the plugin"""
        self.iface.removeToolBarIcon(self.action)

    def get_vector_layers(self):
        """Returns all the opened vector layers"""
        layers = self.iface.legendInterface().layers()
        vector_layers = []

        for layer in layers:
            print layer.id()
            layerType = layer.type()
            if layerType == qgis.core.QgsMapLayer.VectorLayer:
                vector_layers.append(layer)
        return vector_layers

    def run(self):
        """Runs the plugin when the user activate it"""
        project_filename = qgis.core.QgsProject.instance().fileName()
        print '-'
        print project_filename
        if not project_filename:
            project_filename = u'Undefined'
        project_filename = project_filename.encode('utf-8')
        vector_layers = self.get_vector_layers()
        dlg = GeoJSONExportPluginDialog(project_filename, vector_layers)
        dlg.exec_()
Example #20
0
class GeoJSONExportPlugin:
    """QGIS Plugin that export geojson into a remote place"""
    def __init__(self, iface):
        """Initialization of the plugin"""
        # save reference to the QGIS interface
        self.iface = iface

    def initGui(self):
        """Initialize the GUI of the plugin"""
        self.action = QAction(
            QIcon(":/plugins/GeoJSONExportPlugin/img/icon.png"),
            "GeoJSON Export Plugin", self.iface.mainWindow())
        self.action.setObjectName("testAction")
        self.action.setWhatsThis("Configuration for test plugin")
        self.action.setStatusTip("This is status tip")
        QObject.connect(self.action, SIGNAL("triggered()"), self.run)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        """Unload the plugin"""
        self.iface.removeToolBarIcon(self.action)

    def get_vector_layers(self):
        """Returns all the opened vector layers"""
        layers = self.iface.legendInterface().layers()
        vector_layers = []

        for layer in layers:
            print layer.id()
            layerType = layer.type()
            if layerType == qgis.core.QgsMapLayer.VectorLayer:
                vector_layers.append(layer)
        return vector_layers

    def run(self):
        """Runs the plugin when the user activate it"""
        project_filename = qgis.core.QgsProject.instance().fileName()
        print '-'
        print project_filename
        if not project_filename:
            project_filename = u'Undefined'
        project_filename = project_filename.encode('utf-8')
        vector_layers = self.get_vector_layers()
        dlg = GeoJSONExportPluginDialog(project_filename, vector_layers)
        dlg.exec_()
Example #21
0
    def __createMenu(self):
        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction("Close", self.__quit)
        self.__view_menu = self.menuBar().addMenu("&View")
        self.__help_menu = self.menuBar().addMenu("&Help")
        """:type: QMenu"""
        """ @rtype: list of QAction """
        advanced_toggle_action = QAction("Show Advanced Options", self)
        advanced_toggle_action.setObjectName("AdvancedSimulationOptions")
        advanced_toggle_action.setCheckable(True)
        advanced_toggle_action.setChecked(False)
        advanced_toggle_action.toggled.connect(self.toggleAdvancedMode)

        self.__view_menu.addAction(advanced_toggle_action)
        """ @rtype: list of QAction """
        show_about = self.__help_menu.addAction("About")
        show_about.setMenuRole(QAction.ApplicationSpecificRole)
        show_about.triggered.connect(self.__showAboutMessage)
Example #22
0
class AuxiliaryWindowPlugin:
    def __init__(self, iface):
        self.iface = iface
        self.plugin = ContainerAuxiliaryWindow(iface.mainWindow())
        self.namePlugin = "&Auxiliary Window"

    def _connect(self, isConnect=True):
        signal_slot = ({
            'signal': QgsProject.instance().readProject,
            'slot': self.plugin.onReadProject
        }, {
            'signal': QgsProject.instance().writeProject,
            'slot': self.plugin.onWriteProject
        })
        if isConnect:
            for item in signal_slot:
                item['signal'].connect(item['slot'])
        else:
            for item in signal_slot:
                item['signal'].disconnect(item['slot'])

    def initGui(self):
        title = "Auxiliary window"
        icon = QIcon(
            os.path.join(os.path.dirname(__file__), 'auxiliarywindow.png'))
        self.action = QAction(icon, title, self.iface.mainWindow())
        self.action.setObjectName("AuxiliaryWindow")
        self.action.setWhatsThis(title)
        self.action.setStatusTip(title)
        self.action.triggered.connect(self.run)
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(self.namePlugin, self.action)
        self._connect()

    def unload(self):
        self.iface.removeToolBarIcon(self.action)
        self.iface.removePluginMenu(self.namePlugin, self.action)
        del self.action
        self._connect(False)
        self.plugin.close()

    @pyqtSlot()
    def run(self):
        self.plugin.run()
Example #23
0
    def __createMenu(self):
        file_menu = self.menuBar().addMenu("&File")
        file_menu.addAction("Close", self.__quit)
        self.__view_menu = self.menuBar().addMenu("&View")
        self.__help_menu = self.menuBar().addMenu("&Help")
        """:type: QMenu"""

        """ @rtype: list of QAction """
        advanced_toggle_action = QAction("Show Advanced Options", self)
        advanced_toggle_action.setObjectName("AdvancedSimulationOptions")
        advanced_toggle_action.setCheckable(True)
        advanced_toggle_action.setChecked(False)
        advanced_toggle_action.toggled.connect(self.toggleAdvancedMode)

        self.__view_menu.addAction(advanced_toggle_action)

        """ @rtype: list of QAction """
        show_about = self.__help_menu.addAction("About")
        show_about.setMenuRole(QAction.ApplicationSpecificRole)
        show_about.triggered.connect(self.__showAboutMessage)
Example #24
0
def action(name, parent=None, collection=None):
    """Returns a QAction with text and icon for the given snippet name.

    Returns None is no such snippet is available.
    If collection is provided, it is used to set shortcuts to the action.
    """
    title = snippets.title(name)
    if not title:
        return
    a = QAction(parent)
    a.setObjectName(name)
    a.setText(title.replace('&', '&&'))
    icon = snippets.icon(name)
    if icon:
        a.setIcon(icon)
    if collection:
        shortcuts = collection.shortcuts(name)
        if shortcuts:
            a.setShortcuts(shortcuts)
    return a
Example #25
0
def action(name, parent=None, collection=None):
    """Returns a QAction with text and icon for the given snippet name.

    Returns None is no such snippet is available.
    If collection is provided, it is used to set shortcuts to the action.
    """
    title = snippets.title(name)
    if not title:
        return
    a = QAction(parent)
    a.setObjectName(name)
    a.setText(title.replace('&', '&&'))
    icon = snippets.icon(name)
    if icon:
        a.setIcon(icon)
    if collection:
        shortcuts = collection.shortcuts(name)
        if shortcuts:
            a.setShortcuts(shortcuts)
    return a
Example #26
0
    def create_action(self,
                      action_name,
                      action_group,
                      icon_num=None,
                      text=None):
        """ Creates a new action with selected parameters """

        icon = None
        icon_folder = self.plugin_dir + '/icons/'
        icon_path = icon_folder + icon_num + '.png'
        if os.path.exists(icon_path):
            icon = QIcon(icon_path)

        if icon is None:
            action = QAction(text, action_group)
        else:
            action = QAction(icon, text, action_group)
        action.setObjectName(action_name)

        return action
Example #27
0
class AuxiliaryWindowPlugin:

  def __init__(self, iface):
    self.iface = iface
    self.plugin = ContainerAuxiliaryWindow( iface.mainWindow() )
    self.namePlugin = "&Auxiliary Window"

  def _connect(self, isConnect = True):
    signal_slot = (
      { 'signal': QgsProject.instance().readProject, 'slot': self.plugin.onReadProject },
      { 'signal': QgsProject.instance().writeProject, 'slot': self.plugin.onWriteProject }
    )
    if isConnect:
      for item in signal_slot:
        item['signal'].connect( item['slot'] )
    else:
      for item in signal_slot:
        item['signal'].disconnect( item['slot'] )

  def initGui(self):
    title = "Auxiliary window"
    icon = QIcon( os.path.join( os.path.dirname(__file__), 'auxiliarywindow.png' ) )
    self.action = QAction( icon, title, self.iface.mainWindow() )
    self.action.setObjectName( "AuxiliaryWindow" )
    self.action.setWhatsThis( title )
    self.action.setStatusTip( title )
    self.action.triggered.connect( self.run )
    self.iface.addToolBarIcon( self.action )
    self.iface.addPluginToMenu( self.namePlugin, self.action)
    self._connect()

  def unload(self):
    self.iface.removeToolBarIcon( self.action )
    self.iface.removePluginMenu( self.namePlugin, self.action)
    del self.action
    self._connect( False )
    self.plugin.close()
  
  @pyqtSlot()
  def run(self):
    self.plugin.run()
class SearchLayers:
    def __init__(self, iface):
        self.iface = iface
        self.searchDialog = None

    def initGui(self):
        # Create the menu items in the Plugin menu and attach the icon to the toolbar
        icon = QIcon(os.path.dirname(__file__) + "/icon.png")
        self.searchAction = QAction(icon, "Search Layers",
                                    self.iface.mainWindow())
        self.searchAction.setObjectName('searchLayers')
        self.searchAction.triggered.connect(self.showSearchDialog)
        self.iface.addToolBarIcon(self.searchAction)
        self.iface.addPluginToMenu("Search Layers", self.searchAction)

        # Help
        icon = QIcon(os.path.dirname(__file__) + '/help.png')
        self.helpAction = QAction(icon, "Help", self.iface.mainWindow())
        self.helpAction.setObjectName('searchLayersHelp')
        self.helpAction.triggered.connect(self.help)
        self.iface.addPluginToMenu('Search Layers', self.helpAction)

    def unload(self):
        self.iface.removePluginMenu('Search Layers', self.searchAction)
        self.iface.removePluginMenu('Search Layers', self.helpAction)
        self.iface.removeToolBarIcon(self.searchAction)

    def showSearchDialog(self):
        if self.searchDialog is None:
            # All the work is done in the LayerSearchDialog
            self.searchDialog = LayerSearchDialog(self.iface,
                                                  self.iface.mainWindow())
        self.searchDialog.show()

    def help(self):
        '''Display a help page'''
        url = QUrl.fromLocalFile(os.path.dirname(__file__) +
                                 "/index.html").toString()
        webbrowser.open(url, new=2)
Example #29
0
    def addAction(self, action):
        """
        Adds the inputed action to this widget's action group.  This will auto-\
        create a new group if no group is already defined.
        
        :param      action | <QAction> || <str>
        
        :return     <QAction>
        """
        if (not isinstance(action, QAction)):
            action_name = str(action)
            action = QAction(action_name, self)
            action.setObjectName(action_name)

        action.setCheckable(True)

        if (not self._actionGroup):
            self._actionGroup = QActionGroup(self)
            action.setChecked(True)

        self._actionGroup.addAction(action)
        self.reset()
        return action
 def addAction( self, action ):
     """
     Adds the inputed action to this widget's action group.  This will auto-\
     create a new group if no group is already defined.
     
     :param      action | <QAction> || <str>
     
     :return     <QAction>
     """
     if ( not isinstance(action, QAction) ):
         action_name = str(action)
         action = QAction(action_name, self)
         action.setObjectName(action_name)
     
     action.setCheckable(True)
     
     if ( not self._actionGroup ):
         self._actionGroup = QActionGroup(self)
         action.setChecked(True)
         
     self._actionGroup.addAction(action)
     self.reset()
     return action
    def addMenus(self):
        if self.profilesMenu is not None:
            self.profilesMenu.clear()
        self.actions = defaultdict(list)
        settings = QSettings()
        defaultProfile = settings.value('profilesplugin/LastProfile', 'Default', unicode)
        autoLoad = settings.value('profilesplugin/AutoLoad', False, bool)
        for k, v in profiles.iteritems():
            action = QAction(k, self.iface.mainWindow())
            action.setCheckable(True)
            if k == defaultProfile and autoLoad:
                action.setChecked(True)
            action.triggered.connect(lambda _, menuName=k: self.applyProfile(menuName))
            action.setObjectName('mProfilesPlugin_' + k)
            self.actions[v.group].append(action)

        actions = self.iface.mainWindow().menuBar().actions()
        settingsMenu = None
        self.profilesGroup = QActionGroup(self.iface.mainWindow())
        if self.profilesMenu is None:
            for action in actions:
                if action.menu().objectName() == 'mSettingsMenu':
                    settingsMenu = action.menu()
                    self.profilesMenu = QMenu(settingsMenu)
                    self.profilesMenu.setObjectName('mProfilesPlugin')
                    self.profilesMenu.setTitle(self.tr('Profiles'))
                    settingsMenu.addMenu(self.profilesMenu)
                    break

        if self.profilesMenu is not None:
            for k,v in self.actions.iteritems():
                submenu = QMenu(self.profilesMenu)
                submenu.setObjectName('mProfilesPlugin_submenu_' + k)
                submenu.setTitle(k)
                for action in v:
                    self.profilesGroup.addAction(action)
                    submenu.addAction(action)
                self.profilesMenu.addMenu(submenu)

        self.profilesMenu.addSeparator()

        settings = QSettings()
        def _setAutoLoad():
            settings.setValue('profilesplugin/AutoLoad', self.autoloadAction.isChecked())

        self.autoloadAction = QAction(self.tr('Auto-load last profile on QGIS start'), iface.mainWindow())
        self.autoloadAction.setCheckable(True)
        autoLoad = settings.value('profilesplugin/AutoLoad', False, bool)
        self.autoloadAction.setChecked(autoLoad)
        self.autoloadAction.setObjectName('mProfilesPluginAutoLoad')
        self.autoloadAction.triggered.connect(_setAutoLoad)
        self.profilesMenu.addAction(self.autoloadAction)

        self.saveProfileAction = QAction(self.tr('Profiles manager...'),
                                         self.iface.mainWindow())
        self.saveProfileAction.setObjectName('mProfilesPluginProfilesManager')
        self.saveProfileAction.triggered.connect(self.saveProfile)
        self.profilesMenu.addAction(self.saveProfileAction)

        self.showHelpAction = QAction(self.tr('Help'), self.iface.mainWindow())
        self.showHelpAction.setIcon(QgsApplication.getThemeIcon('/mActionHelpContents.svg'))
        self.showHelpAction.setObjectName('mProfilesPluginShowHelp')
        self.showHelpAction.triggered.connect(self.showHelp)
        self.profilesMenu.addAction(self.showHelpAction)
Example #32
0
class TalkEditorApp(FreeseerApp):
    '''Freeseer talk database editor main gui class'''
    def __init__(self, config, db):
        FreeseerApp.__init__(self)

        self.config = config
        self.db = db

        icon = QIcon()
        icon.addPixmap(QPixmap(':/freeseer/logo.png'), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(960, 600)

        #
        # Setup Layout
        #
        self.mainWidget = QWidget()
        self.mainLayout = QVBoxLayout()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)
        self.mainLayout.setAlignment(QtCore.Qt.AlignTop)

        # Add the Title Row (Use BOLD / Big Font)
        #self.titleLayout = QHBoxLayout()
        #self.backButton = QPushButton('Back to Recorder')
        #if backButton:  # Only show the back button if requested by caller
        #    self.titleLayout.addWidget(self.backButton)
        #self.titleLayout.addStretch()

        # Add custom widgets
        self.commandButtons = CommandButtons()
        self.tableView = QTableView()
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.talkDetailsWidget = TalkDetailsWidget()
        self.importTalksWidget = ImportTalksWidget()
        self.mainLayout.addWidget(self.importTalksWidget)
        #self.mainLayout.addLayout(self.titleLayout)
        self.mainLayout.addWidget(self.commandButtons)
        self.mainLayout.addWidget(self.tableView)
        self.mainLayout.addWidget(self.talkDetailsWidget)
        self.mainLayout.addWidget(self.importTalksWidget)
        # --- End Layout

        # Initialize geometry, to be used for restoring window positioning.
        self.geometry = None

        #
        # Setup Menubar
        #
        self.actionExportCsv = QAction(self)
        self.actionExportCsv.setObjectName('actionExportCsv')
        self.actionRemoveAll = QAction(self)
        self.actionRemoveAll.setObjectName('actionRemoveAll')

        # Actions
        self.menuFile.insertAction(self.actionExit, self.actionExportCsv)
        self.menuFile.insertAction(self.actionExit, self.actionRemoveAll)
        # --- End Menubar

        #
        # TableView Connections
        #
        self.connect(self.tableView, SIGNAL('activated(const QModelIndex)'), self.talk_selected)
        self.connect(self.tableView, SIGNAL('selected(const QModelIndex)'), self.talk_selected)
        self.connect(self.tableView, SIGNAL('clicked(const QModelIndex)'), self.talk_selected)

        # Import Widget
        self.connect(self.importTalksWidget.csvRadioButton, SIGNAL('toggled(bool)'), self.toggle_import)
        self.connect(self.importTalksWidget.importButton, SIGNAL('clicked()'), self.import_talks)
        self.connect(self.importTalksWidget.cancelButton, SIGNAL('clicked()'), self.hide_import_talks_widget)
        self.importTalksWidget.setHidden(True)
        self.connect(self.importTalksWidget.csvFileSelectButton, QtCore.SIGNAL('clicked()'), self.csv_file_select)
        self.connect(self.importTalksWidget.csvLineEdit, QtCore.SIGNAL('returnPressed()'),
            self.importTalksWidget.importButton.click)
        self.connect(self.importTalksWidget.rssLineEdit, QtCore.SIGNAL('returnPressed()'),
            self.importTalksWidget.importButton.click)
        self.connect(self.actionExportCsv, QtCore.SIGNAL('triggered()'), self.export_talks_to_csv)
        self.connect(self.actionRemoveAll, QtCore.SIGNAL('triggered()'), self.confirm_reset)

        # Command Buttons
        self.connect(self.commandButtons.removeButton, SIGNAL('clicked()'), self.remove_talk)
        self.connect(self.commandButtons.removeAllButton, SIGNAL('clicked()'), self.confirm_reset)
        self.connect(self.commandButtons.importButton, SIGNAL('clicked()'), self.show_import_talks_widget)
        self.connect(self.commandButtons.exportButton, SIGNAL('clicked()'), self.export_talks_to_csv)
        self.connect(self.commandButtons.searchButton, SIGNAL('clicked()'), self.search_talks)
        self.connect(self.commandButtons.searchLineEdit, SIGNAL('textEdited(QString)'), self.search_talks)
        self.connect(self.commandButtons.searchLineEdit, SIGNAL('returnPressed()'), self.search_talks)

        # Talk Details Buttons
        self.connect(self.talkDetailsWidget.addButton, SIGNAL('clicked()'), self.clear_talk_details_widget)
        self.connect(self.talkDetailsWidget.saveButton, SIGNAL('clicked()'), self.add_talk)

        # Load default language
        actions = self.menuLanguage.actions()
        for action in actions:
            if action.data().toString() == self.config.default_language:
                action.setChecked(True)
                self.translate(action)
                break

        # Load Talk Database
        self.load_presentations_model()

        # Setup Autocompletion
        self.update_autocomple_fields()

        # Select first item
        #self.tableView.setCurrentIndex(self.proxy.index(0,0))
        #self.talk_selected(self.proxy.index(0,0))

    #
    # Translation
    #
    def retranslate(self):
        self.setWindowTitle(self.app.translate("TalkEditorApp", "Freeseer Talk Editor"))

        #
        # Reusable Strings
        #
        self.confirmDBClearTitleString = self.app.translate("TalkEditorApp", "Remove All Talks from Database")
        self.confirmDBClearQuestionString = self.app.translate("TalkEditorApp",
            "Are you sure you want to clear the DB?")
        # --- End Reusable Strings

        #
        # Menubar
        #
        self.actionExportCsv.setText(self.app.translate("TalkEditorApp", "&Export to CSV"))
        self.actionRemoveAll.setText(self.app.translate("TalkEditorApp", "&Remove All Talks"))

        # --- End Menubar

        #
        # TalkDetailsWidget
        #
        self.talkDetailsWidget.titleLabel.setText(self.app.translate("TalkEditorApp", "Title"))
        self.talkDetailsWidget.presenterLabel.setText(self.app.translate("TalkEditorApp", "Presenter"))
        self.talkDetailsWidget.categoryLabel.setText(self.app.translate("TalkEditorApp", "Category"))
        self.talkDetailsWidget.eventLabel.setText(self.app.translate("TalkEditorApp", "Event"))
        self.talkDetailsWidget.roomLabel.setText(self.app.translate("TalkEditorApp", "Room"))
        self.talkDetailsWidget.dateLabel.setText(self.app.translate("TalkEditorApp", "Date"))
        self.talkDetailsWidget.timeLabel.setText(self.app.translate("TalkEditorApp", "Time"))
        # --- End TalkDetailsWidget

        #
        # Import Talks Widget Translations
        #
        self.importTalksWidget.rssRadioButton.setText(self.app.translate("TalkEditorApp", "RSS URL"))
        self.importTalksWidget.csvRadioButton.setText(self.app.translate("TalkEditorApp", "CSV File"))
        self.importTalksWidget.importButton.setText(self.app.translate("TalkEditorApp", "Import"))
        # --- End Talks Widget Translations

        #
        # Command Button Translations\
        #
        #self.commandButtons.addButton.setText(self.app.translate("TalkEditorApp", "Add"))
        self.commandButtons.importButton.setText(self.app.translate("TalkEditorApp", "Import"))
        self.commandButtons.exportButton.setText(self.app.translate("TalkEditorApp", "Export"))
        self.commandButtons.removeButton.setText(self.app.translate("TalkEditorApp", "Remove"))
        self.commandButtons.removeAllButton.setText(self.app.translate("TalkEditorApp", "Remove All"))
        # --- End Command Butotn Translations

        #
        # Search Widget Translations
        #
        self.commandButtons.searchButton.setText(self.app.translate("TalkEditorApp", "Search"))
        # --- End Command Button Translations

    def load_presentations_model(self):
        # Load Presentation Model
        self.presentationModel = self.db.get_presentations_model()
        self.proxy = QSortFilterProxyModel()
        self.proxy.setSourceModel(self.presentationModel)
        self.tableView.setModel(self.proxy)
        self.proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)

        # Fill table whitespace.
        self.tableView.horizontalHeader().setStretchLastSection(False)
        self.tableView.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)

        # Hide the ID field
        self.tableView.setColumnHidden(0, True)

        # Map data to widgets
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy)
        self.mapper.addMapping(self.talkDetailsWidget.titleLineEdit, 1)
        self.mapper.addMapping(self.talkDetailsWidget.presenterLineEdit, 2)
        self.mapper.addMapping(self.talkDetailsWidget.categoryLineEdit, 4)
        self.mapper.addMapping(self.talkDetailsWidget.eventLineEdit, 5)
        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.mapper.addMapping(self.talkDetailsWidget.descriptionTextEdit, 3)
        self.mapper.addMapping(self.talkDetailsWidget.dateEdit, 7)
        self.mapper.addMapping(self.talkDetailsWidget.timeEdit, 8)

        # Load StringLists
        self.titleList = QStringList(self.db.get_string_list("Title"))
        #self.speakerList = QStringList(self.db.get_speaker_list())
        #self.categoryList = QStringList(self.db.get_category_list())
        #self.eventList = QStringList(self.db.get_event_list())
        #self.roomList = QStringList(self.db.get_room_list())

        #Disble input
        self.talkDetailsWidget.disable_input_fields()

    def search_talks(self):
        # The default value is 0. If the value is -1, the keys will be read from all columns.
        self.proxy.setFilterKeyColumn(-1)
        self.proxy.setFilterFixedString(self.commandButtons.searchLineEdit.text())

    def talk_selected(self, model):
        self.talkDetailsWidget.saveButton.setEnabled(False)
        self.mapper.setCurrentIndex(model.row())
        self.talkDetailsWidget.enable_input_fields()

    def toggle_import(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.importTalksWidget.csvLineEdit.setEnabled(True)
            self.importTalksWidget.csvFileSelectButton.setEnabled(True)
            self.importTalksWidget.rssLineEdit.setEnabled(False)
        else:
            self.importTalksWidget.csvLineEdit.setEnabled(False)
            self.importTalksWidget.csvFileSelectButton.setEnabled(False)
            self.importTalksWidget.rssLineEdit.setEnabled(True)

    def show_import_talks_widget(self):
        self.commandButtons.setHidden(True)
        self.tableView.setHidden(True)
        self.talkDetailsWidget.setHidden(True)
        self.importTalksWidget.setHidden(False)

    def hide_import_talks_widget(self):
        self.commandButtons.setHidden(False)
        self.tableView.setHidden(False)
        self.talkDetailsWidget.setHidden(False)
        self.importTalksWidget.setHidden(True)

    def add_talk(self):
        date = self.talkDetailsWidget.dateEdit.date()
        time = self.talkDetailsWidget.timeEdit.time()
        #datetime = QtCore.QDateTime(date, time)
        presentation = Presentation(
            unicode(self.talkDetailsWidget.titleLineEdit.text()),
            unicode(self.talkDetailsWidget.presenterLineEdit.text()),
            unicode(self.talkDetailsWidget.descriptionTextEdit.toPlainText()),
            unicode(self.talkDetailsWidget.categoryLineEdit.text()),
            unicode(self.talkDetailsWidget.eventLineEdit.text()),
            unicode(self.talkDetailsWidget.roomLineEdit.text()),
            unicode(date.toString(QtCore.Qt.ISODate)),
            unicode(time.toString(QtCore.Qt.ISODate)))

        # Do not add talks if they are empty strings
        if (len(presentation.title) == 0):
            return
        self.db.insert_presentation(presentation)

        # Update Model, Refreshes TableView
        self.presentationModel.select()

        # Select Last Row
        self.tableView.selectRow(self.presentationModel.rowCount() - 1)
        self.tableView.setCurrentIndex(self.proxy.index(self.proxy.rowCount() - 1, 0))
        self.talk_selected(self.proxy.index(self.proxy.rowCount() - 1, 0))

        self.update_autocomple_fields()
        self.talkDetailsWidget.disable_input_fields()

    def clear_talk_details_widget(self):
        self.talkDetailsWidget.saveButton.setEnabled(True)
        self.talkDetailsWidget.enable_input_fields()
        self.talkDetailsWidget.titleLineEdit.clear()
        self.talkDetailsWidget.presenterLineEdit.clear()
        self.talkDetailsWidget.descriptionTextEdit.clear()
        #self.talkDetailsWidget.categoryLineEdit.clear()
        #self.talkDetailsWidget.eventLineEdit.clear()
        #self.talkDetailsWidget.roomLineEdit.clear()
        self.presentationModel.select()

    def remove_talk(self):
        try:
            rows_selected = self.tableView.selectionModel().selectedRows()
        except:
            return

        # Reversed because rows in list change position once row is removed
        for row in reversed(rows_selected):
            self.presentationModel.removeRow(row.row())

    def load_talk(self):
        try:
            self.tableView.currentIndex().row()
        except:
            return

        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.presentationModel.select()

    def reset(self):
        self.db.clear_database()
        self.presentationModel.select()

    def confirm_reset(self):
        """Presents a confirmation dialog to ask the user if they are sure they wish to remove the talk database.
        If Yes call the reset() function"""
        confirm = QMessageBox.question(self,
                                       self.confirmDBClearTitleString,
                                       self.confirmDBClearQuestionString,
                                       QMessageBox.Yes |
                                       QMessageBox.No,
                                       QMessageBox.No)

        if confirm == QMessageBox.Yes:
            self.reset()

    def add_talks_from_rss(self):
        rss_url = unicode(self.importTalksWidget.rssLineEdit.text())
        if rss_url:
            self.db.add_talks_from_rss(rss_url)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please enter a RSS URL")
            error.exec_()

    def closeEvent(self, event):
        log.info('Exiting talk database editor...')
        self.geometry = self.saveGeometry()
        event.accept()

    def csv_file_select(self):
        fname = QFileDialog.getOpenFileName(
            self, 'Select file', "", "*.csv")
        if fname:
            self.importTalksWidget.csvLineEdit.setText(fname)

    def add_talks_from_csv(self):
        fname = self.importTalksWidget.csvLineEdit.text()

        if fname:
            self.db.add_talks_from_csv(fname)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please select a file")
            error.exec_()

    def import_talks(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.add_talks_from_csv()
        else:
            self.add_talks_from_rss()

        self.update_autocomple_fields()

    def export_talks_to_csv(self):
        fname = QFileDialog.getSaveFileName(self, 'Select file', "", "*.csv")
        if fname:
            self.db.export_talks_to_csv(fname)

    def update_autocomple_fields(self):
        self.titleList = QStringList(self.db.get_string_list("Title"))
        self.speakerList = QStringList(self.db.get_string_list("Speaker"))
        self.categoryList = QStringList(self.db.get_string_list("Category"))
        self.eventList = QStringList(self.db.get_string_list("Event"))
        self.roomList = QStringList(self.db.get_string_list("Room"))

        self.titleCompleter = QCompleter(self.titleList)
        self.titleCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.speakerCompleter = QCompleter(self.speakerList)
        self.speakerCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.categoryCompleter = QCompleter(self.categoryList)
        self.categoryCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.eventCompleter = QCompleter(self.eventList)
        self.eventCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.roomCompleter = QCompleter(self.roomList)
        self.roomCompleter.setCaseSensitivity(Qt.CaseInsensitive)

        self.talkDetailsWidget.titleLineEdit.setCompleter(self.titleCompleter)
        self.talkDetailsWidget.presenterLineEdit.setCompleter(self.speakerCompleter)
        self.talkDetailsWidget.categoryLineEdit.setCompleter(self.categoryCompleter)
        self.talkDetailsWidget.eventLineEdit.setCompleter(self.eventCompleter)
        self.talkDetailsWidget.roomLineEdit.setCompleter(self.roomCompleter)
Example #33
0
class Plugin(object):
    """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
        """
        # Register all the impact functions
        register_impact_functions()
        # Save reference to the QGIS interface
        self.iface = iface
        self.dock_widget = None
        self.action_import_dialog = None
        self.action_save_scenario = None
        self.action_batch_runner = None
        self.action_shake_converter = None
        self.action_minimum_needs = None
        self.action_global_minimum_needs = None
        self.action_impact_merge_dlg = None
        self.key_action = None
        self.action_options = None
        self.action_keywords_dialog = None
        self.action_keywords_wizard = None
        self.action_function_centric_wizard = None
        self.action_extent_selector = None
        self.translator = None
        self.toolbar = None
        self.actions = []  # list of all QActions we create for InaSAFE
        self.action_dock = None
        self.action_toggle_rubberbands = None
        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)

    # noinspection PyArgumentList
    def change_i18n(self, new_locale):
        """Change internationalisation for the plugin.

        Override the system locale  and then see if we can get a valid
        translation file for whatever locale is effectively being used.

        :param new_locale: The new locale i.e. 'id', 'af', etc.
        :type new_locale: str

        :raises: TranslationLoadException
        """

        os.environ['INASAFE_LANG'] = str(new_locale)

        LOGGER.debug('%s %s %s' % (
            new_locale, QLocale.system().name(), os.environ['INASAFE_LANG']))

        root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        translation_path = os.path.join(
            root, 'safe_qgis', 'i18n',
            'inasafe_' + str(new_locale) + '.qm')

        if os.path.exists(translation_path):
            self.translator = QTranslator()
            result = self.translator.load(translation_path)
            if not result:
                message = 'Failed to load translation for %s' % new_locale
                raise TranslationLoadError(message)
            # noinspection PyTypeChecker,PyCallByClass
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' % (
            translation_path, os.path.exists(translation_path)))

    # 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 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

        """
        # 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)

    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)

    def _create_keywords_action(self):
        """Create action for keywords editor."""
        icon = resources_path('img', 'icons', 'show-keyword-editor.svg')
        self.action_keywords_dialog = QAction(
            QIcon(icon),
            self.tr('InaSAFE Keyword Editor'),
            self.iface.mainWindow())
        self.action_keywords_dialog.setStatusTip(self.tr(
            'Open InaSAFE keywords editor'))
        self.action_keywords_dialog.setWhatsThis(self.tr(
            'Open InaSAFE keywords editor'))
        self.action_keywords_dialog.setEnabled(False)
        self.action_keywords_dialog.triggered.connect(
            self.show_keywords_editor)
        self.add_action(
            self.action_keywords_dialog, add_to_toolbar=self.full_toolbar)

    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('InaSAFE 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)

    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('InaSAFE 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('InaSAFE 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('InaSAFE Minimum Needs Tool'), self.iface.mainWindow())
        self.action_minimum_needs.setStatusTip(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.action_minimum_needs.setWhatsThis(self.tr(
            'Open InaSAFE minimum needs tool'))
        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_minimum_needs_options_action(self):
        """Create action for global minimum needs dialog."""
        icon = resources_path('img', 'icons', 'show-global-minimum-needs.svg')
        self.action_global_minimum_needs = QAction(
            QIcon(icon),
            self.tr('InaSAFE Global Minimum Needs Configuration'),
            self.iface.mainWindow())
        self.action_global_minimum_needs.setStatusTip(self.tr(
            'Open InaSAFE global minimum needs configuration'))
        self.action_global_minimum_needs.setWhatsThis(self.tr(
            'Open InaSAFE global minimum needs configuration'))
        self.action_global_minimum_needs.triggered.connect(
            self.show_global_minimum_needs_configuration)
        self.add_action(
            self.action_global_minimum_needs, 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('InaSAFE 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('InaSAFE Batch Runner'), self.iface.mainWindow())
        self.action_batch_runner.setStatusTip(self.tr(
            'Open InaSAFE Batch Runner'))
        self.action_batch_runner.setWhatsThis(self.tr(
            'Open InaSAFE 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('InaSAFE OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.action_import_dialog.setStatusTip(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.action_import_dialog.setWhatsThis(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.action_import_dialog.triggered.connect(self.show_osm_downloader)
        self.add_action(self.action_import_dialog)

    def _create_impact_merge_action(self):
        """Create action for impact layer merge Dialog."""
        icon = resources_path('img', 'icons', 'show-impact-merge.svg')
        self.action_impact_merge_dlg = QAction(
            QIcon(icon),
            self.tr('InaSAFE Impact Layer Merge'),
            self.iface.mainWindow())
        self.action_impact_merge_dlg.setStatusTip(self.tr(
            'InaSAFE Impact Layer Merge'))
        self.action_impact_merge_dlg.setWhatsThis(self.tr(
            'InaSAFE Impact Layer Merge'))
        self.action_impact_merge_dlg.triggered.connect(self.show_impact_merge)
        self.add_action(
            self.action_impact_merge_dlg, 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 scenarion extents.')
        self.action_toggle_rubberbands.setStatusTip(message)
        self.action_toggle_rubberbands.setWhatsThis(message)
        # Set initial state
        self.action_toggle_rubberbands.setCheckable(True)
        settings = QSettings()
        flag = bool(settings.value(
            'inasafe/showRubberBands', False, 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 InaSAFE 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)."""
        final_release = release_status() == 'final'
        settings = QSettings()
        self.developer_mode = settings.value(
            'inasafe/developer_mode', False, type=bool)
        if not final_release and self.developer_mode:
            icon = resources_path('img', 'icons', 'add-test-layers.svg')
            self.action_add_layers = QAction(
                QIcon(icon),
                self.tr('Add Some Test Layers'),
                self.iface.mainWindow())
            self.action_add_layers.setStatusTip(self.tr(
                'Add some test layers'))
            self.action_add_layers.setWhatsThis(self.tr(
                'Add some test layers'))
            self.action_add_layers.triggered.connect(
                self.add_test_layers)

            self.add_action(self.action_add_layers)

    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.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_()

    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_options_dialog_action()
        self._create_minimum_needs_options_action()
        self._create_analysis_extent_action()
        self._create_dock_toggle_action()
        self._create_rubber_bands_action()
        # TODO: add menu separator - Wizards
        self._create_keywords_wizard_action()
        self._create_analysis_wizard_action()
        # TODO: add menu separator - Data
        self._create_osm_downloader_action()
        self._create_shakemap_converter_action()
        self._create_minimum_needs_action()
        self._create_test_layers_action()
        # TODO: add menu separator - Analysis
        self._create_batch_runner_action()
        self._create_impact_merge_action()
        self._create_save_scenario_action()
        # TODO: This action (and related code) will be deprecated
        # keywords dialog to be replaced by keywords wizard
        self._create_keywords_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())

    def clear_modules(self):
        """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
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(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)

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

    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.user_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)
        # 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.show()  # non modal

    def show_global_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_impact_merge(self):
        """Show the impact layer merge dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.impact_merge_dialog import ImpactMergeDialog

        dialog = ImpactMergeDialog(self.iface.mainWindow())
        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(
            self.iface,
            self.dock_widget,
            self.iface.mainWindow())
        dialog.exec_()  # modal

    def show_keywords_editor(self):
        """Show the keywords editor."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.keywords_dialog import KeywordsDialog

        # Next block is a fix for #776
        if self.iface.activeLayer() is None:
            return

        try:
            keyword_io = KeywordIO()
            keyword_io.read_keywords(self.iface.activeLayer())
        except UnsupportedProviderError:
            # noinspection PyUnresolvedReferences,PyCallByClass
            # noinspection PyTypeChecker,PyArgumentList
            QMessageBox.warning(
                None,
                self.tr('Unsupported layer type'),
                self.tr(
                    'The layer you have selected cannot be used for '
                    'analysis because its data type is unsupported.'))
            return
        # End of fix for #776
        # Fix for #793
        except NoKeywordsFoundError:
            # we will create them from scratch in the dialog
            pass
        # End of fix for #793
        # Fix for filtered-layer
        except InvalidParameterError, e:
            # noinspection PyTypeChecker,PyTypeChecker,PyArgumentList
            QMessageBox.warning(
                None,
                self.tr('Invalid Layer'),
                e.message
            )
            return

        dialog = KeywordsDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dock_widget)
        dialog.exec_()  # modal
class ProfilesPlugin:

    def __init__(self, iface):
        self.iface = iface
        QSettings().setValue('/UI/Customization/enabled', False)

        try:
            from profiles.tests import testerplugin
            from qgistester.tests import addTestModule
            addTestModule(testerplugin, 'Profiles plugin')
        except:
            pass

        self.userProfileAction = None
        self.profilesMenu = None

        iface.initializationCompleted.connect(self.initProfile)

    def unload(self):
        if self.profilesMenu is not None:
            self.profilesMenu.deleteLater()
        self.iface.removePluginMenu(self.tr('Profiles'), self.autoloadAction)
        self.iface.removePluginMenu(self.tr('Profiles'), self.saveProfileAction)
        try:
            from profiles.tests import testerplugin
            from qgistester.tests import removeTestModule
            removeTestModule(testerplugin, 'Profiles plugin')
        except:
            pass
        saveCurrentPluginState()

    def initGui(self):
        self.addMenus()

    def addMenus(self):
        if self.profilesMenu is not None:
            self.profilesMenu.clear()
        self.actions = defaultdict(list)
        settings = QSettings()
        defaultProfile = settings.value('profilesplugin/LastProfile', 'Default', unicode)
        autoLoad = settings.value('profilesplugin/AutoLoad', False, bool)
        for k, v in profiles.iteritems():
            action = QAction(k, self.iface.mainWindow())
            action.setCheckable(True)
            if k == defaultProfile and autoLoad:
                action.setChecked(True)
            action.triggered.connect(lambda _, menuName=k: self.applyProfile(menuName))
            action.setObjectName('mProfilesPlugin_' + k)
            self.actions[v.group].append(action)

        actions = self.iface.mainWindow().menuBar().actions()
        settingsMenu = None
        self.profilesGroup = QActionGroup(self.iface.mainWindow())
        if self.profilesMenu is None:
            for action in actions:
                if action.menu().objectName() == 'mSettingsMenu':
                    settingsMenu = action.menu()
                    self.profilesMenu = QMenu(settingsMenu)
                    self.profilesMenu.setObjectName('mProfilesPlugin')
                    self.profilesMenu.setTitle(self.tr('Profiles'))
                    settingsMenu.addMenu(self.profilesMenu)
                    break

        if self.profilesMenu is not None:
            for k,v in self.actions.iteritems():
                submenu = QMenu(self.profilesMenu)
                submenu.setObjectName('mProfilesPlugin_submenu_' + k)
                submenu.setTitle(k)
                for action in v:
                    self.profilesGroup.addAction(action)
                    submenu.addAction(action)
                self.profilesMenu.addMenu(submenu)

        self.profilesMenu.addSeparator()

        settings = QSettings()
        def _setAutoLoad():
            settings.setValue('profilesplugin/AutoLoad', self.autoloadAction.isChecked())

        self.autoloadAction = QAction(self.tr('Auto-load last profile on QGIS start'), iface.mainWindow())
        self.autoloadAction.setCheckable(True)
        autoLoad = settings.value('profilesplugin/AutoLoad', False, bool)
        self.autoloadAction.setChecked(autoLoad)
        self.autoloadAction.setObjectName('mProfilesPluginAutoLoad')
        self.autoloadAction.triggered.connect(_setAutoLoad)
        self.profilesMenu.addAction(self.autoloadAction)

        self.saveProfileAction = QAction(self.tr('Profiles manager...'),
                                         self.iface.mainWindow())
        self.saveProfileAction.setObjectName('mProfilesPluginProfilesManager')
        self.saveProfileAction.triggered.connect(self.saveProfile)
        self.profilesMenu.addAction(self.saveProfileAction)

        self.showHelpAction = QAction(self.tr('Help'), self.iface.mainWindow())
        self.showHelpAction.setIcon(QgsApplication.getThemeIcon('/mActionHelpContents.svg'))
        self.showHelpAction.setObjectName('mProfilesPluginShowHelp')
        self.showHelpAction.triggered.connect(self.showHelp)
        self.profilesMenu.addAction(self.showHelpAction)


    def applyProfile(self, name):
        profile = profiles.get(name)
        applyProfile(profile)

    def initProfile(self):
        settings = QSettings()
        autoLoad = settings.value('profilesplugin/AutoLoad', False, bool)
        if autoLoad:
            profileName = settings.value('profilesplugin/LastProfile', '', unicode)
            if profileName in profiles:
                profile = profiles[profileName]
                if not profile.hasToInstallPlugins():
                    applyProfile(profile, False)

    def saveProfile(self):
        dlg = ProfileManager(iface.mainWindow())
        dlg.exec_()

    def showHelp(self):
        if not QDesktopServices.openUrl(
                QUrl('file://{}'.format(os.path.join(pluginPath, 'docs', 'html', 'index.html')))):
            QMessageBox.warning(None,
                                self.tr('Error'),
                                self.tr('Can not open help URL in browser'))

    def tr(self, text):
        return QCoreApplication.translate('Profiles', text)
Example #35
0
class FreeseerApp(QMainWindow):
    def __init__(self, config):
        super(FreeseerApp, self).__init__()
        self.config = config
        self.icon = QIcon()
        self.icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")),
                            QIcon.Normal, QIcon.Off)
        self.setWindowIcon(self.icon)

        self.aboutDialog = AboutDialog()
        self.aboutDialog.setModal(True)

        self.logDialog = LogDialog()

        #
        # Translator
        #
        self.app = QApplication.instance()
        self.current_language = None
        self.uiTranslator = QTranslator()
        self.uiTranslator.load(":/languages/tr_en_US.qm")
        self.app.installTranslator(self.uiTranslator)
        self.langActionGroup = QActionGroup(self)
        self.langActionGroup.setExclusive(True)
        QTextCodec.setCodecForTr(QTextCodec.codecForName('utf-8'))
        self.connect(self.langActionGroup, SIGNAL('triggered(QAction *)'),
                     self.translate)
        # --- Translator

        #
        # Setup Menubar
        #
        self.menubar = self.menuBar()

        self.menubar.setGeometry(QRect(0, 0, 500, 50))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuLanguage = QMenu(self.menubar)
        self.menuLanguage.setObjectName(_fromUtf8("menuLanguage"))
        self.menuHelp = QMenu(self.menubar)
        self.menuHelp.setObjectName(_fromUtf8("menuHelp"))

        exitIcon = QIcon.fromTheme("application-exit")
        self.actionExit = QAction(self)
        self.actionExit.setShortcut("Ctrl+Q")
        self.actionExit.setObjectName(_fromUtf8("actionExit"))
        self.actionExit.setIcon(exitIcon)

        helpIcon = QIcon.fromTheme("help-contents")
        self.actionOnlineHelp = QAction(self)
        self.actionOnlineHelp.setObjectName(_fromUtf8("actionOnlineHelp"))
        self.actionOnlineHelp.setIcon(helpIcon)

        self.actionAbout = QAction(self)
        self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
        self.actionAbout.setIcon(self.icon)

        self.actionLog = QAction(self)
        self.actionLog.setObjectName(_fromUtf8("actionLog"))
        self.actionLog.setShortcut("Ctrl+L")

        # Actions
        self.menuFile.addAction(self.actionExit)
        self.menuHelp.addAction(self.actionAbout)
        self.menuHelp.addAction(self.actionLog)
        self.menuHelp.addAction(self.actionOnlineHelp)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuLanguage.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.setupLanguageMenu()
        # --- End Menubar

        self.connect(self.actionExit, SIGNAL('triggered()'), self.close)
        self.connect(self.actionAbout, SIGNAL('triggered()'),
                     self.aboutDialog.show)
        self.connect(self.actionLog, SIGNAL('triggered()'),
                     self.logDialog.show)
        self.connect(self.actionOnlineHelp, SIGNAL('triggered()'),
                     self.openOnlineHelp)

        self.retranslateFreeseerApp()
        self.aboutDialog.aboutWidget.retranslate("en_US")

    def openOnlineHelp(self):
        """Opens a link to the Freeseer Online Help"""
        url = QUrl("http://freeseer.readthedocs.org")
        QDesktopServices.openUrl(url)

    def translate(self, action):
        """Translates the GUI via menu action.

        When a language is selected from the language menu, this function is
        called and the language to be changed to is retrieved.
        """
        self.current_language = str(
            action.data().toString()).strip("tr_").rstrip(".qm")

        log.info("Switching language to: %s" % action.text())
        self.uiTranslator.load(":/languages/tr_%s.qm" % self.current_language)
        self.app.installTranslator(self.uiTranslator)

        self.retranslateFreeseerApp()
        self.aboutDialog.aboutWidget.retranslate(self.current_language)
        self.retranslate()
        self.logDialog.retranslate()

    def retranslate(self):
        """
        Reimplement this function to provide translations to your app.
        """
        pass

    def retranslateFreeseerApp(self):
        #
        # Menubar
        #
        self.menuFile.setTitle(self.app.translate("FreeseerApp", "&File"))
        self.menuLanguage.setTitle(
            self.app.translate("FreeseerApp", "&Language"))
        self.menuHelp.setTitle(self.app.translate("FreeseerApp", "&Help"))

        self.actionExit.setText(self.app.translate("FreeseerApp", "&Quit"))
        self.actionAbout.setText(self.app.translate("FreeseerApp", "&About"))
        self.actionLog.setText(self.app.translate("FreeseerApp", "View &Log"))
        self.actionOnlineHelp.setText(
            self.app.translate("FreeseerApp", "Online Documentation"))
        # --- Menubar

    def setupLanguageMenu(self):
        self.languages = QDir(":/languages").entryList()

        if self.current_language is None:
            self.current_language = QLocale.system().name(
            )  # Retrieve Current Locale from the operating system.
            log.debug("Detected user's locale as %s" % self.current_language)

        for language in self.languages:
            translator = QTranslator(
            )  # Create a translator to translate Language Display Text.
            translator.load(":/languages/%s" % language)
            language_display_text = translator.translate(
                "Translation", "Language Display Text")

            languageAction = QAction(self)
            languageAction.setCheckable(True)
            languageAction.setText(language_display_text)
            languageAction.setData(language)
            self.menuLanguage.addAction(languageAction)
            self.langActionGroup.addAction(languageAction)
Example #36
0
class ProcessingPlugin:
    def __init__(self, iface):
        self.iface = iface

    def initGui(self):
        Processing.initialize()

        self.commander = None
        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        Processing.addAlgListListener(self.toolbox)

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = self.toolbox.toggleViewAction()
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QIcon(os.path.join(cmd_folder, 'images', 'alg.png')))
        self.toolboxAction.setText(self.tr('&Toolbox'))
        self.iface.registerMainWindowAction(self.toolboxAction, 'Ctrl+Alt+T')
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'model.png')),
            self.tr('Graphical &Modeler...'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction, 'Ctrl+Alt+M')
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'history.gif')),
            self.tr('&History...'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction, 'Ctrl+Alt+H')
        self.menu.addAction(self.historyAction)

        self.configAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'config.png')),
            self.tr('&Options...'), self.iface.mainWindow())
        self.configAction.setObjectName('configAction')
        self.configAction.triggered.connect(self.openConfig)
        self.iface.registerMainWindowAction(self.configAction, 'Ctrl+Alt+C')
        self.menu.addAction(self.configAction)

        self.resultsAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'results.png')),
            self.tr('&Results Viewer...'), self.iface.mainWindow())
        self.resultsAction.setObjectName('resultsAction')
        self.resultsAction.triggered.connect(self.openResults)
        self.iface.registerMainWindowAction(self.resultsAction, 'Ctrl+Alt+R')
        self.menu.addAction(self.resultsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(),
                           self.menu)

        self.commanderAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'commander.png')),
            self.tr('&Commander'), self.iface.mainWindow())
        self.commanderAction.setObjectName('commanderAction')
        self.commanderAction.triggered.connect(self.openCommander)
        self.menu.addAction(self.commanderAction)
        self.iface.registerMainWindowAction(self.commanderAction,
                                            self.tr('Ctrl+Alt+M'))

    def unload(self):
        self.toolbox.setVisible(False)
        self.menu.deleteLater()

        # delete temporary output files
        folder = tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.commanderAction)

    def openCommander(self):
        if self.commander is None:
            self.commander = CommanderWindow(self.iface.mainWindow(),
                                             self.iface.mapCanvas())
            Processing.addAlgListListener(self.commander)
        self.commander.prepareGui()
        self.commander.show()

    def openToolbox(self):
        if self.toolbox.isVisible():
            self.toolbox.hide()
        else:
            self.toolbox.show()

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.show()
        dlg.exec_()
        if dlg.update:
            self.toolbox.updateProvider('model')

    def openResults(self):
        dlg = ResultsDialog()
        dlg.show()
        dlg.exec_()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def openConfig(self):
        dlg = ConfigDialog(self.toolbox)
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)
Example #37
0
class GdalTools:
    def __init__(self, iface):
        if not valid:
            return

        # Save reference to the QGIS interface
        self.iface = iface
        try:
            self.QgisVersion = unicode(QGis.QGIS_VERSION_INT)
        except:
            self.QgisVersion = unicode(QGis.qgisVersion)[0]

        if QGis.QGIS_VERSION[0:3] < "1.5":
            # For i18n support
            userPluginPath = qgis.utils.home_plugin_path + "/GdalTools"
            systemPluginPath = qgis.utils.sys_plugin_path + "/GdalTools"

            overrideLocale = QSettings().value("locale/overrideFlag",
                                               False,
                                               type=bool)
            if not overrideLocale:
                localeFullName = QLocale.system().name()
            else:
                localeFullName = QSettings().value("locale/userLocale",
                                                   "",
                                                   type=str)

            if QFileInfo(userPluginPath).exists():
                translationPath = userPluginPath + "/i18n/GdalTools_" + localeFullName + ".qm"
            else:
                translationPath = systemPluginPath + "/i18n/GdalTools_" + 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):
        if not valid:
            return
        if int(self.QgisVersion) < 1:
            QMessageBox.warning(
                self.iface.getMainWindow(), "Gdal Tools",
                QCoreApplication.translate("GdalTools",
                                           "QGIS version detected: ") +
                unicode(self.QgisVersion) + ".xx\n" +
                QCoreApplication.translate(
                    "GdalTools",
                    "This version of Gdal Tools requires at least QGIS version 1.0.0\nPlugin will not be enabled."
                ))
            return None

        from tools.GdalTools_utils import GdalConfig, LayerRegistry
        self.GdalVersionNum = GdalConfig.versionNum()
        LayerRegistry.setIface(self.iface)

        # find the Raster menu
        rasterMenu = None
        menu_bar = self.iface.mainWindow().menuBar()
        actions = menu_bar.actions()

        rasterText = QCoreApplication.translate("QgisApp", "&Raster")

        for a in actions:
            if a.menu() is not None and a.menu().title() == rasterText:
                rasterMenu = a.menu()
                break

        if rasterMenu is None:
            # no Raster menu, create and insert it before the Help menu
            self.menu = QMenu(rasterText, self.iface.mainWindow())
            lastAction = actions[len(actions) - 1]
            menu_bar.insertMenu(lastAction, self.menu)
        else:
            self.menu = rasterMenu
            self.menu.addSeparator()

        # projections menu (Warp (Reproject), Assign projection)
        self.projectionsMenu = QMenu(
            QCoreApplication.translate("GdalTools", "Projections"),
            self.iface.mainWindow())
        self.projectionsMenu.setObjectName("projectionsMenu")

        self.warp = QAction(
            QIcon(":/icons/warp.png"),
            QCoreApplication.translate("GdalTools", "Warp (Reproject)..."),
            self.iface.mainWindow())
        self.warp.setObjectName("warp")
        self.warp.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Warp an image into a new coordinate system"))
        QObject.connect(self.warp, SIGNAL("triggered()"), self.doWarp)

        self.projection = QAction(
            QIcon(":icons/projection-add.png"),
            QCoreApplication.translate("GdalTools", "Assign Projection..."),
            self.iface.mainWindow())
        self.projection.setObjectName("projection")
        self.projection.setStatusTip(
            QCoreApplication.translate("GdalTools",
                                       "Add projection info to the raster"))
        QObject.connect(self.projection, SIGNAL("triggered()"),
                        self.doProjection)

        self.extractProj = QAction(
            QIcon(":icons/projection-export.png"),
            QCoreApplication.translate("GdalTools", "Extract Projection..."),
            self.iface.mainWindow())
        self.extractProj.setObjectName("extractProj")
        self.extractProj.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Extract projection information from raster(s)"))
        QObject.connect(self.extractProj, SIGNAL("triggered()"),
                        self.doExtractProj)

        self.projectionsMenu.addActions(
            [self.warp, self.projection, self.extractProj])

        # conversion menu (Rasterize (Vector to raster), Polygonize (Raster to vector), Translate, RGB to PCT, PCT to RGB)
        self.conversionMenu = QMenu(
            QCoreApplication.translate("GdalTools", "Conversion"),
            self.iface.mainWindow())
        self.conversionMenu.setObjectName("conversionMenu")

        if self.GdalVersionNum >= 1300:
            self.rasterize = QAction(
                QIcon(":/icons/rasterize.png"),
                QCoreApplication.translate("GdalTools",
                                           "Rasterize (Vector to Raster)..."),
                self.iface.mainWindow())
            self.rasterize.setObjectName("rasterize")
            self.rasterize.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools", "Burns vector geometries into a raster"))
            QObject.connect(self.rasterize, SIGNAL("triggered()"),
                            self.doRasterize)
            self.conversionMenu.addAction(self.rasterize)

        if self.GdalVersionNum >= 1600:
            self.polygonize = QAction(
                QIcon(":/icons/polygonize.png"),
                QCoreApplication.translate("GdalTools",
                                           "Polygonize (Raster to Vector)..."),
                self.iface.mainWindow())
            self.polygonize.setObjectName("polygonize")
            self.polygonize.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools",
                    "Produces a polygon feature layer from a raster"))
            QObject.connect(self.polygonize, SIGNAL("triggered()"),
                            self.doPolygonize)
            self.conversionMenu.addAction(self.polygonize)

        self.translate = QAction(
            QIcon(":/icons/translate.png"),
            QCoreApplication.translate("GdalTools",
                                       "Translate (Convert Format)..."),
            self.iface.mainWindow())
        self.translate.setObjectName("translate")
        self.translate.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Converts raster data between different formats"))
        QObject.connect(self.translate, SIGNAL("triggered()"),
                        self.doTranslate)

        self.paletted = QAction(
            QIcon(":icons/24-to-8-bits.png"),
            QCoreApplication.translate("GdalTools", "RGB to PCT..."),
            self.iface.mainWindow())
        self.paletted.setObjectName("paletted")
        self.paletted.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Convert a 24bit RGB image to 8bit paletted"))
        QObject.connect(self.paletted, SIGNAL("triggered()"), self.doPaletted)

        self.rgb = QAction(
            QIcon(":icons/8-to-24-bits.png"),
            QCoreApplication.translate("GdalTools", "PCT to RGB..."),
            self.iface.mainWindow())
        self.rgb.setObjectName("rgb")
        self.rgb.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Convert an 8bit paletted image to 24bit RGB"))
        QObject.connect(self.rgb, SIGNAL("triggered()"), self.doRGB)

        self.conversionMenu.addActions(
            [self.translate, self.paletted, self.rgb])

        # extraction menu (Clipper, Contour)
        self.extractionMenu = QMenu(
            QCoreApplication.translate("GdalTools", "Extraction"),
            self.iface.mainWindow())
        self.extractionMenu.setObjectName("extractionMenu")

        if self.GdalVersionNum >= 1600:
            self.contour = QAction(
                QIcon(":/icons/contour.png"),
                QCoreApplication.translate("GdalTools", "Contour..."),
                self.iface.mainWindow())
            self.contour.setObjectName("contour")
            self.contour.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools", "Builds vector contour lines from a DEM"))
            QObject.connect(self.contour, SIGNAL("triggered()"),
                            self.doContour)
            self.extractionMenu.addAction(self.contour)

        self.clipper = QAction(
            QIcon(":icons/raster-clip.png"),
            QCoreApplication.translate("GdalTools", "Clipper..."),
            self.iface.mainWindow())
        self.clipper.setObjectName("clipper")
        #self.clipper.setStatusTip( QCoreApplication.translate( "GdalTools", "Converts raster data between different formats") )
        QObject.connect(self.clipper, SIGNAL("triggered()"), self.doClipper)

        self.extractionMenu.addActions([self.clipper])

        # analysis menu (DEM (Terrain model), Grid (Interpolation), Near black, Proximity (Raster distance), Sieve)
        self.analysisMenu = QMenu(
            QCoreApplication.translate("GdalTools", "Analysis"),
            self.iface.mainWindow())
        self.analysisMenu.setObjectName("analysisMenu")

        if self.GdalVersionNum >= 1600:
            self.sieve = QAction(
                QIcon(":/icons/sieve.png"),
                QCoreApplication.translate("GdalTools", "Sieve..."),
                self.iface.mainWindow())
            self.sieve.setObjectName("sieve")
            self.sieve.setStatusTip(
                QCoreApplication.translate("GdalTools",
                                           "Removes small raster polygons"))
            QObject.connect(self.sieve, SIGNAL("triggered()"), self.doSieve)
            self.analysisMenu.addAction(self.sieve)

        if self.GdalVersionNum >= 1500:
            self.nearBlack = QAction(
                QIcon(":/icons/nearblack.png"),
                QCoreApplication.translate("GdalTools", "Near Black..."),
                self.iface.mainWindow())
            self.nearBlack.setObjectName("nearBlack")
            self.nearBlack.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools",
                    "Convert nearly black/white borders to exact value"))
            QObject.connect(self.nearBlack, SIGNAL("triggered()"),
                            self.doNearBlack)
            self.analysisMenu.addAction(self.nearBlack)

        if self.GdalVersionNum >= 1700:
            self.fillNodata = QAction(
                QIcon(":/icons/fillnodata.png"),
                QCoreApplication.translate("GdalTools", "Fill nodata..."),
                self.iface.mainWindow())
            self.fillNodata.setObjectName("fillNodata")
            self.fillNodata.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools",
                    "Fill raster regions by interpolation from edges"))
            QObject.connect(self.fillNodata, SIGNAL("triggered()"),
                            self.doFillNodata)
            self.analysisMenu.addAction(self.fillNodata)

        if self.GdalVersionNum >= 1600:
            self.proximity = QAction(
                QIcon(":/icons/proximity.png"),
                QCoreApplication.translate("GdalTools",
                                           "Proximity (Raster Distance)..."),
                self.iface.mainWindow())
            self.proximity.setObjectName("proximity")
            self.proximity.setStatusTip(
                QCoreApplication.translate("GdalTools",
                                           "Produces a raster proximity map"))
            QObject.connect(self.proximity, SIGNAL("triggered()"),
                            self.doProximity)
            self.analysisMenu.addAction(self.proximity)

        if self.GdalVersionNum >= 1500:
            self.grid = QAction(
                QIcon(":/icons/grid.png"),
                QCoreApplication.translate("GdalTools",
                                           "Grid (Interpolation)..."),
                self.iface.mainWindow())
            self.grid.setObjectName("grid")
            self.grid.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools", "Create raster from the scattered data"))
            QObject.connect(self.grid, SIGNAL("triggered()"), self.doGrid)
            self.analysisMenu.addAction(self.grid)

        if self.GdalVersionNum >= 1700:
            self.dem = QAction(
                QIcon(":icons/dem.png"),
                QCoreApplication.translate("GdalTools",
                                           "DEM (Terrain Models)..."),
                self.iface.mainWindow())
            self.dem.setObjectName("dem")
            self.dem.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools", "Tool to analyze and visualize DEMs"))
            QObject.connect(self.dem, SIGNAL("triggered()"), self.doDEM)
            self.analysisMenu.addAction(self.dem)

        #self.analysisMenu.addActions( [  ] )

        # miscellaneous menu (Build overviews (Pyramids), Tile index, Information, Merge, Build Virtual Raster (Catalog))
        self.miscellaneousMenu = QMenu(
            QCoreApplication.translate("GdalTools", "Miscellaneous"),
            self.iface.mainWindow())
        self.miscellaneousMenu.setObjectName("miscellaneousMenu")

        if self.GdalVersionNum >= 1600:
            self.buildVRT = QAction(
                QIcon(":/icons/vrt.png"),
                QCoreApplication.translate(
                    "GdalTools", "Build Virtual Raster (Catalog)..."),
                self.iface.mainWindow())
            self.buildVRT.setObjectName("buildVRT")
            self.buildVRT.setStatusTip(
                QCoreApplication.translate(
                    "GdalTools", "Builds a VRT from a list of datasets"))
            QObject.connect(self.buildVRT, SIGNAL("triggered()"),
                            self.doBuildVRT)
            self.miscellaneousMenu.addAction(self.buildVRT)

        self.merge = QAction(
            QIcon(":/icons/merge.png"),
            QCoreApplication.translate("GdalTools", "Merge..."),
            self.iface.mainWindow())
        self.merge.setObjectName("merge")
        self.merge.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Build a quick mosaic from a set of images"))
        QObject.connect(self.merge, SIGNAL("triggered()"), self.doMerge)

        self.info = QAction(
            QIcon(":/icons/raster-info.png"),
            QCoreApplication.translate("GdalTools", "Information..."),
            self.iface.mainWindow())
        self.info.setObjectName("info")
        self.info.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Lists information about raster dataset"))
        QObject.connect(self.info, SIGNAL("triggered()"), self.doInfo)

        self.overview = QAction(
            QIcon(":icons/raster-overview.png"),
            QCoreApplication.translate("GdalTools",
                                       "Build Overviews (Pyramids)..."),
            self.iface.mainWindow())
        self.overview.setObjectName("overview")
        self.overview.setStatusTip(
            QCoreApplication.translate("GdalTools",
                                       "Builds or rebuilds overview images"))
        QObject.connect(self.overview, SIGNAL("triggered()"), self.doOverview)

        self.tileindex = QAction(
            QIcon(":icons/tiles.png"),
            QCoreApplication.translate("GdalTools", "Tile Index..."),
            self.iface.mainWindow())
        self.tileindex.setObjectName("tileindex")
        self.tileindex.setStatusTip(
            QCoreApplication.translate(
                "GdalTools", "Build a shapefile as a raster tileindex"))
        QObject.connect(self.tileindex, SIGNAL("triggered()"),
                        self.doTileIndex)

        self.miscellaneousMenu.addActions(
            [self.merge, self.info, self.overview, self.tileindex])

        self.menu.addMenu(self.projectionsMenu)
        self.menu.addMenu(self.conversionMenu)
        self.menu.addMenu(self.extractionMenu)

        if not self.analysisMenu.isEmpty():
            self.menu.addMenu(self.analysisMenu)

        self.menu.addMenu(self.miscellaneousMenu)

        self.settings = QAction(
            QCoreApplication.translate("GdalTools", "GdalTools Settings..."),
            self.iface.mainWindow())
        self.settings.setObjectName("settings")
        self.settings.setStatusTip(
            QCoreApplication.translate("GdalTools",
                                       "Various settings for Gdal Tools"))
        QObject.connect(self.settings, SIGNAL("triggered()"), self.doSettings)
        self.menu.addAction(self.settings)

    def unload(self):
        if not valid:
            return
        pass

    def doBuildVRT(self):
        from tools.doBuildVRT import GdalToolsDialog as BuildVRT
        d = BuildVRT(self.iface)
        self.runToolDialog(d)

    def doContour(self):
        from tools.doContour import GdalToolsDialog as Contour
        d = Contour(self.iface)
        self.runToolDialog(d)

    def doRasterize(self):
        from tools.doRasterize import GdalToolsDialog as Rasterize
        d = Rasterize(self.iface)
        self.runToolDialog(d)

    def doPolygonize(self):
        from tools.doPolygonize import GdalToolsDialog as Polygonize
        d = Polygonize(self.iface)
        self.runToolDialog(d)

    def doMerge(self):
        from tools.doMerge import GdalToolsDialog as Merge
        d = Merge(self.iface)
        self.runToolDialog(d)

    def doSieve(self):
        from tools.doSieve import GdalToolsDialog as Sieve
        d = Sieve(self.iface)
        self.runToolDialog(d)

    def doProximity(self):
        from tools.doProximity import GdalToolsDialog as Proximity
        d = Proximity(self.iface)
        self.runToolDialog(d)

    def doNearBlack(self):
        from tools.doNearBlack import GdalToolsDialog as NearBlack
        d = NearBlack(self.iface)
        self.runToolDialog(d)

    def doFillNodata(self):
        from tools.doFillNodata import GdalToolsDialog as FillNodata
        d = FillNodata(self.iface)
        self.runToolDialog(d)

    def doWarp(self):
        from tools.doWarp import GdalToolsDialog as Warp
        d = Warp(self.iface)
        self.runToolDialog(d)

    def doGrid(self):
        from tools.doGrid import GdalToolsDialog as Grid
        d = Grid(self.iface)
        self.runToolDialog(d)

    def doTranslate(self):
        from tools.doTranslate import GdalToolsDialog as Translate
        d = Translate(self.iface)
        self.runToolDialog(d)

    def doInfo(self):
        from tools.doInfo import GdalToolsDialog as Info
        d = Info(self.iface)
        self.runToolDialog(d)

    def doProjection(self):
        from tools.doProjection import GdalToolsDialog as Projection
        d = Projection(self.iface)
        self.runToolDialog(d)

    def doOverview(self):
        from tools.doOverview import GdalToolsDialog as Overview
        d = Overview(self.iface)
        self.runToolDialog(d)

    def doClipper(self):
        from tools.doClipper import GdalToolsDialog as Clipper
        d = Clipper(self.iface)
        self.runToolDialog(d)

    def doPaletted(self):
        from tools.doRgbPct import GdalToolsDialog as RgbPct
        d = RgbPct(self.iface)
        self.runToolDialog(d)

    def doRGB(self):
        from tools.doPctRgb import GdalToolsDialog as PctRgb
        d = PctRgb(self.iface)
        self.runToolDialog(d)

    def doTileIndex(self):
        from tools.doTileIndex import GdalToolsDialog as TileIndex
        d = TileIndex(self.iface)
        self.runToolDialog(d)

    def doExtractProj(self):
        from tools.doExtractProj import GdalToolsDialog as ExtractProj
        d = ExtractProj(self.iface)
        d.exec_()

    def doDEM(self):
        from tools.doDEM import GdalToolsDialog as DEM
        d = DEM(self.iface)
        self.runToolDialog(d)

    def runToolDialog(self, dlg):
        dlg.show_()
        dlg.exec_()
        del dlg

    def doSettings(self):
        from tools.doSettings import GdalToolsSettingsDialog as Settings
        d = Settings(self.iface)
        d.exec_()
Example #38
0
class Plugin(object):
    """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
        self.action_import_dialog = None
        self.action_save_scenario = None
        self.action_batch_runner = None
        self.action_shake_converter = None
        self.action_minimum_needs = None
        self.action_global_minimum_needs = None
        self.action_impact_merge_dlg = None
        self.key_action = None
        self.action_options = None
        self.action_keywords_dialog = None
        self.action_keywords_wizard = None
        self.action_function_centric_wizard = None
        self.action_extent_selector = None
        self.translator = None
        self.toolbar = None
        self.actions = []  # list of all QActions we create for InaSAFE
        self.action_dock = None
        self.action_toggle_rubberbands = None
        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)

    # noinspection PyArgumentList
    def change_i18n(self, new_locale):
        """Change internationalisation for the plugin.

        Override the system locale  and then see if we can get a valid
        translation file for whatever locale is effectively being used.

        :param new_locale: the new locale i.e. 'id', 'af', etc.
        :type new_locale: str

        :raises: TranslationLoadException
        """

        os.environ['INASAFE_LANG'] = str(new_locale)

        LOGGER.debug('%s %s %s' % (
            new_locale, QLocale.system().name(), os.environ['INASAFE_LANG']))

        root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        translation_path = os.path.join(
            root, 'safe_qgis', 'i18n',
            'inasafe_' + str(new_locale) + '.qm')

        if os.path.exists(translation_path):
            self.translator = QTranslator()
            result = self.translator.load(translation_path)
            if not result:
                message = 'Failed to load translation for %s' % new_locale
                raise TranslationLoadError(message)
            # noinspection PyTypeChecker,PyCallByClass
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' % (
            translation_path, os.path.exists(translation_path)))

    # 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 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

        """
        # 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)

    # 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')
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe.gui.widgets.dock import Dock

        self.dock_widget = None
        # --------------------------------------
        # 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 editor
        # --------------------------------------
        icon = resources_path('img', 'icons', 'show-keyword-editor.svg')
        self.action_keywords_dialog = QAction(
            QIcon(icon),
            self.tr('InaSAFE Keyword Editor'),
            self.iface.mainWindow())
        self.action_keywords_dialog.setStatusTip(self.tr(
            'Open InaSAFE keywords editor'))
        self.action_keywords_dialog.setWhatsThis(self.tr(
            'Open InaSAFE keywords editor'))
        self.action_keywords_dialog.setEnabled(False)

        self.action_keywords_dialog.triggered.connect(
            self.show_keywords_editor)

        self.add_action(
            self.action_keywords_dialog, add_to_toolbar=self.full_toolbar)

        # --------------------------------------
        # Create action for keywords creation wizard
        # -------------------------------------
        icon = resources_path('img', 'icons', 'show-keyword-wizard.svg')
        self.action_keywords_wizard = QAction(
            QIcon(icon),
            self.tr('InaSAFE 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)

        # --------------------------------------
        # Create action for IF-centric wizard
        # --------------------------------------
        icon = resources_path('img', 'icons', 'show-wizard.svg')
        self.action_function_centric_wizard = QAction(
            QIcon(icon),
            self.tr('InaSAFE 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)

        # --------------------------------------
        # Create action for options dialog
        # --------------------------------------
        icon = resources_path('img', 'icons', 'configure-inasafe.svg')
        self.action_options = QAction(
            QIcon(icon),
            self.tr('InaSAFE 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)
        # ---------------------------------------
        # Create action for minimum needs dialog
        # ---------------------------------------
        icon = resources_path('img', 'icons', 'show-minimum-needs.svg')
        self.action_minimum_needs = QAction(
            QIcon(icon),
            self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow())
        self.action_minimum_needs.setStatusTip(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.action_minimum_needs.setWhatsThis(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.action_minimum_needs.triggered.connect(self.show_minimum_needs)

        self.add_action(
            self.action_minimum_needs, add_to_toolbar=self.full_toolbar)

        # ----------------------------------------------
        # Create action for global minimum needs dialog
        # ----------------------------------------------
        icon = resources_path('img', 'icons', 'show-global-minimum-needs.svg')
        self.action_global_minimum_needs = QAction(
            QIcon(icon),
            self.tr('InaSAFE Global Minimum Needs Configuration'),
            self.iface.mainWindow())
        self.action_global_minimum_needs.setStatusTip(self.tr(
            'Open InaSAFE global minimum needs configuration'))
        self.action_global_minimum_needs.setWhatsThis(self.tr(
            'Open InaSAFE global minimum needs configuration'))
        self.action_global_minimum_needs.triggered.connect(
            self.show_global_minimum_needs_configuration)

        self.add_action(
            self.action_global_minimum_needs, add_to_toolbar=self.full_toolbar)

        # ---------------------------------------
        # Create action for converter dialog
        # ---------------------------------------
        icon = resources_path('img', 'icons', 'show-converter-tool.svg')
        self.action_shake_converter = QAction(
            QIcon(icon),
            self.tr('InaSAFE 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)

        # ---------------------------------------
        # Create action for batch runner dialog
        # ---------------------------------------
        icon = resources_path('img', 'icons', 'show-batch-runner.svg')
        self.action_batch_runner = QAction(
            QIcon(icon),
            self.tr('InaSAFE Batch Runner'), self.iface.mainWindow())
        self.action_batch_runner.setStatusTip(self.tr(
            'Open InaSAFE Batch Runner'))
        self.action_batch_runner.setWhatsThis(self.tr(
            'Open InaSAFE 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)

        # ---------------------------------------
        # 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)

        # --------------------------------------
        # Create action for import OSM Dialog
        # --------------------------------------
        icon = resources_path('img', 'icons', 'show-osm-download.svg')
        self.action_import_dialog = QAction(
            QIcon(icon),
            self.tr('InaSAFE OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.action_import_dialog.setStatusTip(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.action_import_dialog.setWhatsThis(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.action_import_dialog.triggered.connect(self.show_osm_downloader)

        self.add_action(self.action_import_dialog)

        # --------------------------------------
        # Create action for impact layer merge Dialog
        # --------------------------------------
        icon = resources_path('img', 'icons', 'show-impact-merge.svg')
        self.action_impact_merge_dlg = QAction(
            QIcon(icon),
            self.tr('InaSAFE Impact Layer Merge'),
            self.iface.mainWindow())
        self.action_impact_merge_dlg.setStatusTip(self.tr(
            'InaSAFE Impact Layer Merge'))
        self.action_impact_merge_dlg.setWhatsThis(self.tr(
            'InaSAFE Impact Layer Merge'))
        self.action_impact_merge_dlg.triggered.connect(self.show_impact_merge)

        self.add_action(
            self.action_impact_merge_dlg, add_to_toolbar=self.full_toolbar)

        # --------------------------------------
        # create dockwidget and tabify it with the legend
        # --------------------------------------

        self.dock_widget = Dock(self.iface)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget)
        myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend')

        if myLegendTab:
            self.iface.mainWindow().tabifyDockWidget(
                myLegendTab, self.dock_widget)
            self.dock_widget.raise_()

        #
        # 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())

        # pylint: disable=W0201

        # ---------------------------------------
        # 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 scenarion extents.')
        self.action_toggle_rubberbands.setStatusTip(message)
        self.action_toggle_rubberbands.setWhatsThis(message)
        # Set initial state
        self.action_toggle_rubberbands.setCheckable(True)
        settings = QSettings()
        flag = bool(settings.value(
            'inasafe/showRubberBands', False, 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)

        # ---------------------------------------
        # 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 the analysis area for InaSAFE'),
            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)

    # noinspection PyMethodMayBeStatic
    def clear_modules(self):
        """Unload inasafe functions and try to return QGIS to before InaSAFE.
        """
        from safe.impact_functions import core

        core.unload_plugins()
        # 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
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(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)

    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 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.user_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)
        # 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.show()  # non modal

    def show_global_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(self.iface.mainWindow())
        dialog.exec_()  # modal

    def show_impact_merge(self):
        """Show the impact layer merge dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.impact_merge_dialog import ImpactMergeDialog

        dialog = ImpactMergeDialog(self.iface.mainWindow())
        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(
            self.iface,
            self.dock_widget,
            self.iface.mainWindow())
        dialog.exec_()  # modal

    def show_keywords_editor(self):
        """Show the keywords editor."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.keywords_dialog import KeywordsDialog

        # Next block is a fix for #776
        if self.iface.activeLayer() is None:
            return

        try:
            keyword_io = KeywordIO()
            keyword_io.read_keywords(self.iface.activeLayer())
        except UnsupportedProviderError:
            # noinspection PyUnresolvedReferences,PyCallByClass
            # noinspection PyTypeChecker,PyArgumentList
            QMessageBox.warning(
                None,
                self.tr('Unsupported layer type'),
                self.tr(
                    'The layer you have selected cannot be used for '
                    'analysis because its data type is unsupported.'))
            return
        # End of fix for #776
        # Fix for #793
        except NoKeywordsFoundError:
            # we will create them from scratch in the dialog
            pass
        # End of fix for #793
        # Fix for filtered-layer
        except InvalidParameterError, e:
            # noinspection PyTypeChecker,PyTypeChecker,PyArgumentList
            QMessageBox.warning(
                None,
                self.tr('Invalid Layer'),
                e.message
            )
            return

        dialog = KeywordsDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dock_widget)
        dialog.exec_()  # modal
class Kortforsyningen:
    """QGIS Plugin Implementation."""

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        self.settings = KFSettings()
        
        path = QFileInfo(os.path.realpath(__file__)).path()
        kf_path = path + '/kf/'
        if not os.path.exists(kf_path):
            os.makedirs(kf_path)
            
        self.settings.addSetting('cache_path', 'string', 'global', kf_path)
        self.settings.addSetting('kf_qlr_url', 'string', 'global', CONFIG_FILE_URL)

        self.local_about_file = kf_path + 'about.html'

        # Categories
        self.categories = []
        self.nodes_by_index = {}
        self.node_count = 0

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
             path,
            'i18n',
            '{}.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)

        self.networkManager = QNetworkAccessManager()

    def initGui(self):
        self.config = Config(self.settings, self.networkManager)
        self.config.con_loaded.connect(self.createMenu)
        self.config.kf_con_error.connect(self.show_kf_error)
        self.config.kf_settings_warning.connect(self.show_kf_settings_warning)
        self.config.load()
        
    def show_kf_error(self, error_message):
        log_message(error_message)
        message = u'Check connection and click menu Kortforsyningen->Settings->OK'
        self.iface.messageBar().pushMessage(error_message, message, level=QgsMessageBar.WARNING, duration=10)

    def show_kf_settings_warning(self):
            widget = self.iface.messageBar().createMessage(
                self.tr('Kortforsyningen'), self.tr(u'Username/Password not set or wrong. Click menu Kortforsyningen->Settings')
            )
            settings_btn = QPushButton(widget)
            settings_btn.setText(self.tr("Settings"))
            settings_btn.pressed.connect(self.settings_dialog)
            widget.layout().addWidget(settings_btn)
            self.iface.messageBar().pushWidget(widget, QgsMessageBar.WARNING, duration=10)

    def createMenu(self):
        self.categories = self.config.get_categories()
        self.category_lists = self.config.get_category_lists()
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/Kortforsyningen/settings-cog.png'
        icon_path_info = ':/plugins/Kortforsyningen/icon_about.png'

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName(self.tr('Kortforsyningen'))
        self.menu.setTitle(self.tr('Kortforsyningen'))
        
        searchable_layers = []

        # Add menu object for each theme
        self.category_menus = []
        kf_helper = lambda _id: lambda: self.open_kf_node(_id)
        local_helper = lambda _id: lambda: self.open_local_node(_id)
        
        for category_list in self.category_lists:
            list_categorymenus = []
            for category in category_list:
                category_menu = QMenu()
                category_menu.setTitle(category['name'])
                for selectable in category['selectables']:
                    q_action = QAction(
                        selectable['name'], self.iface.mainWindow()
                    )
                    if selectable['source'] == 'kf':
                        q_action.triggered.connect(
                            kf_helper(selectable['id'])
                        )
                    else:
                        q_action.triggered.connect(
                            local_helper(selectable['id'])
                        )
                    category_menu.addAction(q_action)
                    searchable_layers.append(
                        {
                            'title': selectable['name'],
                            'category': category['name'],
                            'action': q_action
                        }
                    )
                list_categorymenus.append(category_menu)
                self.category_menus.append(category_menu)
            for category_menukuf in list_categorymenus:
                self.menu.addMenu(category_menukuf)
            self.menu.addSeparator()
        self.septimasearchprovider = MySeptimaSearchProvider(self, searchable_layers)

        # Add settings
        self.settings_menu = QAction(
            QIcon(icon_path),
            self.tr('Settings'),
            self.iface.mainWindow()
        )
        self.settings_menu.setObjectName(self.tr('Settings'))
        self.settings_menu.triggered.connect(self.settings_dialog)
        self.menu.addAction(self.settings_menu)

        # Add about
        self.about_menu = QAction(
            QIcon(icon_path_info),
            self.tr('About the plugin'),
            self.iface.mainWindow()
        )
        self.about_menu.setObjectName(self.tr('About the plugin'))
        self.about_menu.triggered.connect(self.about_dialog)
        self.menu.addAction(self.about_menu)

        menu_bar = self.iface.mainWindow().menuBar()
        menu_bar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu
        )
        
    def open_local_node(self, id):
        node = self.config.get_local_maplayer_node(id)
        self.open_node(node, id)

    def open_kf_node(self, id):
        node = self.config.get_kf_maplayer_node(id)
        layer = self.open_node(node, id)

    def open_node(self, node, id):
        QgsProject.instance().read(node)
        layer = QgsMapLayerRegistry.instance().mapLayer(id)
        if layer:
            self.iface.legendInterface().refreshLayerSymbology(layer)
            #self.iface.legendInterface().moveLayer(layer, 0)
            self.iface.legendInterface().refreshLayerSymbology(layer)
            return layer
        else:
            return None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Kortforsyningen', message)

    def settings_dialog(self):
        dlg = KFSettingsDialog(self.settings)
        dlg.setWidgetsFromValues()
        dlg.show()
        result = dlg.exec_()

        if result == 1:
            del dlg
            self.reloadMenu()

    def about_dialog(self):
        if 'KFAboutDialog' in globals():
            dlg = KFAboutDialog()
            dlg.webView.setUrl(QUrl(ABOUT_FILE_URL))
            dlg.webView.urlChanged
            dlg.show()
            result = dlg.exec_()

            if result == 1:
                del dlg
        else:
            dlg = KFAlternativeAboutDialog()
            dlg.buttonBox.accepted.connect(dlg.accept)
            dlg.buttonBox.rejected.connect(dlg.reject)
            dlg.textBrowser.setHtml(self.tr('<p>QGIS is having trouble showing the content of this dialog. Would you like to open it in an external browser window?</p>'))
            dlg.show()
            result = dlg.exec_()

            if result:
                webbrowser.open(ABOUT_FILE_URL)

    def unload(self):
        # Remove settings if user not asked to keep them
        if self.settings.value('remember_settings') is False:
            self.settings.setValue('username', '')
            self.settings.setValue('password', '')
        self.clearMenu();
        
    def reloadMenu(self):
        self.clearMenu()
        self.config.load()
        #self.createMenu()
    
    def clearMenu(self):
        # Remove the submenus
        for submenu in self.category_menus:
            if submenu:
                submenu.deleteLater()
        # remove the menu bar item
        if self.menu:
            self.menu.deleteLater()
Example #40
0
class ReportEditorApp(FreeseerApp):
    '''
    Freeseer report editor main gui class
    '''

    def __init__(self, config, db):
        FreeseerApp.__init__(self)

        self.config = config
        self.db = db

        icon = QIcon()
        icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(960, 400)

        self.mainWidget = QWidget()
        self.mainLayout = QHBoxLayout()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)

        self.editorWidget = ReportEditorWidget()
        self.editorWidget.editor.setColumnHidden(5, True)

        self.mainLayout.addWidget(self.editorWidget)

        # Initialize geometry, to be used for restoring window positioning.
        self.geometry = None

        #
        # Setup Menubar
        #
        self.actionExportCsv = QAction(self)
        self.actionExportCsv.setObjectName(_fromUtf8("actionExportCsv"))

        # Actions
        self.menuFile.insertAction(self.actionExit, self.actionExportCsv)
        # --- End Menubar

        #
        # Report Editor Connections
        #

        # Editor Widget
        self.connect(self.editorWidget.removeButton, SIGNAL('clicked()'), self.remove_talk)
        self.connect(self.editorWidget.clearButton, SIGNAL('clicked()'), self.confirm_reset)
        self.connect(self.editorWidget.closeButton, SIGNAL('clicked()'), self.close)

        # Main Window Connections
        self.connect(self.actionExportCsv, SIGNAL('triggered()'), self.export_reports_to_csv)
        self.connect(self.editorWidget.editor, SIGNAL('clicked (const QModelIndex&)'), self.editorSelectionChanged)

        # Load default language
        actions = self.menuLanguage.actions()
        for action in actions:
            if action.data().toString() == self.config.default_language:
                action.setChecked(True)
                self.translate(action)
                break

        self.load_failures_model()
        self.editorWidget.editor.resizeColumnsToContents()
        self.editorWidget.editor.resizeRowsToContents()

    ###
    ### Translation
    ###
    def retranslate(self):
        self.setWindowTitle(self.app.translate("ReportEditorApp", "Freeseer Report Editor"))

        #
        # Reusable Strings
        #
        self.confirmDBClearTitleString = self.app.translate("ReportEditorApp", "Clear Database")
        self.confirmDBClearQuestionString = self.app.translate("ReportEditorApp", "Are you sure you want to clear the DB?")
        self.selectFileString = self.app.translate("ReportEditorApp", "Select File")
        # --- End Reusable Strings

        #
        # Menubar
        #
        self.actionExportCsv.setText(self.app.translate("ReportEditorApp", "&Export to CSV"))
        # --- End Menubar

        #
        # EditorWidget
        #
        self.editorWidget.removeButton.setText(self.app.translate("ReportEditorApp", "Remove"))
        self.editorWidget.clearButton.setText(self.app.translate("ReportEditorApp", "Clear"))
        self.editorWidget.closeButton.setText(self.app.translate("ReportEditorApp", "Close"))

        self.editorWidget.titleLabel.setText(self.app.translate("ReportEditorApp", "Title:"))
        self.editorWidget.speakerLabel.setText(self.app.translate("ReportEditorApp", "Speaker:"))
        self.editorWidget.descriptionLabel.setText(self.app.translate("ReportEditorApp", "Description:"))
        self.editorWidget.levelLabel.setText(self.app.translate("ReportEditorApp", "Level:"))
        self.editorWidget.eventLabel.setText(self.app.translate("ReportEditorApp", "Event:"))
        self.editorWidget.roomLabel.setText(self.app.translate("ReportEditorApp", "Room:"))
        self.editorWidget.timeLabel.setText(self.app.translate("ReportEditorApp", "Time:"))
        # --- End EditorWidget

    def load_failures_model(self):
        # Load Presentation Model
        self.failureModel = self.db.get_failures_model()
        editor = self.editorWidget.editor
        editor.setModel(self.failureModel)
        editor.horizontalHeader().setResizeMode(QHeaderView.Stretch)

    def hide_add_talk_widget(self):
        self.editorWidget.setHidden(False)
        self.addTalkWidget.setHidden(True)

    def add_talk(self):
        date = self.addTalkWidget.dateEdit.date()
        time = self.addTalkWidget.timeEdit.time()
        datetime = QDateTime(date, time)
        presentation = Presentation(unicode(self.addTalkWidget.titleLineEdit.text()),
                                    unicode(self.addTalkWidget.presenterLineEdit.text()),
                                    "",  # description
                                    "",  # level
                                    unicode(self.addTalkWidget.eventLineEdit.text()),
                                    unicode(self.addTalkWidget.roomLineEdit.text()),
                                    unicode(datetime.toString()))

        # Do not add talks if they are empty strings
        if (len(presentation.title) == 0):
            return

        self.db.insert_presentation(presentation)

        # cleanup
        self.addTalkWidget.titleLineEdit.clear()
        self.addTalkWidget.presenterLineEdit.clear()

        self.failureModel.select()

        self.hide_add_talk_widget()

    def remove_talk(self):
        try:
            row_clicked = self.editorWidget.editor.currentIndex().row()
        except:
            return

        self.failureModel.removeRow(row_clicked)
        self.failureModel.select()

    def reset(self):
        self.db.clear_report_db()
        self.failureModel.select()

    def confirm_reset(self):
        """
        Presents a confirmation dialog to ask the user if they are sure they
        wish to remove the report database.

        If Yes call the reset() function.
        """
        confirm = QMessageBox.question(self,
                    self.confirmDBClearTitleString,
                    self.confirmDBClearQuestionString,
                    QMessageBox.Yes |
                    QMessageBox.No,
                    QMessageBox.No)

        if confirm == QMessageBox.Yes:
            self.reset()

    def closeEvent(self, event):
        log.info('Exiting report editor...')
        self.geometry = self.saveGeometry()
        event.accept()

    def editorSelectionChanged(self, index):
        talkId = self.failureModel.record(index.row()).value(0).toString()
        self.updatePresentationInfo(talkId)

    def updatePresentationInfo(self, talkId):
        p = self.db.get_presentation(talkId)
        if p is not None:
            self.editorWidget.titleLabel2.setText(p.title)
            self.editorWidget.speakerLabel2.setText(p.speaker)
            self.editorWidget.descriptionLabel2.setText(p.description)
            self.editorWidget.levelLabel2.setText(p.level)
            self.editorWidget.eventLabel2.setText(p.event)
            self.editorWidget.roomLabel2.setText(p.room)
            self.editorWidget.timeLabel2.setText(p.time)
        else:
            self.editorWidget.titleLabel2.setText("Talk not found")
            self.editorWidget.speakerLabel2.setText("Talk not found")
            self.editorWidget.descriptionLabel2.setText("Talk not found")
            self.editorWidget.levelLabel2.setText("Talk not found")
            self.editorWidget.eventLabel2.setText("Talk not found")
            self.editorWidget.roomLabel2.setText("Talk not found")
            self.editorWidget.timeLabel2.setText("Talk not found")

    def export_reports_to_csv(self):
        fname = QFileDialog.getSaveFileName(self, self.selectFileString, "", "*.csv")
        if fname:
            self.db.export_reports_to_csv(fname)
Example #41
0
class ReportEditorApp(FreeseerApp):
    '''
    Freeseer report editor main gui class
    '''
    def __init__(self, config, db):
        FreeseerApp.__init__(self)

        self.config = config
        self.db = db

        icon = QIcon()
        icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal,
                       QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(960, 400)

        self.mainWidget = QWidget()
        self.mainLayout = QHBoxLayout()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)

        self.editorWidget = ReportEditorWidget()
        self.editorWidget.editor.setColumnHidden(5, True)

        self.mainLayout.addWidget(self.editorWidget)

        # Initialize geometry, to be used for restoring window positioning.
        self.geometry = None

        #
        # Setup Menubar
        #
        self.actionExportCsv = QAction(self)
        self.actionExportCsv.setObjectName(_fromUtf8("actionExportCsv"))

        # Actions
        self.menuFile.insertAction(self.actionExit, self.actionExportCsv)
        # --- End Menubar

        #
        # Report Editor Connections
        #

        # Editor Widget
        self.connect(self.editorWidget.removeButton, SIGNAL('clicked()'),
                     self.remove_talk)
        self.connect(self.editorWidget.clearButton, SIGNAL('clicked()'),
                     self.confirm_reset)
        self.connect(self.editorWidget.closeButton, SIGNAL('clicked()'),
                     self.close)

        # Main Window Connections
        self.connect(self.actionExportCsv, SIGNAL('triggered()'),
                     self.export_reports_to_csv)
        self.connect(self.editorWidget.editor,
                     SIGNAL('clicked (const QModelIndex&)'),
                     self.editorSelectionChanged)

        # Load default language
        actions = self.menuLanguage.actions()
        for action in actions:
            if action.data().toString() == self.config.default_language:
                action.setChecked(True)
                self.translate(action)
                break

        self.load_failures_model()
        self.editorWidget.editor.resizeColumnsToContents()
        self.editorWidget.editor.resizeRowsToContents()

    ###
    ### Translation
    ###
    def retranslate(self):
        self.setWindowTitle(
            self.app.translate("ReportEditorApp", "Freeseer Report Editor"))

        #
        # Reusable Strings
        #
        self.confirmDBClearTitleString = self.app.translate(
            "ReportEditorApp", "Clear Database")
        self.confirmDBClearQuestionString = self.app.translate(
            "ReportEditorApp", "Are you sure you want to clear the DB?")
        self.selectFileString = self.app.translate("ReportEditorApp",
                                                   "Select File")
        # --- End Reusable Strings

        #
        # Menubar
        #
        self.actionExportCsv.setText(
            self.app.translate("ReportEditorApp", "&Export to CSV"))
        # --- End Menubar

        #
        # EditorWidget
        #
        self.editorWidget.removeButton.setText(
            self.app.translate("ReportEditorApp", "Remove"))
        self.editorWidget.clearButton.setText(
            self.app.translate("ReportEditorApp", "Clear"))
        self.editorWidget.closeButton.setText(
            self.app.translate("ReportEditorApp", "Close"))

        self.editorWidget.titleLabel.setText(
            self.app.translate("ReportEditorApp", "Title:"))
        self.editorWidget.speakerLabel.setText(
            self.app.translate("ReportEditorApp", "Speaker:"))
        self.editorWidget.descriptionLabel.setText(
            self.app.translate("ReportEditorApp", "Description:"))
        self.editorWidget.levelLabel.setText(
            self.app.translate("ReportEditorApp", "Level:"))
        self.editorWidget.eventLabel.setText(
            self.app.translate("ReportEditorApp", "Event:"))
        self.editorWidget.roomLabel.setText(
            self.app.translate("ReportEditorApp", "Room:"))
        self.editorWidget.startTimeLabel.setText(
            self.app.translate("ReportEditorApp", "Start Time:"))
        self.editorWidget.endTimeLabel.setText(
            self.app.translate("ReportEditorApp", "End Time:"))
        # --- End EditorWidget

    def load_failures_model(self):
        # Load Presentation Model
        self.failureModel = self.db.get_failures_model()
        editor = self.editorWidget.editor
        editor.setModel(self.failureModel)
        editor.horizontalHeader().setResizeMode(QHeaderView.Stretch)

    def hide_add_talk_widget(self):
        self.editorWidget.setHidden(False)
        self.addTalkWidget.setHidden(True)

    def add_talk(self):
        date = self.addTalkWidget.dateEdit.date()
        startTime = self.addTalkWidget.startTimeEdit.time()
        datetime = QDateTime(date,
                             startTime)  # original "time" is now "startTime"
        presentation = Presentation(
            unicode(self.addTalkWidget.titleLineEdit.text()),
            unicode(self.addTalkWidget.presenterLineEdit.text()),
            "",  # description
            "",  # level
            unicode(self.addTalkWidget.eventLineEdit.text()),
            unicode(self.addTalkWidget.roomLineEdit.text()),
            unicode(datetime.toString()),
            unicode(self.addTalkWidget.endTimeEdit.text()))

        # Do not add talks if they are empty strings
        if (len(presentation.title) == 0):
            return

        self.db.insert_presentation(presentation)

        # cleanup
        self.addTalkWidget.titleLineEdit.clear()
        self.addTalkWidget.presenterLineEdit.clear()

        self.failureModel.select()

        self.hide_add_talk_widget()

    def remove_talk(self):
        try:
            row_clicked = self.editorWidget.editor.currentIndex().row()
        except:
            return

        self.failureModel.removeRow(row_clicked)
        self.failureModel.select()

    def reset(self):
        self.db.clear_report_db()
        self.failureModel.select()

    def confirm_reset(self):
        """
        Presents a confirmation dialog to ask the user if they are sure they
        wish to remove the report database.

        If Yes call the reset() function.
        """
        confirm = QMessageBox.question(self, self.confirmDBClearTitleString,
                                       self.confirmDBClearQuestionString,
                                       QMessageBox.Yes | QMessageBox.No,
                                       QMessageBox.No)

        if confirm == QMessageBox.Yes:
            self.reset()

    def closeEvent(self, event):
        log.info('Exiting report editor...')
        self.geometry = self.saveGeometry()
        event.accept()

    def editorSelectionChanged(self, index):
        talkId = self.failureModel.record(index.row()).value(0).toString()
        self.updatePresentationInfo(talkId)

    def updatePresentationInfo(self, talkId):
        p = self.db.get_presentation(talkId)
        if p is not None:
            self.editorWidget.titleLabel2.setText(p.title)
            self.editorWidget.speakerLabel2.setText(p.speaker)
            self.editorWidget.descriptionLabel2.setText(p.description)
            self.editorWidget.levelLabel2.setText(p.level)
            self.editorWidget.eventLabel2.setText(p.event)
            self.editorWidget.roomLabel2.setText(p.room)
            self.editorWidget.startTimeLabel2.setText(p.startTime)
            self.editorWidget.endTimeLabel2.setText(p.endTime)
        else:
            self.editorWidget.titleLabel2.setText("Talk not found")
            self.editorWidget.speakerLabel2.setText("Talk not found")
            self.editorWidget.descriptionLabel2.setText("Talk not found")
            self.editorWidget.levelLabel2.setText("Talk not found")
            self.editorWidget.eventLabel2.setText("Talk not found")
            self.editorWidget.roomLabel2.setText("Talk not found")
            self.editorWidget.startTimeLabel2.setText("Talk not found")
            self.editorWidget.endTimeLabel2.setText("Talk not found")

    def export_reports_to_csv(self):
        fname = QFileDialog.getSaveFileName(self, self.selectFileString, "",
                                            "*.csv")
        if fname:
            self.db.export_reports_to_csv(fname)
Example #42
0
class Qgis2threejs:

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

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(QFile.decodeName(__file__))

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

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

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

        self.objectTypeManager = None
        self.pluginManager = None

        self.exportSettings = {}
        self.lastTreeItemData = None
        self.settingsFilePath = None

    def initGui(self):
        # Create action that will start plugin configuration
        icon = QIcon(os.path.join(self.plugin_dir, "icon.png"))
        self.action = QAction(icon, u"Qgis2threejs", self.iface.mainWindow())
        self.action.setObjectName("Qgis2threejs")

        self.settingAction = QAction(u"Settings", self.iface.mainWindow())
        self.settingAction.setObjectName("Qgis2threejsSettings")

        # connect the action to the run method
        self.action.triggered.connect(self.run)
        self.settingAction.triggered.connect(self.setting)

        # Add toolbar button and web menu items
        self.iface.addWebToolBarIcon(self.action)
        self.iface.addPluginToWebMenu(u"Qgis2threejs", self.action)
        self.iface.addPluginToWebMenu(u"Qgis2threejs", self.settingAction)

    def unload(self):
        # Remove the web menu items and icon
        self.iface.removeWebToolBarIcon(self.action)
        self.iface.removePluginWebMenu(u"Qgis2threejs", self.action)
        self.iface.removePluginWebMenu(u"Qgis2threejs", self.settingAction)

        # remove temporary output directory
        removeTemporaryOutputDir()

    def run(self):
        from vectorobject import ObjectTypeManager
        from pluginmanager import PluginManager
        from qgis2threejsdialog import Qgis2threejsDialog

        if self.objectTypeManager is None:
            self.objectTypeManager = ObjectTypeManager()

        if self.pluginManager is None:
            self.pluginManager = PluginManager()

        # restore export settings
        proj_path = QgsProject.instance().fileName()
        settingsFilePath = proj_path + ".qto3settings" if proj_path else None

        if not self.exportSettings or settingsFilePath != self.settingsFilePath:
            if settingsFilePath and os.path.exists(settingsFilePath):
                self.loadExportSettings(settingsFilePath)
                logMessage(u"Restored export settings of this project: {0}".format(
                    os.path.basename(proj_path)))  # QgsProject.instance().title()

        dialog = Qgis2threejsDialog(
            self.iface,
            self.objectTypeManager,
            self.pluginManager,
            self.exportSettings,
            self.lastTreeItemData)

        # show dialog
        dialog.show()
        ret = dialog.exec_()

        self.exportSettings = dialog.settings(True)

        item = dialog.ui.treeWidget.currentItem()
        self.lastTreeItemData = item.data(0, Qt.UserRole) if item else None

        # if export succeeded, save export settings in the directory that
        # project file exists
        if ret and settingsFilePath:
            self.saveExportSettings(settingsFilePath)

        self.settingsFilePath = settingsFilePath

    def setting(self):
        from settingsdialog import SettingsDialog
        dialog = SettingsDialog(self.iface.mainWindow())
        dialog.show()
        if dialog.exec_():
            from pluginmanager import PluginManager
            self.pluginManager = PluginManager()

    def loadExportSettings(self, filename):
        import json
        with open(filename) as f:
            self.exportSettings = json.load(f)

    def saveExportSettings(self, filename):
        import codecs
        import json
        try:
            with codecs.open(filename, "w", "UTF-8") as f:
                json.dump(
                    self.exportSettings,
                    f,
                    ensure_ascii=False,
                    indent=2,
                    sort_keys=True)
            return True
        except Exception as e:
            logMessage("Failed to save export settings: " + str(e))
            return False
Example #43
0
class TalkEditorApp(FreeseerApp):
    '''Freeseer talk database editor main gui class'''
    def __init__(self, config, db):
        super(TalkEditorApp, self).__init__(config)

        self.db = db

        icon = QIcon()
        icon.addPixmap(QPixmap(':/freeseer/logo.png'), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(960, 600)

        #
        # Setup Layout
        #
        self.mainWidget = QWidget()
        self.mainLayout = QVBoxLayout()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)
        self.mainLayout.setAlignment(Qt.AlignTop)

        # Add custom widgets
        self.commandButtons = CommandButtons()
        self.tableView = QTableView()
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.talkDetailsWidget = TalkDetailsWidget()
        self.importTalksWidget = ImportTalksWidget()
        self.newTalkWidget = NewTalkWidget()
        self.mainLayout.addWidget(self.importTalksWidget)
        #self.mainLayout.addLayout(self.titleLayout)
        self.mainLayout.addWidget(self.commandButtons)
        self.mainLayout.addWidget(self.tableView)
        self.mainLayout.addWidget(self.talkDetailsWidget)
        self.mainLayout.addWidget(self.importTalksWidget)
        # --- End Layout

        # Keep track of index of the most recently selected talk
        self.currentTalkIndex = QPersistentModelIndex()

        # Prompt user to "Continue Editing", "Discard Changes" or "Save Changes"
        self.savePromptBox = QMessageBox()
        self.savePromptBox.setWindowTitle("Unsaved Changes Exist")
        self.savePromptBox.setIcon(QMessageBox.Information)
        self.savePromptBox.setText(
            "The talk you were editing has unsaved changes.")
        self.continueButton = self.savePromptBox.addButton(
            "Continue Editing", QMessageBox.RejectRole)
        self.discardButton = self.savePromptBox.addButton(
            "Discard Changes", QMessageBox.DestructiveRole)
        self.saveButton = self.savePromptBox.addButton("Save Changes",
                                                       QMessageBox.AcceptRole)
        self.savePromptBox.setDefaultButton(self.saveButton)

        # Initialize geometry, to be used for restoring window positioning.
        self.geometry = None

        #
        # Setup Menubar
        #
        self.actionExportCsv = QAction(self)
        self.actionExportCsv.setObjectName('actionExportCsv')
        self.actionRemoveAll = QAction(self)
        self.actionRemoveAll.setObjectName('actionRemoveAll')

        # Actions
        self.menuFile.insertAction(self.actionExit, self.actionExportCsv)
        self.menuFile.insertAction(self.actionExit, self.actionRemoveAll)
        # --- End Menubar

        #
        # TableView Connections
        #
        self.connect(self.tableView, SIGNAL('activated(const QModelIndex)'),
                     self.click_talk)
        self.connect(self.tableView, SIGNAL('selected(const QModelIndex)'),
                     self.click_talk)
        self.connect(self.tableView, SIGNAL('clicked(const QModelIndex)'),
                     self.click_talk)

        # Import Widget
        self.connect(self.importTalksWidget.csvRadioButton,
                     SIGNAL('toggled(bool)'), self.toggle_import)
        self.connect(self.importTalksWidget.importButton, SIGNAL('clicked()'),
                     self.import_talks)
        self.connect(self.importTalksWidget.cancelButton, SIGNAL('clicked()'),
                     self.hide_import_talks_widget)
        self.importTalksWidget.setHidden(True)
        self.connect(self.importTalksWidget.csvFileSelectButton,
                     SIGNAL('clicked()'), self.csv_file_select)
        self.connect(self.importTalksWidget.csvLineEdit,
                     SIGNAL('returnPressed()'),
                     self.importTalksWidget.importButton.click)
        self.connect(self.importTalksWidget.rssLineEdit,
                     SIGNAL('returnPressed()'),
                     self.importTalksWidget.importButton.click)
        self.connect(self.actionExportCsv, SIGNAL('triggered()'),
                     self.export_talks_to_csv)
        self.connect(self.actionRemoveAll, SIGNAL('triggered()'),
                     self.confirm_reset)

        # Command Buttons
        self.connect(self.commandButtons.addButton, SIGNAL('clicked()'),
                     self.click_add_button)
        self.connect(self.commandButtons.removeButton, SIGNAL('clicked()'),
                     self.remove_talk)
        self.connect(self.commandButtons.removeAllButton, SIGNAL('clicked()'),
                     self.confirm_reset)
        self.connect(self.commandButtons.importButton, SIGNAL('clicked()'),
                     self.show_import_talks_widget)
        self.connect(self.commandButtons.exportButton, SIGNAL('clicked()'),
                     self.export_talks_to_csv)
        self.connect(self.commandButtons.searchButton, SIGNAL('clicked()'),
                     self.search_talks)
        self.connect(self.commandButtons.searchLineEdit,
                     SIGNAL('textEdited(QString)'), self.search_talks)
        self.connect(self.commandButtons.searchLineEdit,
                     SIGNAL('returnPressed()'), self.search_talks)

        # Talk Details Buttons
        self.connect(self.talkDetailsWidget.saveButton, SIGNAL('clicked()'),
                     self.update_talk)

        # Talk Details Widget
        self.connect(self.talkDetailsWidget.titleLineEdit,
                     SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.presenterLineEdit,
                     SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.categoryLineEdit,
                     SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.eventLineEdit,
                     SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.roomLineEdit,
                     SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.descriptionTextEdit,
                     SIGNAL('modificationChanged(bool)'), self.enable_save)
        self.connect(self.talkDetailsWidget.dateEdit,
                     SIGNAL('dateChanged(const QDate)'), self.enable_save)
        self.connect(self.talkDetailsWidget.startTimeEdit,
                     SIGNAL('timeChanged(const QTime)'), self.enable_save)
        self.connect(self.talkDetailsWidget.endTimeEdit,
                     SIGNAL('timeChanged(const QTime)'), self.enable_save)

        # New Talk Widget
        self.newTalkWidget.connect(self.newTalkWidget.addButton,
                                   SIGNAL('clicked()'), self.add_talk)
        self.newTalkWidget.connect(self.newTalkWidget.cancelButton,
                                   SIGNAL('clicked()'),
                                   self.newTalkWidget.reject)

        # Load default language
        actions = self.menuLanguage.actions()
        for action in actions:
            if action.data().toString() == self.config.default_language:
                action.setChecked(True)
                self.translate(action)
                break

        # Load Talk Database
        self.load_presentations_model()

        # Setup Autocompletion
        self.update_autocomplete_fields()

        self.talkDetailsWidget.saveButton.setEnabled(False)

        # Select first item
        #self.tableView.setCurrentIndex(self.proxy.index(0,0))
        #self.talk_selected(self.proxy.index(0,0))

    #
    # Translation
    #
    def retranslate(self):
        self.setWindowTitle(
            self.app.translate("TalkEditorApp", "Freeseer Talk Editor"))

        #
        # Reusable Strings
        #
        self.confirmDBClearTitleString = self.app.translate(
            "TalkEditorApp", "Remove All Talks from Database")
        self.confirmDBClearQuestionString = self.app.translate(
            "TalkEditorApp", "Are you sure you want to clear the DB?")
        self.confirmTalkDetailsClearTitleString = self.app.translate(
            "TalkEditorApp", "Unsaved Data")
        self.confirmTalkDetailsClearQuestionString = self.app.translate(
            "TalkEditorApp", "Unsaved talk details will be lost. Continue?")
        # --- End Reusable Strings

        #
        # Menubar
        #
        self.actionExportCsv.setText(
            self.app.translate("TalkEditorApp", "&Export to CSV"))
        self.actionRemoveAll.setText(
            self.app.translate("TalkEditorApp", "&Remove All Talks"))

        # --- End Menubar

        #
        # TalkDetailsWidget
        #
        self.talkDetailsWidget.titleLabel.setText(
            self.app.translate("TalkEditorApp", "Title"))
        self.talkDetailsWidget.presenterLabel.setText(
            self.app.translate("TalkEditorApp", "Presenter"))
        self.talkDetailsWidget.categoryLabel.setText(
            self.app.translate("TalkEditorApp", "Category"))
        self.talkDetailsWidget.eventLabel.setText(
            self.app.translate("TalkEditorApp", "Event"))
        self.talkDetailsWidget.roomLabel.setText(
            self.app.translate("TalkEditorApp", "Room"))
        self.talkDetailsWidget.dateLabel.setText(
            self.app.translate("TalkEditorApp", "Date"))
        self.talkDetailsWidget.startTimeLabel.setText(
            self.app.translate("TalkEditorApp", "Start Time"))
        self.talkDetailsWidget.endTimeLabel.setText(
            self.app.translate("TalkEditorApp", "End Time"))
        # --- End TalkDetailsWidget

        #
        # Import Talks Widget Translations
        #
        self.importTalksWidget.rssRadioButton.setText(
            self.app.translate("TalkEditorApp", "RSS URL"))
        self.importTalksWidget.csvRadioButton.setText(
            self.app.translate("TalkEditorApp", "CSV File"))
        self.importTalksWidget.importButton.setText(
            self.app.translate("TalkEditorApp", "Import"))
        # --- End Talks Widget Translations

        #
        # Command Button Translations\
        #
        self.commandButtons.importButton.setText(
            self.app.translate("TalkEditorApp", "Import"))
        self.commandButtons.exportButton.setText(
            self.app.translate("TalkEditorApp", "Export"))
        self.commandButtons.addButton.setText(
            self.app.translate("TalkEditorApp", "Add New Talk"))
        self.commandButtons.removeButton.setText(
            self.app.translate("TalkEditorApp", "Remove"))
        self.commandButtons.removeAllButton.setText(
            self.app.translate("TalkEditorApp", "Remove All"))
        # --- End Command Butotn Translations

        #
        # Search Widget Translations
        #
        self.commandButtons.searchButton.setText(
            self.app.translate("TalkEditorApp", "Search"))
        # --- End Command Button Translations

    def load_presentations_model(self):
        # Load Presentation Model
        self.presentationModel = self.db.get_presentations_model()
        self.proxy = QSortFilterProxyModel()
        self.proxy.setSourceModel(self.presentationModel)
        self.tableView.setModel(self.proxy)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)

        # Fill table whitespace.
        self.tableView.horizontalHeader().setStretchLastSection(False)
        self.tableView.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)

        # Hide the ID field
        self.tableView.setColumnHidden(0, True)

        # Map data to widgets
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy)
        self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
        self.mapper.addMapping(self.talkDetailsWidget.titleLineEdit, 1)
        self.mapper.addMapping(self.talkDetailsWidget.presenterLineEdit, 2)
        self.mapper.addMapping(self.talkDetailsWidget.categoryLineEdit, 4)
        self.mapper.addMapping(self.talkDetailsWidget.eventLineEdit, 5)
        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.mapper.addMapping(self.talkDetailsWidget.descriptionTextEdit, 3)
        self.mapper.addMapping(self.talkDetailsWidget.dateEdit, 7)
        self.mapper.addMapping(self.talkDetailsWidget.startTimeEdit, 8)
        self.mapper.addMapping(self.talkDetailsWidget.endTimeEdit, 9)

        # Load StringLists
        self.titleList = QStringList(self.db.get_string_list("Title"))
        #self.speakerList = QStringList(self.db.get_speaker_list())
        #self.categoryList = QStringList(self.db.get_category_list())
        #self.eventList = QStringList(self.db.get_event_list())
        #self.roomList = QStringList(self.db.get_room_list())

        #Disble input
        self.talkDetailsWidget.disable_input_fields()

    def search_talks(self):
        # The default value is 0. If the value is -1, the keys will be read from all columns.
        self.proxy.setFilterKeyColumn(-1)
        self.proxy.setFilterFixedString(
            self.commandButtons.searchLineEdit.text())

    def show_save_prompt(self):
        """Prompts the user to save or discard changes, or continue editing."""
        self.savePromptBox.exec_()
        self.savePromptBox.setDefaultButton(self.saveButton)
        return self.savePromptBox.clickedButton()

    def click_talk(self, model):
        """Warns user if there are unsaved changes, and selects talk clicked by the user."""
        log.info("Selecting row %d", model.row())
        modelRow = model.row()
        if self.unsaved_details_exist():
            log.info("Unsaved changes exist in row %d",
                     self.currentTalkIndex.row())
            confirm = self.show_save_prompt()
            if confirm == self.saveButton:
                log.info("Saving changes in row %d...",
                         self.currentTalkIndex.row())
                self.tableView.selectRow(self.currentTalkIndex.row())
                self.update_talk()
                newModel = self.tableView.currentIndex().sibling(modelRow, 0)
                self.select_talk(newModel)
            elif confirm == self.discardButton:
                log.info("Discarding changes in row %d...",
                         self.currentTalkIndex.row())
                self.talk_selected(model)
            else:
                log.info("Continue editing row %d",
                         self.currentTalkIndex.row())
                self.tableView.selectRow(self.currentTalkIndex.row())
        else:
            self.talk_selected(model)

    def click_add_button(self):
        """Warns user if there are unsaved changes, and shows the New Talk window."""
        if self.unsaved_details_exist():
            log.info("Unsaved changes exist in row %d",
                     self.currentTalkIndex.row())
            confirm = self.show_save_prompt()
            if confirm == self.saveButton:
                log.info("Saving changes in row %d...",
                         self.currentTalkIndex.row())
                self.update_talk()
                self.show_new_talk_popup()
            elif confirm == self.discardButton:
                log.info("Discarding changes in row %d...",
                         self.currentTalkIndex.row())
                # Ensure that changes are discarded
                self.talk_selected(self.currentTalkIndex)
                self.show_new_talk_popup()
            else:
                log.info("Continue editing row %d",
                         self.currentTalkIndex.row())
        else:
            self.show_new_talk_popup()

    def talk_selected(self, model):
        self.mapper.setCurrentIndex(model.row())
        self.talkDetailsWidget.enable_input_fields()
        self.talkDetailsWidget.saveButton.setEnabled(False)
        self.currentTalkIndex = QPersistentModelIndex(model)

    def toggle_import(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.importTalksWidget.csvLineEdit.setEnabled(True)
            self.importTalksWidget.csvFileSelectButton.setEnabled(True)
            self.importTalksWidget.rssLineEdit.setEnabled(False)
        else:
            self.importTalksWidget.csvLineEdit.setEnabled(False)
            self.importTalksWidget.csvFileSelectButton.setEnabled(False)
            self.importTalksWidget.rssLineEdit.setEnabled(True)

    def show_import_talks_widget(self):
        self.commandButtons.setHidden(True)
        self.tableView.setHidden(True)
        self.talkDetailsWidget.setHidden(True)
        self.importTalksWidget.setHidden(False)

    def hide_import_talks_widget(self):
        self.commandButtons.setHidden(False)
        self.tableView.setHidden(False)
        self.talkDetailsWidget.setHidden(False)
        self.importTalksWidget.setHidden(True)

    def add_talk(self):
        """Adds a new talk to the database using data from the NewTalkWidget input fields"""
        presentation = self.create_presentation(
            self.newTalkWidget.talkDetailsWidget)

        if presentation:
            self.db.insert_presentation(presentation)
            self.newTalkWidget.accept()  # Close the dialog

    def update_talk(self):
        """Updates the currently selected talk using data from the TalkEditorApp input fields"""
        selected_talk = self.tableView.currentIndex()
        if selected_talk.row(
        ) >= 0:  # The tableView index begins at 0 and is -1 by default
            talk_id = selected_talk.sibling(selected_talk.row(),
                                            0).data().toString()
            presentation = self.create_presentation(self.talkDetailsWidget)

            if presentation:
                self.db.update_presentation(talk_id, presentation)
                self.apply_changes(selected_talk)
                self.talkDetailsWidget.saveButton.setEnabled(False)

    def create_presentation(self, talkDetailsWidget):
        """Creates and returns an instance of Presentation using data from the input fields"""
        date = talkDetailsWidget.dateEdit.date()
        startTime = talkDetailsWidget.startTimeEdit.time()
        endTime = talkDetailsWidget.endTimeEdit.time()

        title = unicode(talkDetailsWidget.titleLineEdit.text()).strip()
        if title:
            return Presentation(
                unicode(talkDetailsWidget.titleLineEdit.text()).strip(),
                unicode(talkDetailsWidget.presenterLineEdit.text()).strip(),
                unicode(talkDetailsWidget.descriptionTextEdit.toPlainText()).
                strip(),
                unicode(talkDetailsWidget.categoryLineEdit.text()).strip(),
                unicode(talkDetailsWidget.eventLineEdit.text()).strip(),
                unicode(talkDetailsWidget.roomLineEdit.text()).strip(),
                unicode(date.toString(Qt.ISODate)),
                unicode(startTime.toString(Qt.ISODate)),
                unicode(endTime.toString(Qt.ISODate)))

    def show_new_talk_popup(self):
        """Displays a modal dialog with a talk details view

        When Add is selected, a new talk is added to the database using the input field data.
        When Cancel is selected, no talk is added.
        """
        log.info('Opening Add Talk window...')
        self.clear_new_talk_fields()
        self.remove_new_talk_placeholder_text()
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.setFocus()
        if self.newTalkWidget.exec_() == 1:
            self.apply_changes()
            self.talkDetailsWidget.disable_input_fields()
        else:
            log.info('No talk added...')

    def apply_changes(self, updated_talk=None):
        """Repopulates the model to display the effective changes

        Updates the autocomplete fields.
        Displays the updated model in the table view, and selects the newly updated/added talk.
        """
        self.presentationModel.select()
        self.select_talk(updated_talk)
        self.update_autocomplete_fields()

    def select_talk(self, talk=None):
        """Selects the given talk in the table view

        If no talk is given, the last row in the table view is selected.
        """
        if talk:
            row = talk.row()
            column = talk.column()
        else:
            row = self.presentationModel.rowCount() - 1  # Select last row
            column = 0

        self.tableView.selectRow(row)
        self.tableView.setCurrentIndex(self.proxy.index(row, column))
        self.talk_selected(self.proxy.index(row, column))

    def remove_talk(self):
        try:
            rows_selected = self.tableView.selectionModel().selectedRows()
        except:
            return

        # Reversed because rows in list change position once row is removed
        for row in reversed(rows_selected):
            self.presentationModel.removeRow(row.row())
        self.talkDetailsWidget.clear_input_fields()
        self.talkDetailsWidget.disable_input_fields()

    def load_talk(self):
        try:
            self.tableView.currentIndex().row()
        except:
            return

        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.presentationModel.select()

    def reset(self):
        self.db.clear_database()
        self.presentationModel.select()
        self.talkDetailsWidget.clear_input_fields()
        self.talkDetailsWidget.disable_input_fields()

    def confirm_reset(self):
        """Presents a confirmation dialog to ask the user if they are sure they wish to remove the talk database.
        If Yes call the reset() function"""
        confirm = QMessageBox.question(self, self.confirmDBClearTitleString,
                                       self.confirmDBClearQuestionString,
                                       QMessageBox.Yes | QMessageBox.No,
                                       QMessageBox.No)

        if confirm == QMessageBox.Yes:
            self.reset()

    def add_talks_from_rss(self):
        rss_url = unicode(self.importTalksWidget.rssLineEdit.text())
        if rss_url:
            self.db.add_talks_from_rss(rss_url)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please enter a RSS URL")
            error.exec_()

    def closeEvent(self, event):
        if self.unsaved_details_exist():
            log.info("Unsaved changes exist in row %d",
                     self.currentTalkIndex.row())
            confirm = self.show_save_prompt()
            if confirm == self.saveButton:
                log.info("Saving changes in row %d...",
                         self.currentTalkIndex.row())
                self.update_talk()
                log.info('Exiting talk database editor...')
                self.geometry = self.saveGeometry()
                event.accept()
            elif confirm == self.discardButton:
                log.info("Discarding changes in row %d...",
                         self.currentTalkIndex.row())
                # Ensure that changes are discarded
                self.talk_selected(self.currentTalkIndex)
                log.info('Exiting talk database editor...')
                self.geometry = self.saveGeometry()
                event.accept()
            else:
                log.info("Continue editing row %d",
                         self.currentTalkIndex.row())
                event.ignore()
        else:
            log.info('Exiting talk database editor...')
            self.geometry = self.saveGeometry()
            event.accept()

    def csv_file_select(self):
        fname = QFileDialog.getOpenFileName(self, 'Select file', "", "*.csv")
        if fname:
            self.importTalksWidget.csvLineEdit.setText(fname)

    def add_talks_from_csv(self):
        fname = self.importTalksWidget.csvLineEdit.text()

        if fname:
            self.db.add_talks_from_csv(fname)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please select a file")
            error.exec_()

    def import_talks(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.add_talks_from_csv()
        else:
            self.add_talks_from_rss()

        self.update_autocomplete_fields()

    def export_talks_to_csv(self):
        fname = QFileDialog.getSaveFileName(self, 'Select file', "", "*.csv")
        if fname:
            self.db.export_talks_to_csv(fname)

    def update_autocomplete_fields(self):
        self.titleList = QStringList(self.db.get_string_list("Title"))
        self.speakerList = QStringList(self.db.get_string_list("Speaker"))
        self.categoryList = QStringList(self.db.get_string_list("Category"))
        self.eventList = QStringList(self.db.get_string_list("Event"))
        self.roomList = QStringList(self.db.get_string_list("Room"))

        self.titleCompleter = QCompleter(self.titleList)
        self.titleCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.speakerCompleter = QCompleter(self.speakerList)
        self.speakerCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.categoryCompleter = QCompleter(self.categoryList)
        self.categoryCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.eventCompleter = QCompleter(self.eventList)
        self.eventCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.roomCompleter = QCompleter(self.roomList)
        self.roomCompleter.setCaseSensitivity(Qt.CaseInsensitive)

        self.talkDetailsWidget.titleLineEdit.setCompleter(self.titleCompleter)
        self.talkDetailsWidget.presenterLineEdit.setCompleter(
            self.speakerCompleter)
        self.talkDetailsWidget.categoryLineEdit.setCompleter(
            self.categoryCompleter)
        self.talkDetailsWidget.eventLineEdit.setCompleter(self.eventCompleter)
        self.talkDetailsWidget.roomLineEdit.setCompleter(self.roomCompleter)

    def are_fields_enabled(self):
        return (self.talkDetailsWidget.titleLineEdit.isEnabled()
                and self.talkDetailsWidget.presenterLineEdit.isEnabled()
                and self.talkDetailsWidget.categoryLineEdit.isEnabled()
                and self.talkDetailsWidget.eventLineEdit.isEnabled()
                and self.talkDetailsWidget.roomLineEdit.isEnabled()
                and self.talkDetailsWidget.dateEdit.isEnabled()
                and self.talkDetailsWidget.startTimeEdit.isEnabled()
                and self.talkDetailsWidget.endTimeEdit.isEnabled())

    def unsaved_details_exist(self):
        """Checks if changes have been made to new/existing talk details

        Looks for text in the input fields and check the enabled state of the Save Talk button
        If the Save Talk button is enabled, the input fields contain modified values
        """
        return (self.talkDetailsWidget.saveButton.isEnabled() and
                (self.talkDetailsWidget.titleLineEdit.text()
                 or self.talkDetailsWidget.presenterLineEdit.text()
                 or self.talkDetailsWidget.categoryLineEdit.text()
                 or self.talkDetailsWidget.descriptionTextEdit.toPlainText()))

    def enable_save(self):
        self.talkDetailsWidget.saveButton.setEnabled(True)

    def clear_new_talk_fields(self):
        """Removes existing data from all NewTalkWidget fields except event, room, date and time"""
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.clear()
        self.newTalkWidget.talkDetailsWidget.presenterLineEdit.clear()
        self.newTalkWidget.talkDetailsWidget.descriptionTextEdit.clear()
        self.newTalkWidget.talkDetailsWidget.categoryLineEdit.clear()

    def remove_new_talk_placeholder_text(self):
        """Removes placeholder text in NewTalkWidget originally set by TalkDetailsWidget"""
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.setPlaceholderText(
            "")
        self.newTalkWidget.talkDetailsWidget.presenterLineEdit.setPlaceholderText(
            "")
        self.newTalkWidget.talkDetailsWidget.categoryLineEdit.setPlaceholderText(
            "")
        self.newTalkWidget.talkDetailsWidget.eventLineEdit.setPlaceholderText(
            "")
        self.newTalkWidget.talkDetailsWidget.roomLineEdit.setPlaceholderText(
            "")
Example #44
0
File: stdio.py Project: alepee/dff
class IO(QDockWidget):
   def __init__(self, mainWindow):
	super(IO, self).__init__()
	self.__mainWindow = mainWindow
	self.addAction()
	self.configure()
	self.io = self.initIO()
	self.sigout = "IOOUTputtext"
        self.connect(self, SIGNAL(self.sigout), self.puttextout)
	self.sigerr = "IOERRputtext"
        self.connect(self, SIGNAL(self.sigerr), self.puttexterr)
	self.redirect = RedirectIO(self)
	self.cioout = CIO(self, sys.__stdout__.fileno(), self.sigout)     
	self.cioout.start()
	self.cioerr = CIO(self, sys.__stderr__.fileno(), self.sigerr)     
	self.cioerr.start()

   def configure(self):
        self.setAllowedAreas(Qt.AllDockWidgetAreas)
        self.setObjectName("dockWidgetBrowser")
        self.setWindowTitle(QApplication.translate("Log", "Log", None, QApplication.UnicodeUTF8))
 
   def addAction(self):
        self.__action = QAction(self)
        self.__action.setCheckable(True)
        self.__action.setChecked(True)
        self.__action.setObjectName("actionCoreInformations")
        self.__action.setText(QApplication.translate("MainWindow", "Log", None, QApplication.UnicodeUTF8))
        self.__mainWindow.menuWindow.addAction(self.__action)
        self.connect(self.__action,  SIGNAL("triggered()"),  self.changeVisibleInformations)
     
   def changeVisibleInformations(self):
        if not self.isVisible() :
            self.setVisible(True)
            self.__action.setChecked(True)
        else :
            self.setVisible(False)
            self.__action.setChecked(False)

   def visibilityChanged(self,  bool):
        if not self.isVisible() :
            self.__action.setChecked(False)
        else :
            self.__action.setChecked(True)

   def initIO(self):
        self.iowidget = QWidget(self)        
        self.layout = QHBoxLayout(self.iowidget)
        self.iowidget.setLayout(self.layout)
        self.tabwidget = QTabWidget(self)
        self.tabwidget.setElideMode(Qt.ElideRight)

	self.textOut = QTextEdit(self)
	self.textOut.setReadOnly(1)
	self.textOut.name = "output"
        self.setWidget(self.textOut)
	self.tabwidget.addTab(self.textOut, "Output")

	self.textErr = QTextEdit(self)
	self.textErr.setReadOnly(1)
	self.textErr.name = "error"
        self.setWidget(self.textErr)
	self.tabwidget.addTab(self.textErr, "Error")
	
	self.layout.addWidget(self.tabwidget)
        self.setWidget(self.iowidget)

   def puttextout(self, text):
 	self.textOut.append(text)

   def puttexterr(self, text):
        self.textErr.append(text)
Example #45
0
class CurveFitting(Module):
    """Module to fit waves to a function."""

    # To add new fitting functions, do the following:
    # 1) Edit GUI
    # 2) Modify _parameterTableDefaults
    # 3) Create a fit[Function] method to do the fitting
    # 4) Call fit[Function] from doFit

    # Default values for parameter table
    # Each dict entry is a list of lists. The inner list contains a row of values.
    _parameterTableDefaults = {
            'Polynomial': [
                ['p0', 1],
                ['p1', 1],
                ['p2', 1],
                ],
            'Sinusoid': [
                ['p0', 1],
                ['p1', 1],
                ['p2', 1],
                ['p3', 1],
                ],
            'Power Law': [
                ['y0', 0],
                ['a', 1],
                ['k', 1],
                ],
            'Exponential': [
                ['y0', 0],
                ['A', 1],
                ['b', 1],
                ],
            'Logarithm': [
                ['y0', 0],
                ['a', 1],
                ['base', 10],
                ],
            'Gaussian': [
                ['amp', 1],
                ['mean', 0],
                ['width', 1],
                ],
            'Lorentzian': [
                ['amp', 1],
                ['mean', 0],
                ['hwhm', 1],
                ],
            }

    def __init__(self):
        Module.__init__(self)

    def buildWidget(self):
        self._widget = QWidget()
        self._ui = Ui_CurveFitting()
        self._ui.setupUi(self._widget)

        self.setModels()
        self.setupSpinBoxes()
        self.setupParameterTableData()

        # Connect button signals
        self._ui.doFitButton.clicked.connect(self.doFit)
        self._ui.closeButton.clicked.connect(self.closeWindow)
        self._ui.function.currentIndexChanged[str].connect(self.changeFunction)
        self._ui.function.currentIndexChanged[str].connect(self.connectSlotsOnFunctionChange)
        self._ui.initialValuesWave.activated[str].connect(self.changeInitialValuesWave)
        self._ui.useInitialValuesWave.toggled[bool].connect(self.changeInitialValuesWaveFromCheckbox)

        self._ui.useWaveForInterpolation.toggled[bool].connect(self.catchInterpolationWaveGroupBoxCheck)
        self._ui.useDomainForInterpolation.toggled[bool].connect(self.catchInterpolationDomainGroupBoxCheck)
        
        self.connectSlotsOnFunctionChange('')

    def setModels(self):
        # Set up model and view
        self._allWavesListModel = self._app.model('appWaves')
        self._ui.xWave.setModel(self._allWavesListModel)
        self._ui.yWave.setModel(self._allWavesListModel)
        self._ui.weightWave.setModel(self._allWavesListModel)
        self._ui.initialValuesWave.setModel(self._allWavesListModel)
        self._ui.interpolationWave.setModel(self._allWavesListModel)

    def setupSpinBoxes(self):
        self._ui.dataRangeStart.addWaveView(self._ui.xWave)
        self._ui.dataRangeEnd.addWaveView(self._ui.xWave)

        self._ui.dataRangeStart.addWaveView(self._ui.yWave)
        self._ui.dataRangeEnd.addWaveView(self._ui.yWave)

        self._ui.interpolationWaveRangeStart.addWaveView(self._ui.interpolationWave)
        self._ui.interpolationWaveRangeEnd.addWaveView(self._ui.interpolationWave)

    def setupParameterTableData(self):
        self._parameterTableData = {}
        self._currentFunction = None
        self.changeFunction('')
    
    def closeWindow(self):
        self._widget.parent().close()

    def connectSlotsOnFunctionChange(self, newFunctionName):
        """
        Disconnect slots dependent on which function is chosen.

        If polynomial function is chosen, connect slot to update parameter table
        on degree change.
        """

        # Disconnect slots
        try:
            self._ui.polynomialDegree.valueChanged[int].disconnect(self.changePolynomialDegree)
        except:
            pass

        # Connect polynomial degree change
        if Util.getWidgetValue(self._ui.function) == 'Polynomial':
            self._ui.polynomialDegree.valueChanged[int].connect(self.changePolynomialDegree)

    def catchInterpolationWaveGroupBoxCheck(self, checked):
        # Set the opposite check for the domain group box
        Util.setWidgetValue(self._ui.useDomainForInterpolation, not checked)

    def catchInterpolationDomainGroupBoxCheck(self, checked):
        # Set the opposite check for the wave group box
        Util.setWidgetValue(self._ui.useWaveForInterpolation, not checked)
        
    def saveParameterTable(self):
        """
        Save the parameters for the current function to the object.
        """

        if self._currentFunction:
            self._parameterTableData[self._currentFunction] = self.getCurrentParameterTable()

    def changeFunction(self, newFunctionName):
        # Save parameters for old function
        self.saveParameterTable()
        #if self._currentFunction:
        #    self._parameterTableData[self._currentFunction] = self.getCurrentParameterTable()

        # Now update _currentFunction to the function that is currently selected.
        # If this method was called because the user selected a different function,
        # then this will be modified. If it was called because the fit curve button
        # was pressed, then its value will not be changed.
        self._currentFunction = Util.getWidgetValue(self._ui.function)

        # Enter in parameters for new function
        # If there are previously user-entered values, then use them
        # else, if a wave is selected, then use that
        # else, use the initial values
        # Either way, if there are blank entries, then use initial values for them

        # Clear the table, but leave all the column headers
        for rowIndex in range(self._ui.parameterTable.rowCount()):
            self._ui.parameterTable.removeRow(0)

        parameters = []
        # If there is saved data, use it
        if self._currentFunction in self._parameterTableData:
            parameters = self._parameterTableData[self._currentFunction]

        # If there aren't enough rows for all the parameters, extend with 
        # initial values. This will also occur if no parameters had been saved.
        savedParametersLength = len(parameters)
        defaultParameters = self._parameterTableDefaults[self._currentFunction]
        if savedParametersLength < len(defaultParameters):
            parameters.extend(defaultParameters[len(parameters):])
            
            # Use wave if requested by the user
            if Util.getWidgetValue(self._ui.useInitialValuesWave):
                # Convert from QString to str
                waveName = str(Util.getWidgetValue(self._ui.initialValuesWave))
                if self._app.waves().wave(waveName) is None:
                    # waveName is not a name of a wave
                    pass
                else:
                    waveData = self._app.waves().wave(waveName).data()
                    for i in range(savedParametersLength, len(defaultParameters)):
                        parameters[i][1] = waveData[i]
        
        self.writeParametersToTable(parameters)

    def writeParametersToTable(self, parameters, startRow=0):
        # Determine how many rows the table should have
        numRows = startRow + len(parameters)
        self._ui.parameterTable.setRowCount(numRows)

        # Now actually write to the table
        for rowIndex, row in enumerate(parameters, startRow):
            for colIndex, value in enumerate(row):
                item = QTableWidgetItem(str(value))
                if colIndex == 0:
                    # parameter name, do not want it editable
                    item.setFlags(Qt.ItemIsEnabled)

                self._ui.parameterTable.setItem(rowIndex, colIndex, item)
                
    def changePolynomialDegree(self, newDegree):
        # If decreasing the degree, just remove the last entries
        # If increasing the degree,
        #    If a wave is selected, then use that for the new values
        #    else, use the initial values
        
        desiredNumRows = newDegree + 1
        currentNumRows = self._ui.parameterTable.rowCount()
        
        if desiredNumRows == currentNumRows:
            # Nothing to do
            return

        # Set defaults
        rows = []
        for d in range(desiredNumRows):
            rows.append(['p' + str(d), 1])
        self._parameterTableDefaults['Polynomial'] = rows

        # Update table
        self._ui.parameterTable.setRowCount(desiredNumRows)

        if desiredNumRows < currentNumRows:
            # We are done, because no rows need to be edited
            return

        # Degree is being increased
        parameters = self._parameterTableDefaults['Polynomial'][currentNumRows:desiredNumRows]
        if Util.getWidgetValue(self._ui.useInitialValuesWave):
            # Convert from QString to str
            waveName = str(Util.getWidgetValue(self._ui.initialValuesWave))
            if self._app.waves().wave(waveName) is None:
                # waveName is not a name of a wave
                pass
            else:
                waveData = self._app.waves().wave(waveName).data(currentNumRows, desiredNumRows)
                for index, value in enumerate(waveData):
                    parameters[index][1] = value

        self.writeParametersToTable(parameters, currentNumRows)

    def changeInitialValuesWaveFromCheckbox(self, checked):
        """
        If the useInitialValuesWave checkbox is checked, then
        call changeInitialValuesWave.
        """

        if checked:
            self.changeInitialValuesWave(str(Util.getWidgetValue(self._ui.initialValuesWave)))

    def changeInitialValuesWave(self, waveName):
        # Use the wave for as many parameters as possible
        # if the wave is too long, then just use the first n values
        # if the wave is too short, then leave the current value in place
        #     if there is no current value, then use the initial values

        if Util.getWidgetValue(self._ui.useInitialValuesWave):
            # Get the current values, with any undefined values using the initial values
            parameters = self.currentParametersBackedByDefaults()

            # Now get the wave values
            parameters = self.updateParametersListWithWave(parameters, waveName)

            # Set the table to the parameters
            self.writeParametersToTable(parameters)


    def updateParametersListWithWave(self, parameters, waveName):
        """
        Given a list of parameter table rows, and the name of a wave,
        this will update the parameter values with the entries in the wave.
        """

        waveName = str(waveName)
        if self._app.waves().wave(waveName) is None:
            # waveName is not a name of a wave
            return parameters

        waveData = self._app.waves().wave(waveName).data(0, len(parameters))
        for i in range(len(waveData)):
            parameters[i][1] = waveData[i]

        return parameters

    def currentParametersBackedByDefaults(self):
        # Start with initial values
        parameters = self._parameterTableDefaults[self._currentFunction]

        # Then get the current values and update parameters with it
        currentParameters = self.getCurrentParameterTable()
        for rowIndex, row in enumerate(currentParameters):
            parameters[rowIndex] = row

        return parameters

    def getCurrentParameterTable(self):
        """
        Save data to a 2-d array mimicking the table.
        """
        # FIXME only works with text right now. Need to add in support for check boxes
        # Maybe do this by creating a QTableWidgetItem option in Util.getWidgetValue
        # and using QTableWidget.cellWidget to get the indiv. cells
        table = []
        row = []
        for rowIndex in range(self._ui.parameterTable.rowCount()):
            for colIndex in range(self._ui.parameterTable.columnCount()):
                try:
                    row.append(str(self._ui.parameterTable.item(rowIndex, colIndex).text()))
                except AttributeError:
                    row.append('')
            table.append(row)
            row = []

        return table

    def parameterColumnValues(self, functionName, columnNum):
        """
        Return a list of the values of a specific column in the parameter table.
        """

        if functionName not in self._parameterTableData:
            return None

        tableData = self._parameterTableData[functionName]

        values = [str(row[columnNum]) for row in tableData]
        return values

    def parameterNames(self, functionName):
        """
        Return a list of the names of the parameters for the given function.
        """
        return self.parameterColumnValues(functionName, 0)

    def parameterInitialValues(self, functionName):
        """
        Return a list of the initial values of the parameters (NOT the default values) for the given function.
        """
        values = self.parameterColumnValues(functionName, 1)
        initialValues = [float(v) if Util.isNumber(v) else 1 for v in values]
        return initialValues

    def doFit(self):
        # save user-defined parameters
        self.saveParameterTable()

        # Get all waves that are selected before doing anything else
        # If any waves are created, as they are in the output tab section,
        # then the wave combo boxes are refreshed, and the previous selection
        # is lost
        xWaveName = Util.getWidgetValue(self._ui.xWave)
        yWaveName = Util.getWidgetValue(self._ui.yWave)
        weightWaveName = Util.getWidgetValue(self._ui.weightWave)
        interpolationDomainWaveName = Util.getWidgetValue(self._ui.interpolationWave)

        # Get data tab
        dataRangeStart = Util.getWidgetValue(self._ui.dataRangeStart)
        dataRangeEnd = Util.getWidgetValue(self._ui.dataRangeEnd)
        
        xWave = self._app.waves().wave(xWaveName)
        yWave = self._app.waves().wave(yWaveName)
        xLength = xWave.length()
        yLength = yWave.length()
        
        # Verify data range limits are valid
        if dataRangeStart > xLength or dataRangeStart > yLength:
            dataRangeStart = 0
        if dataRangeEnd > xLength or dataRangeEnd > yLength:
            dataRangeEnd = min(xLength, yLength) - 1

        xData = xWave.data(dataRangeStart, dataRangeEnd + 1)
        yData = yWave.data(dataRangeStart, dataRangeEnd + 1)

        # Get weights, if required by user
        if Util.getWidgetValue(self._ui.useWeights):
            weightWave = self._app.waves().wave(weightWaveName)
            weightLength = weightWave.length()
            weightData = weightWave.data(dataRangeStart, dataRangeEnd + 1)

            # If weighting inversely, invert the weights
            if Util.getWidgetValue(self._ui.weightIndirectly):
                weightData = [1./w if w != 0 else 0 for w in weightData]

            if len(weightData) != len(yData):
                print "The number of weight points is not the same as the number of y points."
                return 1
        else:
            weightData = None

        # Get output tab
        outputOptions = {}
        outputWaves = {}

        outputOptions['createTable'] = Util.getWidgetValue(self._ui.createTable)

        outputOptions['outputParameters'] = Util.getWidgetValue(self._ui.outputParameters)
        if outputOptions['outputParameters']:
            outputOptions['saveLabels'] = Util.getWidgetValue(self._ui.saveLabels)

            # Create saveLabels wave
            if outputOptions['saveLabels']:
                saveLabelsDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.saveLabelsDestination))
                outputWaves['saveLabelsWave'] = Wave(saveLabelsDestination, 'String')
                self._app.waves().addWave(outputWaves['saveLabelsWave'])

            # Create parameter wave
            parameterDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.parameterDestination))
            outputWaves['parameterWave'] = Wave(parameterDestination, 'Decimal')
            self._app.waves().addWave(outputWaves['parameterWave'])

        outputOptions['outputInterpolation'] = Util.getWidgetValue(self._ui.outputInterpolation)
        if outputOptions['outputInterpolation']:
            # Create interpolation wave
            interpolationDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.interpolationDestination))
            outputWaves['interpolationDestinationWave'] = Wave(interpolationDestination, 'Decimal')
            self._app.waves().addWave(outputWaves['interpolationDestinationWave'])

            if Util.getWidgetValue(self._ui.useWaveForInterpolation):
                # Using an already-existing wave for the interpolation points.
                interpolationDomainWave = self._app.waves().wave(interpolationDomainWaveName)
                interpolationWaveRangeStart = Util.getWidgetValue(self._ui.interpolationWaveRangeStart)
                interpolationWaveRangeEnd = Util.getWidgetValue(self._ui.interpolationWaveRangeEnd)
                
                outputWaves['interpolationDomainWave'] = interpolationDomainWave
    
                # Start the wave with as many blanks as necessary in order to get the destination wave
                # to line up correctly with the domain wave, for easy plotting.
                outputWaves['interpolationDestinationWave'].extend([''] * interpolationWaveRangeStart)
                
                # Verify data range limits are valid
                interpolationDomainLength = interpolationDomainWave.length()
                if interpolationWaveRangeStart > interpolationDomainLength:
                    interpolationWaveRangeStart = 0
                if interpolationWaveRangeEnd > interpolationDomainLength:
                    interpolationWaveRangeEnd  = interpolationDomainLength - 1
    
                outputOptions['interpolationDomainWaveData'] = interpolationDomainWave.data(interpolationWaveRangeStart, interpolationWaveRangeEnd + 1)
            else:
                # Creating a new wave based on a domain and number of points.
                customWaveName = Util.getWidgetValue(self._ui.interpolationCustomWaveName)
                customLowerLimit = float(Util.getWidgetValue(self._ui.interpolationCustomLowerLimit))
                customUpperLimit = float(Util.getWidgetValue(self._ui.interpolationCustomUpperLimit))
                customNumPoints = Util.getWidgetValue(self._ui.interpolationCustomNumPoints)

                outputOptions['interpolationDomainWaveData'] = numpy.linspace(customLowerLimit, customUpperLimit, customNumPoints, endpoint=True)

                interpolationDomainWaveName = self._app.waves().findGoodWaveName(customWaveName)
                outputWaves['interpolationDomainWave'] = Wave(interpolationDomainWaveName, 'Decimal', outputOptions['interpolationDomainWaveData'])
                self._app.waves().addWave(outputWaves['interpolationDomainWave'])

        outputOptions['saveResiduals'] = Util.getWidgetValue(self._ui.saveResiduals)
        if outputOptions['saveResiduals']:
            residualsDestination = self._app.waves().findGoodWaveName(Util.getWidgetValue(self._ui.residualsDestination))
            outputWaves['residualsWave'] = Wave(residualsDestination, 'Decimal')
            self._app.waves().addWave(outputWaves['residualsWave'])

            # If the fit is not done to all the data in the wave, then we need to add blanks to the beginning
            # of the residual wave because the residuals will only be calculated for the part of the data that
            # was actually fit.
            outputWaves['residualsWave'].extend([''] * dataRangeStart)

            # Save the x wave, in case it is different from the interpolationDomainWave
            outputWaves['xWave'] = xWave

        # Determine the function and call the appropriate method
        functionName = Util.getWidgetValue(self._ui.function)

        if functionName == 'Polynomial':
            self.fitPolynomial(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Sinusoid':
            self.fitSinusoid(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Power Law':
            self.fitPowerLaw(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Exponential':
            self.fitExponential(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Logarithm':
            self.fitLogarithm(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Gaussian':
            self.fitGaussian(xData, yData, weightData, outputWaves, outputOptions)
        elif functionName == 'Lorentzian':
            self.fitLorentzian(xData, yData, weightData, outputWaves, outputOptions)

    def fitPolynomial(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        # Get the degree of the polynomial the user wants to use
        degree = Util.getWidgetValue(self._ui.polynomialDegree)

        def polynomialFunction(p, x):
            # If x is a list, then val needs to be a list
            # If x is a number, then val needs to be a number
            if isinstance(x, list):
                val = numpy.array([p[0]] * len(x))
            else:
                val = p[0]

            # Add x, x^2, x^3, etc entries
            for d in range(1, degree + 1):
                val += numpy.multiply(p[d], numpy.power(x, d))
            return val

        parameterNames = self.parameterNames('Polynomial')
        initialValues = self.parameterInitialValues('Polynomial')
        if initialValues is None:
            initialValues = [1] * degree

        self.fitFunction(polynomialFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Polynomial Fit')

    def fitSinusoid(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        sinusoidFunction = lambda p, x: p[0] + p[1] * numpy.cos(x / p[2] * 2. * numpy.pi + p[3])
        
        parameterNames = self.parameterNames('Sinusoid')
        initialValues = self.parameterInitialValues('Sinusoid')
        if initialValues is None:
            initialValues = [1, 1, 1, 1]

        self.fitFunction(sinusoidFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Sinusoid Fit')

    def fitPowerLaw(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        powerLawFunction = lambda p, x: numpy.add(p[0], numpy.multiply(p[1], numpy.power(x, p[2])))

        parameterNames = self.parameterNames('Power Law')
        initialValues = self.parameterInitialValues('Power Law')
        if initialValues is None:
            initialValues = [0, 1, 1]

        self.fitFunction(powerLawFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Power Law Fit')

    def fitExponential(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        exponentialFunction = lambda p, x: numpy.add(p[0], numpy.multiply(p[1], numpy.power(numpy.e, numpy.multiply(p[2], x))))

        parameterNames = self.parameterNames('Exponential')
        initialValues = self.parameterInitialValues('Exponential')
        if initialValues is None:
            initialValues = [0, 1, 1]

        self.fitFunction(exponentialFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Exponential Fit')

    def fitLogarithm(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        # There is no numpy log function where you can specify a custom base, so we'll define one
        customBaseLog = lambda base, x: numpy.divide(numpy.log(x), numpy.log(base))
        logarithmFunction = lambda p, x: numpy.add(p[0], numpy.multiply(p[1], customBaseLog(p[2], x)))

        parameterNames = self.parameterNames('Logarithm')
        initialValues = self.parameterInitialValues('Logarithm')
        if initialValues is None:
            initialValues = [0, 1, 10]

        self.fitFunction(logarithmFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Logarithm Fit')

    def fitGaussian(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        gaussianFunction = lambda p, x: numpy.multiply(p[0], numpy.power(numpy.e, numpy.divide(-1 * numpy.power((numpy.subtract(x, p[1])), 2), 2 * numpy.power(p[2], 2))))

        parameterNames = self.parameterNames('Gaussian')
        initialValues = self.parameterInitialValues('Gaussian')
        if initialValues is None:
            initialValues = [1, 0, 1]

        self.fitFunction(gaussianFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Gaussian Fit')

    def fitLorentzian(self, xData, yData, weightData=None, outputWaves={}, outputOptions={}):
        lorentzianFunction = lambda p, x: numpy.divide(numpy.multiply(p[0], p[2]), numpy.add(numpy.power(numpy.subtract(x, p[1]), 2), numpy.power(p[2], 2)))

        parameterNames = self.parameterNames('Lorentzian')
        initialValues = self.parameterInitialValues('Lorentzian')
        if initialValues is None:
            initialValues = [1, 0, 1]

        self.fitFunction(lorentzianFunction, parameterNames, initialValues, xData, yData, weightData, outputWaves, outputOptions, 'Lorentzian Fit')



    def fitFunction(self, function, parameterNames, initialValues, xData, yData, weightData=None, outputWaves={}, outputOptions={}, tableName='Fit'):
        # Can also include initial guesses for the parameters, as well as sigma's for weighting of the ydata

        # Need to fail with error message if the leastsq call does not succeed

        # Do the fit
        result = self.fitFunctionLeastSquares(function, initialValues, xData, yData, weightData)
        parameters = result[0]

        tableWaves = []

        # Deal with the parameter-related waves
        if outputOptions['outputParameters']:
            # save parameter labels
            if outputOptions['saveLabels']:
                tableWaves.append(outputWaves['saveLabelsWave'])

                outputWaves['saveLabelsWave'].extend(parameterNames)

            tableWaves.append(outputWaves['parameterWave'])

            # save parameters to a wave
            outputWaves['parameterWave'].extend(parameters)

        # Do the interpolation
        if outputOptions['outputInterpolation']:
            domain = outputOptions['interpolationDomainWaveData']
            
            determinedFunction = lambda x: function(parameters, x)
            for val in domain:
                outputWaves['interpolationDestinationWave'].push(determinedFunction(val))

            tableWaves.append(outputWaves['interpolationDomainWave'])
            tableWaves.append(outputWaves['interpolationDestinationWave'])

        # Do the residuals
        if outputOptions['saveResiduals']:
            residualsFunc = lambda p, x, y: numpy.subtract(y, function(p, x))
            residuals = residualsFunc(parameters, xData, yData)
            outputWaves['residualsWave'].extend(residuals)
            tableWaves.append(outputWaves['xWave'])
            tableWaves.append(outputWaves['residualsWave'])

        # Create table
        if outputOptions['createTable']:
            self.createTable(tableWaves, tableName)

    def fitFunctionLeastSquares(self, func, guess, xData, yData, weightData=None):
        """
        Do a least squares fit for a generic function.

        func must have the signature (p, x) where p is a list of parameters
        and x is a float.

        guess is the user's guess of the parameters, and must be a list of 
        length len(p).

        xData and yData are the data to fit.
        """

        if weightData is None:
            #errorFunc = lambda p, x, y: func(p, x) - y
            errorFunc = lambda p, x, y: numpy.subtract(func(p, x), y)
            return scipy.optimize.leastsq(errorFunc, guess[:], args=(xData, yData), full_output=True)
        else:
            errorFunc = lambda p, x, y, w: numpy.multiply(w, numpy.subtract(func(p, x), y))
            return scipy.optimize.leastsq(errorFunc, guess[:], args=(xData, yData, weightData), full_output=True)

        #return scipy.optimize.leastsq(errorFunc, guess[:], args=(xData, yData), full_output=True)


    def createTable(self, waves=[], title='Fit'):
        if len(waves) == 0:
            return

        self._app.createTable(waves, title)



    def load(self):
        self.window = SubWindow(self._app.ui.workspace)

        self.menuEntry = QAction(self._app)
        self.menuEntry.setObjectName("actionCurveFiting")
        self.menuEntry.setText("Curve Fitting")
        self.menuEntry.triggered.connect(self.window.show)
        
        self.menu = vars(self._app.ui)["menuData"]
        self.menu.addAction(self.menuEntry)

        self.buildWidget()
        self.window.setWidget(self._widget)
        self._widget.setParent(self.window)

        self.window.hide()

    def unload(self):

        self._widget.deleteLater()
        self.window.deleteLater()
        self.menu.removeAction(self.menuEntry)

    def reload(self):
        self.setModels()
        self.setupSpinBoxes()
        self.setupParameterTableData()
        Util.setWidgetValue(self._ui.function, 'Polynomial')
        Util.setWidgetValue(self._ui.useInitialValuesWave, False)
class AutoFieldsDockWidget( QDockWidget, Ui_AutoFieldsDockWidget ):
    """ Class in charge of all the UI logic """

    def __init__( self, parent, iface, autoFieldManager, messageManager, language='en' ):
        self.iface = iface
        self.msg = messageManager
        self.language = language
        QDockWidget.__init__( self, parent )
        # Set up the user interface from Designer.
        self.setupUi( self )

        self.autoFieldManager = autoFieldManager
        self.geometryDict = ['points','lines','polygons']
        self.fieldTypesDict = ['Integer','Real','String','Date']

        self.root = QgsProject.instance().layerTreeRoot()

        # UI stuff that wasn't set/initialized in Qt-Designer
        self.tblLayers.setColumnWidth( 0, 24 )
        self.tblLayers.setColumnWidth( 1, 140 )
        self.tblLayers.setColumnWidth( 2, 110 )
        self.tblLayers.horizontalHeader().setResizeMode( 0, QHeaderView.Fixed )
        self.tblLayers.sortItems(1, Qt.AscendingOrder)
        self.cboField.setEnabled( False )
        self.cboFieldType.setItemData( 0, QVariant.Int, Qt.UserRole )
        self.cboFieldType.setItemData( 1, QVariant.Double, Qt.UserRole )
        self.cboFieldType.setItemData( 2, QVariant.String, Qt.UserRole )
        self.cboFieldType.setItemData( 3, QVariant.Date, Qt.UserRole )
        self.fieldTypeChanged( self.cboFieldType.currentIndex() ) # Update length/precision controls
        self.btnGroup = QButtonGroup()
        self.btnGroup.addButton( self.optXCoord )
        self.btnGroup.addButton( self.optYCoord )
        self.btnGroup.addButton( self.optLength )
        self.btnGroup.addButton( self.optPerimeter )
        self.btnGroup.addButton( self.optArea )
        self.btnGroup.addButton( self.optDate )
        self.btnGroup.addButton( self.optCustomExpression )
        #self.btnGroup.addButton( self.optSpatialValue )
        self.updateExpressionControls( self.optCustomExpression )

        self.frameFields.setEnabled( False )
        self.frameExpression.setEnabled( False )
        self.populateLayersTable()

        QgsMapLayerRegistry.instance().legendLayersAdded.connect( self.populateLayersTable )
        QgsMapLayerRegistry.instance().layersRemoved.connect( self.populateLayersTable )
        # Also listen to Layer Tree node position changes
        self.root.addedChildren.connect( self.populateLayersTable )
        self.root.removedChildren.connect( self.populateLayersTable )

        self.tblLayers.itemSelectionChanged.connect( self.updateFieldAndExpressionControls )
        self.optNewField.toggled.connect( self.newFieldToggled )
        self.cboField.currentIndexChanged.connect( self.fieldChanged )
        self.cboFieldType.currentIndexChanged.connect( self.fieldTypeChanged )
        self.btnSaveAutoField.clicked.connect( self.saveAutoField )
        self.btnNewCustomExpression.clicked.connect( self.setCustomExpression )
        self.btnGroup.buttonClicked.connect( self.updateExpressionControls )

        self.expressionDlg = None

        # 'List of AutoFields' Tab
        settings = QSettings()
        check = settings.value(
            self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields",
            True, type=bool )
        self.chkOnlyEnabledAutoFields.setChecked( check )
        check = settings.value(
            self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures",
            True, type=bool )
        self.chkCalculateOnExisting.setChecked( check )
        self.btnRemoveAutoFields.setEnabled( False )
        self.tblAutoFields.sortItems(0, Qt.AscendingOrder)
        self.populateAutoFieldsTable()
        self.autoFieldManager.autoFieldCreated.connect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldRemoved.connect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldEnabled.connect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldDisabled.connect( self.populateAutoFieldsTable )
        self.tblAutoFields.itemSelectionChanged.connect( self.updateRemoveAutoFieldButton )
        self.chkOnlyEnabledAutoFields.toggled.connect( self.saveShowOnlyEnabledPreference )
        self.chkCalculateOnExisting.toggled.connect( self.saveCalculateOnExistingPreference )
        self.btnRemoveAutoFields.clicked.connect( self.removeAutoFieldFromTable )

        # Context menu
        self.tblAutoFields.setContextMenuPolicy( Qt.CustomContextMenu )
        self.tblAutoFields.customContextMenuRequested.connect( self.openAutoFieldContextMenu )

        # About Tab
        self.btnHelp.clicked.connect( self.openDocumentation )


    def populateLayersTable( self, foo=None, foo2=None, foo3=None ):
        """ List vector layers that support changes in attributes and are writable.
            Arguments are 3 and optional because this function listens to several
            SIGNALs.
        """

        # Initialize Layers Table
        self.tblLayers.clearContents()
        self.tblLayers.setRowCount( 0 )

        vLayers = []
        for layer in QgsMapLayerRegistry.instance().mapLayers().values():
            if layer.type() == QgsMapLayer.VectorLayer:
                if layer.dataProvider().capabilities() & QgsVectorDataProvider.ChangeAttributeValues:
                    if not layer.isReadOnly():
                        if layer.geometryType() < 3: # Avoid UnknownGeometry and NoGeometry
                            vLayers.append( layer )

        self.tblLayers.setRowCount( len( vLayers ) )
        self.tblLayers.setColumnCount( 3 )

        self.tblLayers.setSortingEnabled( False )
        for row, lyr in enumerate( vLayers ):
            item = QTableWidgetItem( QIcon( ":/plugins/AutoFields/icons/" + \
                self.geometryDict[lyr.geometryType()] + ".png"),
                str( lyr.geometryType() ) )
            self.tblLayers.setItem( row, 0, item )

            item = QTableWidgetItem( lyr.name() )
            item.setData( Qt.UserRole, lyr.id() )
            self.tblLayers.setItem( row, 1, item )

            tmpTreeLayer = self.root.findLayer( lyr.id() )
            if tmpTreeLayer:
                group = tmpTreeLayer.parent().name()
                self.tblLayers.setItem(row, 2,
                    QTableWidgetItem( group if group else QApplication.translate("AutoFieldsDockWidgetPy",
                        "< root >" ) ) )

        self.tblLayers.setSortingEnabled( True )


    def updateFieldAndExpressionControls( self ):
        """ After a selection is changed, reflect possible values in field controls """
        self.msg.show( "New selection " + str(len( self.tblLayers.selectedItems() ) / 3), 'info', True )

        if not self.tblLayers.selectedItems():
            self.frameFields.setEnabled( False )
            self.frameExpression.setEnabled( False )
            return
        else:
            self.frameFields.setEnabled( True )
            self.frameExpression.setEnabled( True )

        # List common fields in cboField and get geometries selected
        geometryTypeSet = self.updateFieldList()


        # Update expression controls
        if 0 in geometryTypeSet and len( geometryTypeSet ) == 1: # Points
            self.optXCoord.setEnabled( True )
            self.optYCoord.setEnabled( True )
            self.optLength.setEnabled( False )
            self.optPerimeter.setEnabled( False )
            self.optArea.setEnabled( False )
        elif 1 in geometryTypeSet and len( geometryTypeSet ) == 1: # Lines
            self.optXCoord.setEnabled( False )
            self.optYCoord.setEnabled( False )
            self.optLength.setEnabled( True )
            self.optPerimeter.setEnabled( False )
            self.optArea.setEnabled( False )
        elif 2 in geometryTypeSet and len( geometryTypeSet ) == 1: # Polygons
            self.optXCoord.setEnabled( False )
            self.optYCoord.setEnabled( False )
            self.optLength.setEnabled( False )
            self.optPerimeter.setEnabled( True )
            self.optArea.setEnabled( True )
        else:
            self.optXCoord.setEnabled( False )
            self.optYCoord.setEnabled( False )
            self.optLength.setEnabled( False )
            self.optPerimeter.setEnabled( False )
            self.optArea.setEnabled( False )

        if not self.btnGroup.checkedButton().isEnabled():
            self.optCustomExpression.setChecked( True ) # Default selection
            self.updateExpressionControls( self.optCustomExpression )

        self.expressionDlg = None # Initialize the dialog


    def updateFieldList( self ):
        """ Update field list and return geometries selected """
        commonFields = []
        geometryTypeSet = set()
        bFirstFlag = True
        for item in self.tblLayers.selectedItems():
            if item.column() == 1: # It's the layer name item
                self.msg.show( "ID " + item.data( Qt.UserRole ), 'info', True ) # Get layer id
                layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )
                geometryTypeSet.add( layer.geometryType() )
                tmpFields = [field.name() for field in layer.dataProvider().fields()] # Get field names stored in the provider
                if bFirstFlag: # Initialize commonFields
                    commonFields = tmpFields
                    bFirstFlag = False
                else: # Intersect fields
                    if commonFields: # Avoid intersecting if no common fields
                        commonFields = list( set( commonFields ) & set( tmpFields ) )

        commonFields.sort()
        self.msg.show( "FIELDS: "+ str(commonFields), 'info', True)

        self.cboField.clear()
        if not commonFields:
            self.optExistingField.setEnabled( False )
            self.optNewField.setChecked( True )
        else:
            self.optExistingField.setEnabled( True )
            self.cboField.addItems( commonFields )

        return geometryTypeSet


    def newFieldToggled( self ):
        """ Alternate between controls of new field and existing field """
        newIsChecked = self.optNewField.isChecked()

        self.cboField.setEnabled( not newIsChecked )

        self.lblFieldName.setEnabled( newIsChecked )
        self.lblFieldType.setEnabled( newIsChecked )
        self.txtFieldName.setEnabled( newIsChecked )
        self.cboFieldType.setEnabled( newIsChecked )

        if newIsChecked:
            self.fieldTypeChanged( self.cboFieldType.currentIndex() )
        else:
            self.lblFieldLength.setEnabled( newIsChecked )
            self.lblFieldPrecision.setEnabled( newIsChecked )
            self.txtFieldLength.setEnabled( newIsChecked )
            self.txtFieldPrecision.setEnabled( newIsChecked )

        self.expressionDlg = None # Initialize the dialog


    def fieldTypeChanged( self, idx ):
        """ Update field length and field precision controls' state and values """
        text = self.fieldTypesDict[idx]
        if text == 'Integer':
            self.txtFieldLength.setRange( 1, 10 )
            self.txtFieldLength.setEnabled( True )
            self.txtFieldPrecision.setEnabled( False )
            self.lblFieldLength.setEnabled( True )
            self.lblFieldPrecision.setEnabled( False )
        elif text == 'Real':
            self.txtFieldLength.setRange( 1, 20 )
            self.txtFieldPrecision.setRange( 0, 15 )
            self.txtFieldLength.setEnabled( True )
            self.txtFieldPrecision.setEnabled( True )
            self.lblFieldLength.setEnabled( True )
            self.lblFieldPrecision.setEnabled( True )
        elif text == 'String':
            self.txtFieldLength.setRange( 1, 255 )
            self.txtFieldLength.setEnabled( True )
            self.txtFieldPrecision.setEnabled( False )
            self.lblFieldLength.setEnabled( True )
            self.lblFieldPrecision.setEnabled( False )
        else: # Date
            self.txtFieldLength.setEnabled( False )
            self.txtFieldPrecision.setEnabled( False )
            self.lblFieldLength.setEnabled( False )
            self.lblFieldPrecision.setEnabled( False )


    def fieldChanged( self, idx ):
        """ Just to initialize the expression dialog if selected field changes """
        self.expressionDlg = None # Initialize the dialog


    def saveAutoField( self ):
        """ Do some validation and then call AutoFieldManager """

        # Check layers
        if not self.tblLayers.selectedItems():
            self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                "[Warning] Please first select a layer." ), 'warning' )
            return

        # Check expression
        expression = u''
        if self.optXCoord.isChecked():
            expression = u'$x'
        elif self.optYCoord.isChecked():
            expression = u'$y'
        elif self.optLength.isChecked():
            expression = u'$length'
        elif self.optPerimeter.isChecked():
            expression = u'$perimeter'
        elif self.optArea.isChecked():
            expression = u'$area'
        elif self.optDate.isChecked():
            expression = u'now()'
        elif self.optCustomExpression.isChecked():
            if self.expressionDlg:
                expression = self.expressionDlg.expression
            if not self.expressionDlg or not expression:
                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                    "[Warning] Please first set a valid custom expression." ),
                    'warning' )
                return
        else: # optSpatialValue
            pass

        # Check fields
        fieldName = ''
        if self.optNewField.isChecked():
            if self.txtFieldName.text():

                fieldName = self.txtFieldName.text().strip()
                newField = QgsField( fieldName,
                    self.cboFieldType.itemData( self.cboFieldType.currentIndex(), Qt.UserRole) )

                length = self.txtFieldLength.value()
                precision = self.txtFieldPrecision.value()
                # Ensure length and precision are valid values when dealing with Real numbers
                if self.fieldTypesDict[self.cboFieldType.currentIndex()] == 'Real':
                    if precision > length:
                        precision = length
                newField.setLength( length )
                newField.setPrecision( precision )

                for item in self.tblLayers.selectedItems():
                    if item.column() == 1: # It's the layer name item
                        layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )
                        if layer.fieldNameIndex( fieldName ) != -1:
                            self.msg.show(
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] The field " ) + fieldName + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " already exists in layer " ) + layer.name() + ". " + \
                                QApplication.translate( "AutoFieldsDockWidgetPy",
                                    " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                'warning' )
                        else:
                            res = layer.dataProvider().addAttributes( [ newField ] )
                            if res:
                                layer.updateFields()

                                # Check if fieldName is preserved by the provider after field creation.
                                if layer.fieldNameIndex( fieldName ) == -1:
                                    self.msg.show(
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            "[Error] The field " ) + fieldName + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " was probably created with another name by the layer (" ) + \
                                        layer.name() + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            ") provider. " ) + \
                                        QApplication.translate( "AutoFieldsDockWidgetPy",
                                            " If you want to create an AutoField on it, you need to choose it from 'Existing Field' list." ),
                                        'warning' )
                                else:

                                    self.doSaveAutoField( layer, fieldName, expression )

                            else:
                                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                                    "[Error] Couldn't create " ) + newField.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy",
                                        " field in " ) + layer.name() + \
                                    QApplication.translate( "AutoFieldsDockWidgetPy", " layer." ),
                                    'warning' )

                # Some fields might have been created, update the field list once
                self.updateFieldList()

            else:
                self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                    "[Warning] Please first set a name for the new field." ), 'warning' )
                return
        else:
            fieldName = self.cboField.currentText()

            for item in self.tblLayers.selectedItems():
                if item.column() == 1: # It's the layer name item
                    layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )
                    self.doSaveAutoField( layer, fieldName, expression )


    def doSaveAutoField( self, layer, fieldName, expression ):
        """ Repetitive logic to save or overwrite an AutoField """
        # Check if the field is an AutoField and ask if we should overwrite it
        res = True
        bCalculateOnExisting = self.chkCalculateOnExisting.isChecked()
        if self.autoFieldManager.isFieldAnAutoField( layer, fieldName ):
            reply = QMessageBox.question( self.iface.mainWindow(),
                QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ),
                QApplication.translate( "AutoFieldsDockWidgetPy", "The field '" ) + \
                fieldName + QApplication.translate( "AutoFieldsDockWidgetPy",
                    "' from layer '" ) + layer.name() + \
                QApplication.translate( "AutoFieldsDockWidgetPy",
                    "' is already an AutoField.\nDo you want to overwrite it?" ),
                QMessageBox.Yes | QMessageBox.No, QMessageBox.No )

            if reply == QMessageBox.Yes:
                res = self.autoFieldManager.overwriteAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting )

        else:
            res = self.autoFieldManager.createAutoField( layer, fieldName, expression, calculateOnExisting=bCalculateOnExisting )

        if not res:
            # res will only be False if create/overwriteAutoField return False
            self.msg.show( "[Error] The AutoField for layer '" + layer.name() + \
                "' and field '" + fieldName + "' couldn't be created.", 'warning', True )


    def setCustomExpression( self ):
        """ Initialize and show the expression builder dialog """
        layer = None
        if len( self.tblLayers.selectedItems() ) / 3 == 1: # Single layer selected?
            for item in self.tblLayers.selectedItems():
                if item.column() == 1: # It's the layer name item
                    layer = QgsMapLayerRegistry.instance().mapLayer( item.data( Qt.UserRole ) )

        if not self.expressionDlg:
            self.expressionDlg = ExpressionBuilderDialog( self.iface.mainWindow() )
            context = QgsExpressionContext()
            context.appendScope( QgsExpressionContextUtils.globalScope() )
            context.appendScope( QgsExpressionContextUtils.projectScope() )

            # Initialize dialog with layer-based names and variables if single layer selected
            if len( self.tblLayers.selectedItems() ) / 3 == 1:
                context.appendScope( QgsExpressionContextUtils.layerScope( layer ) )
                self.expressionDlg.expressionBuilderWidget.setLayer( layer )
                self.expressionDlg.expressionBuilderWidget.loadFieldNames()

                # This block was borrowed from QGIS/python/plugins/processing/algs/qgis/FieldsCalculator.py
                da = QgsDistanceArea()
                da.setSourceCrs( layer.crs().srsid() )
                da.setEllipsoidalMode( self.iface.mapCanvas().mapSettings().hasCrsTransformEnabled() )
                da.setEllipsoid( QgsProject.instance().readEntry( 'Measure', '/Ellipsoid', GEO_NONE )[0] )
                self.expressionDlg.expressionBuilderWidget.setGeomCalculator( da )

                # If this layer-field is an AutoField, get its expression
                if self.optExistingField.isChecked():
                    fieldName = self.cboField.currentText()
                    expression = self.autoFieldManager.getFieldExpression( layer, fieldName )
                    self.expressionDlg.expressionBuilderWidget.setExpressionText( expression )
                    self.expressionDlg.expression = expression # To remember it when closing/opening

            self.expressionDlg.expressionBuilderWidget.setExpressionContext( context )

        self.expressionDlg.show()


    def updateExpressionControls( self, button ):
        """ Enable/disable push buttons when appropriate """
        if button.objectName() == 'optCustomExpression':
            self.btnNewCustomExpression.setEnabled( True )
            #self.btnNewSpatialValue.setEnabled( False )
        #elif button.objectName() == 'optSpatialValue':
            #self.btnNewCustomExpression.setEnabled( False )
            #self.btnNewSpatialValue.setEnabled( True )
        else:
            self.btnNewCustomExpression.setEnabled( False )
            #self.btnNewSpatialValue.setEnabled( False )


    def populateAutoFieldsTable( self, autoFieldId=None ):
        """ Listens to any modification on AutoFields to update the list """
        dictAutoFields = self.autoFieldManager.listAutoFields()
        if autoFieldId: # Just update this one
            if not autoFieldId in dictAutoFields: # AutoField removed
                self.msg.show( "[Info] Removing AutoField from table.", 'info', True )
                # Iterate through AF rows and remove row where data matches AFID
                deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0)
                if deleteRow != -1:
                    self.tblAutoFields.removeRow( deleteRow )
            else:
                # if it's in the table: remove it and re-add it (from new dict)
                deleteRow = self.findRowOfItemDataInAutoFieldsTable( autoFieldId, 0)
                if deleteRow != -1:
                    self.msg.show( "[Info] Refreshing AutoField status in table.", 'info', True )
                    self.tblAutoFields.removeRow( deleteRow )
                    self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId] )
                else: # New AutoField, just add it to table
                    self.msg.show( "[Info] Adding new AutoField to table.", 'info', True )
                    self.addAutoFieldToAutoFieldsTable( autoFieldId, dictAutoFields[autoFieldId] )
        else:
            # Initialize AutoFields Table
            self.tblAutoFields.clearContents()
            self.tblAutoFields.setRowCount( 0 )

            #self.tblAutoFields.setRowCount( len( dictAutoFields ) )
            self.tblAutoFields.setColumnCount( 4 )

            self.tblAutoFields.setSortingEnabled( False )
            for key in dictAutoFields.keys():
                autoField = dictAutoFields[key]
                self.addAutoFieldToAutoFieldsTable( key, autoField, False )

            self.tblAutoFields.setSortingEnabled( True )


    def findRowOfItemDataInAutoFieldsTable( self, data, col ):
        """ Get the row number that matches its data to a given data (check only the given column) """
        for numRow in range( self.tblAutoFields.rowCount() ):
            item = self.tblAutoFields.item( numRow, col )
            if item.data( Qt.UserRole ) == data:
                return numRow
        return -1


    def addAutoFieldToAutoFieldsTable( self, autoFieldId, autoField, freezeSorting=True ):
        """ Add a whole row to the AutoFields table """
        if self.chkOnlyEnabledAutoFields.isChecked() and not autoField['enabled']:
            return

        if freezeSorting:
            self.tblAutoFields.setSortingEnabled( False )

        row = self.tblAutoFields.rowCount()
        self.tblAutoFields.insertRow( row )
        name = autoField['layer']
        if 'layerId' in autoField:
            lyr = QgsMapLayerRegistry.instance().mapLayer( autoField['layerId'] )
            name = lyr.name()
        item = QTableWidgetItem( name )
        item.setData( Qt.UserRole, autoFieldId )
        item.setData( Qt.ToolTipRole, autoField['layer'] )
        if not autoField['enabled']:
            item.setForeground( QBrush( Qt.gray ) )
        self.tblAutoFields.setItem( row, 0, item )
        item = QTableWidgetItem( autoField['field'] )
        if not autoField['enabled']:
            item.setForeground( QBrush( Qt.gray ) )
        self.tblAutoFields.setItem( row, 1, item )
        item = QTableWidgetItem( autoField['expression'] )
        if not autoField['enabled']:
            item.setForeground( QBrush( Qt.gray ) )
        self.tblAutoFields.setItem( row, 2, item )
        item = QTableWidgetItem( QApplication.translate( "AutoFieldsDockWidgetPy",
            "Enabled" ) if autoField['enabled'] else QApplication.translate( "AutoFieldsDockWidgetPy", "Disabled" ) )
        item.setData( Qt.UserRole, 'enabled' if autoField['enabled'] else 'disabled' )
        if not autoField['enabled']:
            item.setForeground( QBrush( Qt.gray ) )
        self.tblAutoFields.setItem( row, 3, item )

        if freezeSorting:
            self.tblAutoFields.setSortingEnabled( True )


    def openAutoFieldContextMenu( self, position ):
        bLayers = False
        layers = QgsMapLayerRegistry.instance().mapLayers().values()
        for layer in layers:
            if layer.type() == QgsMapLayer.VectorLayer:
                if layer.dataProvider().capabilities() & QgsVectorDataProvider.AddFeatures:
                    bLayers = True
                    break

        item = self.tblAutoFields.itemAt( position )
        if item:
            row = item.row()
            self.menu = QMenu()
            self.action = QAction( "Assign this AutoField to another layer", None )
            self.action.setObjectName('action')
            if self.tblAutoFields.item( row, 3 ).data( Qt.UserRole ) == 'enabled':
                self.action.setEnabled( False )
            self.menu.addAction( self.action )
            action = self.menu.exec_(self.tblAutoFields.mapToGlobal(position))
            if action and action.objectName() == 'action':
                if not bLayers:
                    self.msg.show( QApplication.translate( "AutoFieldsDockWidgetPy",
                        "First load some vector layers to QGIS to be able to assign disabled AutoFields." ), 'warning' )
                    return

                autoFieldId = self.tblAutoFields.item( row, 0 ).data( Qt.UserRole )
                bCalculateOnExisting = self.chkCalculateOnExisting.isChecked()
                dlg = AssignAutoFieldToLayerDialog( self.iface.mainWindow(), self.autoFieldManager, autoFieldId, bCalculateOnExisting )
                dlg.show()


    def updateRemoveAutoFieldButton( self ):
        """ Enable/disable button to remove AutoFields when appropriate """
        self.btnRemoveAutoFields.setEnabled( len( self.tblAutoFields.selectedItems() ) / 4 )


    def removeAutoFieldFromTable( self ):
        """ Show a confirmation dialog for all AutoFields selected.
            If confirmed, remove AutoFields from table.
        """
        # Column 0 has the AutoField id
        autoFieldsToRemove = [ item.data( Qt.UserRole ) for item in self.tblAutoFields.selectedItems() if item.column() == 0 ]

        reply = QMessageBox.question( self.iface.mainWindow(),
            QApplication.translate( "AutoFieldsDockWidgetPy", "Confirmation" ),
            QApplication.translate( "AutoFieldsDockWidgetPy",
                "Do you really want to remove " ) + \
            str(len( autoFieldsToRemove )) + \
            (" AutoFields?" if len( autoFieldsToRemove ) > 1 else " AutoField?"),
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No )

        if reply == QMessageBox.Yes:
            for autoFieldId in autoFieldsToRemove:
                self.autoFieldManager.removeAutoField( autoFieldId )


    def saveShowOnlyEnabledPreference( self, status ):
        """ Saves the preference in QSettings and updates list of AutoFields """
        settings = QSettings()
        settings.setValue( self.autoFieldManager.settingsPrefix + "/showOnlyEnabledAutoFields" , status )
        self.populateAutoFieldsTable()


    def saveCalculateOnExistingPreference( self, status ):
        """ Saves the preference in QSettings """
        settings = QSettings()
        settings.setValue( self.autoFieldManager.settingsPrefix + "/calculateOnExistingFeatures" , status )


    def openDocumentation( self ):
        """ Open a browser to show documentation page """
        import webbrowser
        webbrowser.open( "http://geotux.tuxfamily.org/index.php/"+ self.language +"/geo-blogs/item/333-autofields-plugin-for-qgis" )


    def disconnectAll( self ):
        """ Terminates all SIGNAL/SLOT connections created by this class """
        QgsMapLayerRegistry.instance().legendLayersAdded.disconnect( self.populateLayersTable )
        QgsMapLayerRegistry.instance().layersRemoved.disconnect( self.populateLayersTable )
        self.root.addedChildren.disconnect( self.populateLayersTable )
        self.root.removedChildren.disconnect( self.populateLayersTable )

        self.tblLayers.itemSelectionChanged.disconnect( self.updateFieldAndExpressionControls )
        self.optNewField.toggled.disconnect( self.newFieldToggled )
        self.cboField.currentIndexChanged.disconnect( self.fieldChanged )
        self.cboFieldType.currentIndexChanged.disconnect( self.fieldTypeChanged )
        self.btnSaveAutoField.clicked.disconnect( self.saveAutoField )
        self.btnNewCustomExpression.clicked.disconnect( self.setCustomExpression )
        self.btnGroup.buttonClicked.disconnect( self.updateExpressionControls )

        self.autoFieldManager.autoFieldCreated.disconnect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldRemoved.disconnect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldEnabled.disconnect( self.populateAutoFieldsTable )
        self.autoFieldManager.autoFieldDisabled.disconnect( self.populateAutoFieldsTable )
        self.tblAutoFields.itemSelectionChanged.disconnect( self.updateRemoveAutoFieldButton )
        self.chkOnlyEnabledAutoFields.toggled.disconnect( self.saveShowOnlyEnabledPreference )
        self.btnRemoveAutoFields.clicked.disconnect( self.removeAutoFieldFromTable )
Example #47
0
class FreeseerApp(QMainWindowWithDpi):

    def __init__(self, config):
        super(FreeseerApp, self).__init__()
        self.config = config
        self.icon = QIcon()
        self.icon.addPixmap(QPixmap(_fromUtf8(":/freeseer/logo.png")), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(self.icon)

        self.aboutDialog = AboutDialog()
        self.aboutDialog.setModal(True)

        self.logDialog = LogDialog()

        #
        # Translator
        #
        self.app = QApplication.instance()
        self.current_language = None
        self.uiTranslator = QTranslator()
        self.uiTranslator.load(":/languages/tr_en_US.qm")
        self.app.installTranslator(self.uiTranslator)
        self.langActionGroup = QActionGroup(self)
        self.langActionGroup.setExclusive(True)
        QTextCodec.setCodecForTr(QTextCodec.codecForName('utf-8'))
        self.connect(self.langActionGroup, SIGNAL('triggered(QAction *)'), self.translate)
        # --- Translator

        #
        # Setup Menubar
        #
        self.menubar = self.menuBar()

        self.menubar.setGeometry(self.qrect_with_dpi(0, 0, 500, 50))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuLanguage = QMenu(self.menubar)
        self.menuLanguage.setObjectName(_fromUtf8("menuLanguage"))
        self.menuHelp = QMenu(self.menubar)
        self.menuHelp.setObjectName(_fromUtf8("menuHelp"))

        exitIcon = QIcon.fromTheme("application-exit")
        self.actionExit = QAction(self)
        self.actionExit.setShortcut("Ctrl+Q")
        self.actionExit.setObjectName(_fromUtf8("actionExit"))
        self.actionExit.setIcon(exitIcon)

        helpIcon = QIcon.fromTheme("help-contents")
        self.actionOnlineHelp = QAction(self)
        self.actionOnlineHelp.setObjectName(_fromUtf8("actionOnlineHelp"))
        self.actionOnlineHelp.setIcon(helpIcon)

        self.actionAbout = QAction(self)
        self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
        self.actionAbout.setIcon(self.icon)

        self.actionLog = QAction(self)
        self.actionLog.setObjectName(_fromUtf8("actionLog"))
        self.actionLog.setShortcut("Ctrl+L")

        # Actions
        self.menuFile.addAction(self.actionExit)
        self.menuHelp.addAction(self.actionAbout)
        self.menuHelp.addAction(self.actionLog)
        self.menuHelp.addAction(self.actionOnlineHelp)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuLanguage.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.setupLanguageMenu()
        # --- End Menubar

        self.connect(self.actionExit, SIGNAL('triggered()'), self.close)
        self.connect(self.actionAbout, SIGNAL('triggered()'), self.aboutDialog.show)
        self.connect(self.actionLog, SIGNAL('triggered()'), self.logDialog.show)
        self.connect(self.actionOnlineHelp, SIGNAL('triggered()'), self.openOnlineHelp)

        self.retranslateFreeseerApp()
        self.aboutDialog.aboutWidget.retranslate("en_US")

    def openOnlineHelp(self):
        """Opens a link to the Freeseer Online Help"""
        url = QUrl("http://freeseer.readthedocs.org")
        QDesktopServices.openUrl(url)

    def translate(self, action):
        """Translates the GUI via menu action.

        When a language is selected from the language menu, this function is
        called and the language to be changed to is retrieved.
        """
        self.current_language = str(action.data().toString()).strip("tr_").rstrip(".qm")

        log.info("Switching language to: %s" % action.text())
        self.uiTranslator.load(":/languages/tr_%s.qm" % self.current_language)
        self.app.installTranslator(self.uiTranslator)

        self.retranslateFreeseerApp()
        self.aboutDialog.aboutWidget.retranslate(self.current_language)
        self.retranslate()
        self.logDialog.retranslate()

    def retranslate(self):
        """
        Reimplement this function to provide translations to your app.
        """
        pass

    def retranslateFreeseerApp(self):
        #
        # Menubar
        #
        self.menuFile.setTitle(self.app.translate("FreeseerApp", "&File"))
        self.menuLanguage.setTitle(self.app.translate("FreeseerApp", "&Language"))
        self.menuHelp.setTitle(self.app.translate("FreeseerApp", "&Help"))

        self.actionExit.setText(self.app.translate("FreeseerApp", "&Quit"))
        self.actionAbout.setText(self.app.translate("FreeseerApp", "&About"))
        self.actionLog.setText(self.app.translate("FreeseerApp", "View &Log"))
        self.actionOnlineHelp.setText(self.app.translate("FreeseerApp", "Online Documentation"))
        # --- Menubar

    def setupLanguageMenu(self):
        self.languages = QDir(":/languages").entryList()

        if self.current_language is None:
            self.current_language = QLocale.system().name()  # Retrieve Current Locale from the operating system.
            log.debug("Detected user's locale as %s" % self.current_language)

        for language in self.languages:
            translator = QTranslator()  # Create a translator to translate Language Display Text.
            translator.load(":/languages/%s" % language)
            language_display_text = translator.translate("Translation", "Language Display Text")

            languageAction = QAction(self)
            languageAction.setCheckable(True)
            languageAction.setText(language_display_text)
            languageAction.setData(language)
            self.menuLanguage.addAction(languageAction)
            self.langActionGroup.addAction(languageAction)
Example #48
0
class Plugin:
    """The QGIS interface implementation for the Risk in a box plugin.

    This class acts as the 'glue' between QGIS and our custom logic.
    It creates a toolbar and menubar 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.

        Args:
            iface - a Quantum GIS QGisAppInterface instance. This instance
                is automatically passed to the plugin by QGIS when it loads the
                plugin.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """

        # Save reference to the QGIS interface
        self.iface = iface
        self.translator = None
        self.setupI18n()
        #print self.tr('InaSAFE')
        utilities.setupLogger()

    #noinspection PyArgumentList
    def setupI18n(self, thePreferredLocale=None):
        """Setup internationalisation for the plugin.

        See if QGIS wants to override the system locale
        and then see if we can get a valid translation file
        for whatever locale is effectively being used.

        Args:
           thePreferredLocale - optional parameter which if set
           will override any other way of determining locale..
        Returns:
           None.
        Raises:
           TranslationLoadException
        """
        myOverrideFlag = QSettings().value(
            'locale/overrideFlag',
            QVariant(False)).toBool()

        if thePreferredLocale is not None:
            myLocaleName = thePreferredLocale
        elif myOverrideFlag:
            myLocaleName = QSettings().value('locale/userLocale',
                                             QVariant('')).toString()
        else:
            myLocaleName = QLocale.system().name()
            # NOTES: we split the locale name because we need the first two
            # character i.e. 'id', 'af, etc
            myLocaleName = str(myLocaleName).split('_')[0]

        # Also set the system locale to the user overridden local
        # so that the inasafe library functions gettext will work
        # .. see:: :py:func:`common.utilities`
        os.environ['LANG'] = str(myLocaleName)

        LOGGER.debug('%s %s %s %s' % (
            thePreferredLocale,
            myOverrideFlag,
            QLocale.system().name(),
            os.environ['LANG']))

        myRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        myTranslationPath = os.path.join(
            myRoot, 'safe_qgis', 'i18n',
            'inasafe_' + str(myLocaleName) + '.qm')

        if os.path.exists(myTranslationPath):
            self.translator = QTranslator()
            myResult = self.translator.load(myTranslationPath)
            if not myResult:
                myMessage = 'Failed to load translation for %s' % myLocaleName
                raise TranslationLoadError(myMessage)
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' % (
            myTranslationPath,
            os.path.exists(myTranslationPath)))

    def tr(self, theString):
        """We implement this ourself since we do not inherit QObject.

        Args:
           theString - string for translation.
        Returns:
           Translated version of theString.
        Raises:
           no exceptions explicitly raised.
        """
        return QCoreApplication.translate('Plugin', theString)

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

        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).

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe_qgis.dock import Dock
        self.dockWidget = None
        #--------------------------------------
        # Create action for plugin dockable window (show/hide)
        #--------------------------------------
        # pylint: disable=W0201
        self.actionDock = QAction(
            QIcon(':/plugins/inasafe/icon.svg'),
            self.tr('Toggle InaSAFE Dock'), self.iface.mainWindow())
        self.actionDock.setObjectName('InaSAFEDockToggle')
        self.actionDock.setStatusTip(self.tr(
            'Show/hide InaSAFE dock widget'))
        self.actionDock.setWhatsThis(self.tr(
            'Show/hide InaSAFE dock widget'))
        self.actionDock.setCheckable(True)
        self.actionDock.setChecked(True)
        QObject.connect(
            self.actionDock, SIGNAL('triggered()'),
            self.showHideDockWidget)
        # add to plugin toolbar
        self.iface.addToolBarIcon(self.actionDock)
        # add to plugin menu
        self.iface.addPluginToMenu(
            self.tr('InaSAFE'),
            self.actionDock)

        #--------------------------------------
        # Create action for keywords editor
        #--------------------------------------
        self.actionKeywordsDialog = QAction(
            QIcon(':/plugins/inasafe/show-keyword-editor.svg'),
            self.tr('InaSAFE Keyword Editor'),
            self.iface.mainWindow())
        self.actionKeywordsDialog.setStatusTip(self.tr(
            'Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setWhatsThis(self.tr(
            'Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setEnabled(False)

        QObject.connect(
            self.actionKeywordsDialog, SIGNAL('triggered()'),
            self.showKeywordsEditor)

        self.iface.addToolBarIcon(self.actionKeywordsDialog)
        self.iface.addPluginToMenu(
            self.tr('InaSAFE'),
            self.actionKeywordsDialog)

        #--------------------------------------
        # Create action for reset icon
        #--------------------------------------
        self.actionResetDock = QAction(
            QIcon(':/plugins/inasafe/reset-dock.svg'),
            self.tr('Reset Dock'), self.iface.mainWindow())
        self.actionResetDock.setStatusTip(self.tr(
            'Reset the InaSAFE Dock'))
        self.actionResetDock.setWhatsThis(self.tr(
            'Reset the InaSAFE Dock'))
        QObject.connect(
            self.actionResetDock, SIGNAL('triggered()'),
            self.resetDock)

        self.iface.addToolBarIcon(self.actionResetDock)
        self.iface.addPluginToMenu(
            self.tr('InaSAFE'),
            self.actionResetDock)

        #--------------------------------------
        # Create action for options dialog
        #--------------------------------------
        self.actionOptions = QAction(
            QIcon(':/plugins/inasafe/configure-inasafe.svg'),
            self.tr('InaSAFE Options'), self.iface.mainWindow())
        self.actionOptions.setStatusTip(self.tr(
            'Open InaSAFE options dialog'))
        self.actionOptions.setWhatsThis(self.tr(
            'Open InaSAFE options dialog'))
        QObject.connect(
            self.actionOptions, SIGNAL('triggered()'),
            self.showOptions)

        self.iface.addToolBarIcon(self.actionOptions)
        self.iface.addPluginToMenu(
            self.tr('InaSAFE'),
            self.actionOptions)

        #--------------------------------------
        # Create action for impact functions doc dialog
        #--------------------------------------
        self.actionImpactFunctionsDoc = QAction(
            QIcon(':/plugins/inasafe/show-impact-functions.svg'),
            self.tr('InaSAFE Impact Functions Browser'),
            self.iface.mainWindow())
        self.actionImpactFunctionsDoc.setStatusTip(self.tr(
            'Open InaSAFE Impact Functions Browser'))
        self.actionImpactFunctionsDoc.setWhatsThis(self.tr(
            'Open InaSAFE Impact Functions Browser'))
        QObject.connect(
            self.actionImpactFunctionsDoc, SIGNAL('triggered()'),
            self.showImpactFunctionsDoc)

        self.iface.addToolBarIcon(self.actionImpactFunctionsDoc)
        self.iface.addPluginToMenu(self.tr('InaSAFE'),
                                   self.actionImpactFunctionsDoc)

        # Short cut for Open Impact Functions Doc
        self.keyAction = QAction("Test Plugin", self.iface.mainWindow())
        self.iface.registerMainWindowAction(self.keyAction, "F7")
        QObject.connect(self.keyAction, SIGNAL("triggered()"),
                        self.keyActionF7)

        #---------------------------------------
        # Create action for minimum needs dialog
        #---------------------------------------
        self.actionMinimumNeeds = QAction(
            QIcon(':/plugins/inasafe/show-minimum-needs.svg'),
            self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow())
        self.actionMinimumNeeds.setStatusTip(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.actionMinimumNeeds.setWhatsThis(self.tr(
            'Open InaSAFE minimum needs tool'))
        QObject.connect(self.actionMinimumNeeds, SIGNAL('triggered()'),
                        self.showMinimumNeeds)

        self.iface.addToolBarIcon(self.actionMinimumNeeds)
        self.iface.addPluginToMenu(self.tr('InaSAFE'),
                                   self.actionMinimumNeeds)

        #---------------------------------------
        # Create action for converter dialog
        #---------------------------------------
        self.actionConverter = QAction(
            QIcon(':/plugins/inasafe/show-minimum-needs.svg'),
            self.tr('InaSAFE Converter'), self.iface.mainWindow())
        self.actionConverter.setStatusTip(self.tr(
            'Open InaSAFE Converter'))
        self.actionConverter.setWhatsThis(self.tr(
            'Open InaSAFE Converter'))
        QObject.connect(self.actionConverter, SIGNAL('triggered()'),
                        self.showConverter)

        self.iface.addToolBarIcon(self.actionConverter)
        self.iface.addPluginToMenu(self.tr('InaSAFE'),
                                   self.actionConverter)

        #--------------------------------------
        # Create action for import OSM Dialog
        #--------------------------------------
        self.actionImportDlg = QAction(
            QIcon(':/plugins/inasafe/osm-download.png'),
            self.tr('InaSAFE OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.actionImportDlg.setStatusTip(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.actionImportDlg.setWhatsThis(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        QObject.connect(
            self.actionImportDlg, SIGNAL('triggered()'),
            self.showImportDlg)

        self.iface.addToolBarIcon(self.actionImportDlg)
        self.iface.addPluginToMenu(
            self.tr('InaSAFE'),
            self.actionImportDlg)

        #--------------------------------------
        # create dockwidget and tabify it with the legend
        #--------------------------------------
        self.dockWidget = Dock(self.iface)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockWidget)
        myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend')

        if myLegendTab:
            self.iface.mainWindow().tabifyDockWidget(
                myLegendTab, self.dockWidget)
            self.dockWidget.raise_()
        #
        # Hook up a slot for when the current layer is changed
        #
        QObject.connect(
            self.iface,
            SIGNAL("currentLayerChanged(QgsMapLayer*)"),
            self.layerChanged)

        #
        # Hook up a slot for when the dock is hidden using its close button
        # or  view-panels
        #
        QObject.connect(
            self.dockWidget,
            SIGNAL("visibilityChanged (bool)"),
            self.toggleActionDock)

        # pylint: disable=W0201

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

        This method is called by QGIS and should be used to *remove*
        any graphical user interface elements that should appear in QGIS.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionDock)
        self.iface.removeToolBarIcon(self.actionDock)
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionKeywordsDialog)
        self.iface.removeToolBarIcon(self.actionKeywordsDialog)
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionResetDock)
        self.iface.removeToolBarIcon(self.actionResetDock)
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionOptions)
        self.iface.removeToolBarIcon(self.actionOptions)
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionMinimumNeeds)
        self.iface.removeToolBarIcon(self.actionMinimumNeeds)
        self.iface.removePluginMenu(self.tr('InaSAFE'),
                                    self.actionImpactFunctionsDoc)
        self.iface.removeToolBarIcon(self.actionImpactFunctionsDoc)
        self.iface.mainWindow().removeDockWidget(self.dockWidget)
        self.dockWidget.setVisible(False)
        self.dockWidget.destroy()
        QObject.disconnect(
            self.iface,
            SIGNAL("currentLayerChanged(QgsMapLayer*)"),
            self.layerChanged)

    def toggleActionDock(self, checked):
        """check or uncheck the toggle inaSAFE toolbar button.

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

        .. see also:: :func:`Plugin.initGui`.

        Args:
           checked - if actionDock has to be checked or not
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """

        self.actionDock.setChecked(checked)

    # Run method that performs all the real work
    def showHideDockWidget(self):
        """Show or hide the dock widget.

        This slot is called when the user clicks the toolbar icon or
        menu item associated with this plugin. It will hide or show
        the dock depending on its current state.

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        if self.dockWidget.isVisible():
            self.dockWidget.setVisible(False)
        else:
            self.dockWidget.setVisible(True)
            self.dockWidget.raise_()

    def showMinimumNeeds(self):
        """Show the minimum needs dialog.

        This slot is called when the user clicks the minimum needs toolbar
        icon or menu item associated with this plugin.

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # import here only so that it is AFTER i18n set up
        from safe_qgis.minimum_needs import MinimumNeeds

        myDialog = MinimumNeeds(self.iface.mainWindow())
        myDialog.show()

    def showOptions(self):
        """Show the options dialog.

        This slot is called when the user clicks the options toolbar
        icon or menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # import here only so that it is AFTER i18n set up
        from safe_qgis.options_dialog import OptionsDialog

        myDialog = OptionsDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dockWidget)
        myDialog.show()

    def showKeywordsEditor(self):
        """Show the keywords editor.

        This slot is called when the user clicks the keyword editor toolbar
        icon or menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.

        Returns:
           None.

        Raises:
           no exceptions explicitly raised.
        """
        # import here only so that it is AFTER i18n set up
        from safe_qgis.keywords_dialog import KeywordsDialog

        if self.iface.activeLayer() is None:
            return
        myDialog = KeywordsDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dockWidget)
        myDialog.setModal(True)
        myDialog.show()

    def showImpactFunctionsDoc(self):
        """Show the impact function doc

        This slot is called when the user clicks the impact functions
        toolbar icon or menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # import here only so that it is AFTER i18n set up
        from safe_qgis.impact_functions_doc import ImpactFunctionsDoc

        myDialog = ImpactFunctionsDoc(self.iface.mainWindow())
        myDialog.show()

    def showConverter(self):
        """Show the converter dialog.

        This slot is called when the user clicks the impact functions
        toolbar icon or menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        # import here only so that it is AFTER i18n set up
        from safe_qgis.converter_dialog import ConverterDialog

        myDialog = ConverterDialog(self.iface.mainWindow())
        myDialog.show()

    def showImportDlg(self):
        from safe_qgis.import_dialog import ImportDialog

        dlg = ImportDialog(self.iface.mainWindow(), self.iface)
        dlg.setModal(True)
        dlg.show()

    def resetDock(self):
        """Reset the dock to its default state.

        This slot is called when the user clicks the reset icon in the toolbar
        or the reset menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        self.dockWidget.getLayers()

    def layerChanged(self, theLayer):
        """Enable or disable the keywords editor icon.

        This slot is called when the user clicks the keyword editor toolbar
        icon or menu item associated with this plugin

        .. see also:: :func:`Plugin.initGui`.

        Args:
           None.
        Returns:
           None.
        Raises:
           no exceptions explicitly raised.
        """
        if theLayer is None:
            self.actionKeywordsDialog.setEnabled(False)
        else:
            self.actionKeywordsDialog.setEnabled(True)
        self.dockWidget.layerChanged(theLayer)

    def keyActionF7(self):
        '''Executed when user press F7'''
        self.showConverter()
Example #49
0
class ProcessingPlugin:

    def __init__(self, iface):
        self.iface = iface

    def initGui(self):
        Processing.initialize()

        self.commander = None
        self.toolbox = ProcessingToolbox()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.toolbox)
        self.toolbox.hide()
        Processing.addAlgListListener(self.toolbox)

        self.menu = QMenu(self.iface.mainWindow().menuBar())
        self.menu.setObjectName('processing')
        self.menu.setTitle(self.tr('Pro&cessing'))

        self.toolboxAction = self.toolbox.toggleViewAction()
        self.toolboxAction.setObjectName('toolboxAction')
        self.toolboxAction.setIcon(
            QIcon(os.path.join(cmd_folder, 'images', 'alg.png')))
        self.toolboxAction.setText(self.tr('&Toolbox'))
        self.iface.registerMainWindowAction(self.toolboxAction, 'Ctrl+Alt+T')
        self.menu.addAction(self.toolboxAction)

        self.modelerAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'model.png')),
            self.tr('Graphical &Modeler...'), self.iface.mainWindow())
        self.modelerAction.setObjectName('modelerAction')
        self.modelerAction.triggered.connect(self.openModeler)
        self.iface.registerMainWindowAction(self.modelerAction, 'Ctrl+Alt+M')
        self.menu.addAction(self.modelerAction)

        self.historyAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'history.gif')),
            self.tr('&History...'), self.iface.mainWindow())
        self.historyAction.setObjectName('historyAction')
        self.historyAction.triggered.connect(self.openHistory)
        self.iface.registerMainWindowAction(self.historyAction, 'Ctrl+Alt+H')
        self.menu.addAction(self.historyAction)

        self.configAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'config.png')),
            self.tr('&Options...'), self.iface.mainWindow())
        self.configAction.setObjectName('configAction')
        self.configAction.triggered.connect(self.openConfig)
        self.iface.registerMainWindowAction(self.configAction, 'Ctrl+Alt+C')
        self.menu.addAction(self.configAction)

        self.resultsAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'results.png')),
            self.tr('&Results Viewer...'), self.iface.mainWindow())
        self.resultsAction.setObjectName('resultsAction')
        self.resultsAction.triggered.connect(self.openResults)
        self.iface.registerMainWindowAction(self.resultsAction, 'Ctrl+Alt+R')
        self.menu.addAction(self.resultsAction)

        menuBar = self.iface.mainWindow().menuBar()
        menuBar.insertMenu(
            self.iface.firstRightStandardMenu().menuAction(), self.menu)

        self.commanderAction = QAction(
            QIcon(os.path.join(cmd_folder, 'images', 'commander.png')),
            self.tr('&Commander'), self.iface.mainWindow())
        self.commanderAction.setObjectName('commanderAction')
        self.commanderAction.triggered.connect(self.openCommander)
        self.menu.addAction(self.commanderAction)
        self.iface.registerMainWindowAction(self.commanderAction,
                                            self.tr('Ctrl+Alt+M'))

    def unload(self):
        self.toolbox.setVisible(False)
        self.menu.deleteLater()

        # delete temporary output files
        folder = tempFolder()
        if QDir(folder).exists():
            shutil.rmtree(folder, True)

        self.iface.unregisterMainWindowAction(self.commanderAction)

    def openCommander(self):
        if self.commander is None:
            self.commander = CommanderWindow(
                self.iface.mainWindow(),
                self.iface.mapCanvas())
            Processing.addAlgListListener(self.commander)
        self.commander.prepareGui()
        self.commander.show()

    def openToolbox(self):
        if self.toolbox.isVisible():
            self.toolbox.hide()
        else:
            self.toolbox.show()

    def openModeler(self):
        dlg = ModelerDialog()
        dlg.show()
        dlg.exec_()
        if dlg.update:
            self.toolbox.updateProvider('model')

    def openResults(self):
        dlg = ResultsDialog()
        dlg.show()
        dlg.exec_()

    def openHistory(self):
        dlg = HistoryDialog()
        dlg.exec_()

    def openConfig(self):
        dlg = ConfigDialog(self.toolbox)
        dlg.exec_()

    def tr(self, message):
        return QCoreApplication.translate('ProcessingPlugin', message)
Example #50
0
class TalkEditorApp(FreeseerApp):
    '''Freeseer talk database editor main gui class'''
    def __init__(self, config, db):
        FreeseerApp.__init__(self)

        self.config = config
        self.db = db

        icon = QIcon()
        icon.addPixmap(QPixmap(':/freeseer/logo.png'), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.resize(960, 600)

        #
        # Setup Layout
        #
        self.mainWidget = QWidget()
        self.mainLayout = QVBoxLayout()
        self.mainWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.mainWidget)
        self.mainLayout.setAlignment(Qt.AlignTop)

        # Add custom widgets
        self.commandButtons = CommandButtons()
        self.tableView = QTableView()
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.talkDetailsWidget = TalkDetailsWidget()
        self.importTalksWidget = ImportTalksWidget()
        self.newTalkWidget = NewTalkWidget()
        self.mainLayout.addWidget(self.importTalksWidget)
        #self.mainLayout.addLayout(self.titleLayout)
        self.mainLayout.addWidget(self.commandButtons)
        self.mainLayout.addWidget(self.tableView)
        self.mainLayout.addWidget(self.talkDetailsWidget)
        self.mainLayout.addWidget(self.importTalksWidget)
        # --- End Layout

        # Initialize geometry, to be used for restoring window positioning.
        self.geometry = None

        #
        # Setup Menubar
        #
        self.actionExportCsv = QAction(self)
        self.actionExportCsv.setObjectName('actionExportCsv')
        self.actionRemoveAll = QAction(self)
        self.actionRemoveAll.setObjectName('actionRemoveAll')

        # Actions
        self.menuFile.insertAction(self.actionExit, self.actionExportCsv)
        self.menuFile.insertAction(self.actionExit, self.actionRemoveAll)
        # --- End Menubar

        #
        # TableView Connections
        #
        self.connect(self.tableView, SIGNAL('activated(const QModelIndex)'), self.talk_selected)
        self.connect(self.tableView, SIGNAL('selected(const QModelIndex)'), self.talk_selected)
        self.connect(self.tableView, SIGNAL('clicked(const QModelIndex)'), self.talk_selected)

        # Import Widget
        self.connect(self.importTalksWidget.csvRadioButton, SIGNAL('toggled(bool)'), self.toggle_import)
        self.connect(self.importTalksWidget.importButton, SIGNAL('clicked()'), self.import_talks)
        self.connect(self.importTalksWidget.cancelButton, SIGNAL('clicked()'), self.hide_import_talks_widget)
        self.importTalksWidget.setHidden(True)
        self.connect(self.importTalksWidget.csvFileSelectButton, SIGNAL('clicked()'), self.csv_file_select)
        self.connect(self.importTalksWidget.csvLineEdit, SIGNAL('returnPressed()'),
            self.importTalksWidget.importButton.click)
        self.connect(self.importTalksWidget.rssLineEdit, SIGNAL('returnPressed()'),
            self.importTalksWidget.importButton.click)
        self.connect(self.actionExportCsv, SIGNAL('triggered()'), self.export_talks_to_csv)
        self.connect(self.actionRemoveAll, SIGNAL('triggered()'), self.confirm_reset)

        # Command Buttons
        self.connect(self.commandButtons.addButton, SIGNAL('clicked()'), self.show_new_talk_popup)
        self.connect(self.commandButtons.removeButton, SIGNAL('clicked()'), self.remove_talk)
        self.connect(self.commandButtons.removeAllButton, SIGNAL('clicked()'), self.confirm_reset)
        self.connect(self.commandButtons.importButton, SIGNAL('clicked()'), self.show_import_talks_widget)
        self.connect(self.commandButtons.exportButton, SIGNAL('clicked()'), self.export_talks_to_csv)
        self.connect(self.commandButtons.searchButton, SIGNAL('clicked()'), self.search_talks)
        self.connect(self.commandButtons.searchLineEdit, SIGNAL('textEdited(QString)'), self.search_talks)
        self.connect(self.commandButtons.searchLineEdit, SIGNAL('returnPressed()'), self.search_talks)

        # Talk Details Buttons
        self.connect(self.talkDetailsWidget.saveButton, SIGNAL('clicked()'), self.update_talk)

        # Talk Details Widget
        self.connect(self.talkDetailsWidget.titleLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.presenterLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.categoryLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.eventLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.roomLineEdit, SIGNAL('textEdited(const QString)'), self.enable_save)
        self.connect(self.talkDetailsWidget.descriptionTextEdit, SIGNAL('modificationChanged(bool)'), self.enable_save)
        self.connect(self.talkDetailsWidget.dateEdit, SIGNAL('dateChanged(const QDate)'), self.enable_save)
        self.connect(self.talkDetailsWidget.startTimeEdit, SIGNAL('timeChanged(const QTime)'), self.enable_save)
        self.connect(self.talkDetailsWidget.endTimeEdit, SIGNAL('timeChanged(const QTime)'), self.enable_save)

        # New Talk Widget
        self.newTalkWidget.connect(self.newTalkWidget.addButton, SIGNAL('clicked()'), self.add_talk)
        self.newTalkWidget.connect(self.newTalkWidget.cancelButton, SIGNAL('clicked()'), self.newTalkWidget.reject)

        # Load default language
        actions = self.menuLanguage.actions()
        for action in actions:
            if action.data().toString() == self.config.default_language:
                action.setChecked(True)
                self.translate(action)
                break

        # Load Talk Database
        self.load_presentations_model()

        # Setup Autocompletion
        self.update_autocomplete_fields()

        self.talkDetailsWidget.saveButton.setEnabled(False)

        # Select first item
        #self.tableView.setCurrentIndex(self.proxy.index(0,0))
        #self.talk_selected(self.proxy.index(0,0))

    #
    # Translation
    #
    def retranslate(self):
        self.setWindowTitle(self.app.translate("TalkEditorApp", "Freeseer Talk Editor"))

        #
        # Reusable Strings
        #
        self.confirmDBClearTitleString = self.app.translate("TalkEditorApp", "Remove All Talks from Database")
        self.confirmDBClearQuestionString = self.app.translate("TalkEditorApp",
                                                               "Are you sure you want to clear the DB?")
        self.confirmTalkDetailsClearTitleString = self.app.translate("TalkEditorApp", "Unsaved Data")
        self.confirmTalkDetailsClearQuestionString = self.app.translate("TalkEditorApp",
                                                                        "Unsaved talk details will be lost. Continue?")
        # --- End Reusable Strings

        #
        # Menubar
        #
        self.actionExportCsv.setText(self.app.translate("TalkEditorApp", "&Export to CSV"))
        self.actionRemoveAll.setText(self.app.translate("TalkEditorApp", "&Remove All Talks"))

        # --- End Menubar

        #
        # TalkDetailsWidget
        #
        self.talkDetailsWidget.titleLabel.setText(self.app.translate("TalkEditorApp", "Title"))
        self.talkDetailsWidget.presenterLabel.setText(self.app.translate("TalkEditorApp", "Presenter"))
        self.talkDetailsWidget.categoryLabel.setText(self.app.translate("TalkEditorApp", "Category"))
        self.talkDetailsWidget.eventLabel.setText(self.app.translate("TalkEditorApp", "Event"))
        self.talkDetailsWidget.roomLabel.setText(self.app.translate("TalkEditorApp", "Room"))
        self.talkDetailsWidget.dateLabel.setText(self.app.translate("TalkEditorApp", "Date"))
        self.talkDetailsWidget.startTimeLabel.setText(self.app.translate("TalkEditorApp", "Start Time"))
        self.talkDetailsWidget.endTimeLabel.setText(self.app.translate("TalkEditorApp", "End Time"))
        # --- End TalkDetailsWidget

        #
        # Import Talks Widget Translations
        #
        self.importTalksWidget.rssRadioButton.setText(self.app.translate("TalkEditorApp", "RSS URL"))
        self.importTalksWidget.csvRadioButton.setText(self.app.translate("TalkEditorApp", "CSV File"))
        self.importTalksWidget.importButton.setText(self.app.translate("TalkEditorApp", "Import"))
        # --- End Talks Widget Translations

        #
        # Command Button Translations\
        #
        self.commandButtons.importButton.setText(self.app.translate("TalkEditorApp", "Import"))
        self.commandButtons.exportButton.setText(self.app.translate("TalkEditorApp", "Export"))
        self.commandButtons.addButton.setText(self.app.translate("TalkEditorApp", "Add New Talk"))
        self.commandButtons.removeButton.setText(self.app.translate("TalkEditorApp", "Remove"))
        self.commandButtons.removeAllButton.setText(self.app.translate("TalkEditorApp", "Remove All"))
        # --- End Command Butotn Translations

        #
        # Search Widget Translations
        #
        self.commandButtons.searchButton.setText(self.app.translate("TalkEditorApp", "Search"))
        # --- End Command Button Translations

    def load_presentations_model(self):
        # Load Presentation Model
        self.presentationModel = self.db.get_presentations_model()
        self.proxy = QSortFilterProxyModel()
        self.proxy.setSourceModel(self.presentationModel)
        self.tableView.setModel(self.proxy)
        self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)

        # Fill table whitespace.
        self.tableView.horizontalHeader().setStretchLastSection(False)
        self.tableView.horizontalHeader().setResizeMode(1, QHeaderView.Stretch)

        # Hide the ID field
        self.tableView.setColumnHidden(0, True)

        # Map data to widgets
        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy)
        self.mapper.setSubmitPolicy(QDataWidgetMapper.ManualSubmit)
        self.mapper.addMapping(self.talkDetailsWidget.titleLineEdit, 1)
        self.mapper.addMapping(self.talkDetailsWidget.presenterLineEdit, 2)
        self.mapper.addMapping(self.talkDetailsWidget.categoryLineEdit, 4)
        self.mapper.addMapping(self.talkDetailsWidget.eventLineEdit, 5)
        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.mapper.addMapping(self.talkDetailsWidget.descriptionTextEdit, 3)
        self.mapper.addMapping(self.talkDetailsWidget.dateEdit, 7)
        self.mapper.addMapping(self.talkDetailsWidget.startTimeEdit, 8)
        self.mapper.addMapping(self.talkDetailsWidget.endTimeEdit, 9)

        # Load StringLists
        self.titleList = QStringList(self.db.get_string_list("Title"))
        #self.speakerList = QStringList(self.db.get_speaker_list())
        #self.categoryList = QStringList(self.db.get_category_list())
        #self.eventList = QStringList(self.db.get_event_list())
        #self.roomList = QStringList(self.db.get_room_list())

        #Disble input
        self.talkDetailsWidget.disable_input_fields()

    def search_talks(self):
        # The default value is 0. If the value is -1, the keys will be read from all columns.
        self.proxy.setFilterKeyColumn(-1)
        self.proxy.setFilterFixedString(self.commandButtons.searchLineEdit.text())

    def talk_selected(self, model):
        self.mapper.setCurrentIndex(model.row())
        self.talkDetailsWidget.enable_input_fields()
        self.talkDetailsWidget.saveButton.setEnabled(False)

    def toggle_import(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.importTalksWidget.csvLineEdit.setEnabled(True)
            self.importTalksWidget.csvFileSelectButton.setEnabled(True)
            self.importTalksWidget.rssLineEdit.setEnabled(False)
        else:
            self.importTalksWidget.csvLineEdit.setEnabled(False)
            self.importTalksWidget.csvFileSelectButton.setEnabled(False)
            self.importTalksWidget.rssLineEdit.setEnabled(True)

    def show_import_talks_widget(self):
        self.commandButtons.setHidden(True)
        self.tableView.setHidden(True)
        self.talkDetailsWidget.setHidden(True)
        self.importTalksWidget.setHidden(False)

    def hide_import_talks_widget(self):
        self.commandButtons.setHidden(False)
        self.tableView.setHidden(False)
        self.talkDetailsWidget.setHidden(False)
        self.importTalksWidget.setHidden(True)

    def add_talk(self):
        """Adds a new talk to the database using data from the NewTalkWidget input fields"""
        presentation = self.create_presentation(self.newTalkWidget.talkDetailsWidget)

        if presentation:
            self.db.insert_presentation(presentation)
            self.newTalkWidget.accept()  # Close the dialog

    def update_talk(self):
        """Updates the currently selected talk using data from the TalkEditorApp input fields"""
        selected_talk = self.tableView.currentIndex()
        if selected_talk.row() >= 0:  # The tableView index begins at 0 and is -1 by default
            talk_id = selected_talk.sibling(selected_talk.row(), 0).data().toString()
            presentation = self.create_presentation(self.talkDetailsWidget)

            if presentation:
                self.db.update_presentation(talk_id, presentation)
                self.apply_changes(selected_talk)
                self.talkDetailsWidget.saveButton.setEnabled(False)

    def create_presentation(self, talkDetailsWidget):
        """Creates and returns an instance of Presentation using data from the input fields"""
        date = talkDetailsWidget.dateEdit.date()
        startTime = talkDetailsWidget.startTimeEdit.time()
        endTime = talkDetailsWidget.endTimeEdit.time()

        title = unicode(talkDetailsWidget.titleLineEdit.text()).strip()
        if title:
            return Presentation(
                unicode(talkDetailsWidget.titleLineEdit.text()).strip(),
                unicode(talkDetailsWidget.presenterLineEdit.text()).strip(),
                unicode(talkDetailsWidget.descriptionTextEdit.toPlainText()).strip(),
                unicode(talkDetailsWidget.categoryLineEdit.text()).strip(),
                unicode(talkDetailsWidget.eventLineEdit.text()).strip(),
                unicode(talkDetailsWidget.roomLineEdit.text()).strip(),
                unicode(date.toString(Qt.ISODate)),
                unicode(startTime.toString(Qt.ISODate)),
                unicode(endTime.toString(Qt.ISODate)))

    def show_new_talk_popup(self):
        """Displays a modal dialog with a talk details view

        When Add is selected, a new talk is added to the database using the input field data.
        When Cancel is selected, no talk is added.
        """
        log.info('Opening Add Talk window...')
        self.clear_new_talk_fields()
        self.remove_new_talk_placeholder_text()
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.setFocus()
        if self.newTalkWidget.exec_() == 1:
            self.apply_changes()
            self.talkDetailsWidget.disable_input_fields()
        else:
            log.info('No talk added...')

    def apply_changes(self, updated_talk=None):
        """Repopulates the model to display the effective changes

        Updates the autocomplete fields.
        Displays the updated model in the table view, and selects the newly updated/added talk.
        """
        self.presentationModel.select()
        self.select_talk(updated_talk)
        self.update_autocomplete_fields()

    def select_talk(self, talk=None):
        """Selects the given talk in the table view

        If no talk is given, the last row in the table view is selected.
        """
        if talk:
            row = talk.row()
            column = talk.column()
        else:
            row = self.presentationModel.rowCount() - 1  # Select last row
            column = 0

        self.tableView.selectRow(row)
        self.tableView.setCurrentIndex(self.proxy.index(row, column))
        self.talk_selected(self.proxy.index(row, column))

    def remove_talk(self):
        try:
            rows_selected = self.tableView.selectionModel().selectedRows()
        except:
            return

        # Reversed because rows in list change position once row is removed
        for row in reversed(rows_selected):
            self.presentationModel.removeRow(row.row())

    def load_talk(self):
        try:
            self.tableView.currentIndex().row()
        except:
            return

        self.mapper.addMapping(self.talkDetailsWidget.roomLineEdit, 6)
        self.presentationModel.select()

    def reset(self):
        self.db.clear_database()
        self.presentationModel.select()

    def confirm_reset(self):
        """Presents a confirmation dialog to ask the user if they are sure they wish to remove the talk database.
        If Yes call the reset() function"""
        confirm = QMessageBox.question(self,
                                       self.confirmDBClearTitleString,
                                       self.confirmDBClearQuestionString,
                                       QMessageBox.Yes |
                                       QMessageBox.No,
                                       QMessageBox.No)

        if confirm == QMessageBox.Yes:
            self.reset()

    def add_talks_from_rss(self):
        rss_url = unicode(self.importTalksWidget.rssLineEdit.text())
        if rss_url:
            self.db.add_talks_from_rss(rss_url)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please enter a RSS URL")
            error.exec_()

    def closeEvent(self, event):
        log.info('Exiting talk database editor...')
        self.geometry = self.saveGeometry()
        event.accept()

    def csv_file_select(self):
        fname = QFileDialog.getOpenFileName(
            self, 'Select file', "", "*.csv")
        if fname:
            self.importTalksWidget.csvLineEdit.setText(fname)

    def add_talks_from_csv(self):
        fname = self.importTalksWidget.csvLineEdit.text()

        if fname:
            self.db.add_talks_from_csv(fname)
            self.presentationModel.select()
            self.hide_import_talks_widget()
        else:
            error = QMessageBox()
            error.setText("Please select a file")
            error.exec_()

    def import_talks(self):
        if self.importTalksWidget.csvRadioButton.isChecked():
            self.add_talks_from_csv()
        else:
            self.add_talks_from_rss()

        self.update_autocomplete_fields()

    def export_talks_to_csv(self):
        fname = QFileDialog.getSaveFileName(self, 'Select file', "", "*.csv")
        if fname:
            self.db.export_talks_to_csv(fname)

    def update_autocomplete_fields(self):
        self.titleList = QStringList(self.db.get_string_list("Title"))
        self.speakerList = QStringList(self.db.get_string_list("Speaker"))
        self.categoryList = QStringList(self.db.get_string_list("Category"))
        self.eventList = QStringList(self.db.get_string_list("Event"))
        self.roomList = QStringList(self.db.get_string_list("Room"))

        self.titleCompleter = QCompleter(self.titleList)
        self.titleCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.speakerCompleter = QCompleter(self.speakerList)
        self.speakerCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.categoryCompleter = QCompleter(self.categoryList)
        self.categoryCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.eventCompleter = QCompleter(self.eventList)
        self.eventCompleter.setCaseSensitivity(Qt.CaseInsensitive)
        self.roomCompleter = QCompleter(self.roomList)
        self.roomCompleter.setCaseSensitivity(Qt.CaseInsensitive)

        self.talkDetailsWidget.titleLineEdit.setCompleter(self.titleCompleter)
        self.talkDetailsWidget.presenterLineEdit.setCompleter(self.speakerCompleter)
        self.talkDetailsWidget.categoryLineEdit.setCompleter(self.categoryCompleter)
        self.talkDetailsWidget.eventLineEdit.setCompleter(self.eventCompleter)
        self.talkDetailsWidget.roomLineEdit.setCompleter(self.roomCompleter)

    def are_fields_enabled(self):
        return (self.talkDetailsWidget.titleLineEdit.isEnabled() and
                self.talkDetailsWidget.presenterLineEdit.isEnabled() and
                self.talkDetailsWidget.categoryLineEdit.isEnabled() and
                self.talkDetailsWidget.eventLineEdit.isEnabled() and
                self.talkDetailsWidget.roomLineEdit.isEnabled() and
                self.talkDetailsWidget.dateEdit.isEnabled() and
                self.talkDetailsWidget.startTimeEdit.isEnabled() and
                self.talkDetailsWidget.endTimeEdit.isEnabled())

    def unsaved_details_exist(self):
        """Checks if changes have been made to new/existing talk details

        Looks for text in the input fields and check the enabled state of the Save Talk button
        If the Save Talk button is enabled, the input fields contain modified values
        """
        return (self.talkDetailsWidget.saveButton.isEnabled() and
                (self.talkDetailsWidget.titleLineEdit.text() or
                self.talkDetailsWidget.presenterLineEdit.text() or
                self.talkDetailsWidget.categoryLineEdit.text() or
                self.talkDetailsWidget.descriptionTextEdit.toPlainText()))

    def enable_save(self):
        self.talkDetailsWidget.saveButton.setEnabled(True)

    def clear_new_talk_fields(self):
        """Removes existing data from all NewTalkWidget fields except event, room, date and time"""
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.clear()
        self.newTalkWidget.talkDetailsWidget.presenterLineEdit.clear()
        self.newTalkWidget.talkDetailsWidget.descriptionTextEdit.clear()
        self.newTalkWidget.talkDetailsWidget.categoryLineEdit.clear()

    def remove_new_talk_placeholder_text(self):
        """Removes placeholder text in NewTalkWidget originally set by TalkDetailsWidget"""
        self.newTalkWidget.talkDetailsWidget.titleLineEdit.setPlaceholderText("")
        self.newTalkWidget.talkDetailsWidget.presenterLineEdit.setPlaceholderText("")
        self.newTalkWidget.talkDetailsWidget.categoryLineEdit.setPlaceholderText("")
        self.newTalkWidget.talkDetailsWidget.eventLineEdit.setPlaceholderText("")
        self.newTalkWidget.talkDetailsWidget.roomLineEdit.setPlaceholderText("")
Example #51
0
class fToolsPlugin:
    def __init__(self, iface):
        self.iface = iface
        try:
            self.QgisVersion = unicode(QGis.QGIS_VERSION_INT)
        except:
            self.QgisVersion = unicode(QGis.qgisVersion)[0]

    def getThemeIcon(self, icon):
        settings = QSettings()
        pluginPath = os.path.dirname(__file__)
        themePath = "icons" + QDir.separator() + settings.value(
            "/Themes", "default") + QDir.separator() + icon
        defaultPath = "icons" + QDir.separator() + "default" + QDir.separator(
        ) + icon
        if QFile.exists(pluginPath + QDir.separator() + themePath):
            return QIcon(":" + themePath)
        elif QFile.exists(pluginPath + QDir.separator() + defaultPath):
            return QIcon(":" + defaultPath)
        else:
            return QIcon()

    def updateThemeIcons(self, theme):
        self.analysisMenu.setIcon(QIcon(self.getThemeIcon("analysis.png")))
        self.distMatrix.setIcon(QIcon(self.getThemeIcon("matrix.png")))
        self.sumLines.setIcon(QIcon(self.getThemeIcon("sum_lines.png")))
        self.pointsPoly.setIcon(QIcon(self.getThemeIcon("sum_points.png")))
        self.compStats.setIcon(QIcon(
            self.getThemeIcon("basic_statistics.png")))
        self.listUnique.setIcon(QIcon(self.getThemeIcon("unique.png")))
        self.nearestNeigh.setIcon(QIcon(self.getThemeIcon("neighbour.png")))
        self.meanCoords.setIcon(QIcon(self.getThemeIcon("mean.png")))
        self.intLines.setIcon(QIcon(self.getThemeIcon("intersections.png")))

        self.researchMenu.setIcon(QIcon(self.getThemeIcon("sampling.png")))
        self.randSel.setIcon(QIcon(self.getThemeIcon("random_selection.png")))
        self.randSub.setIcon(QIcon(self.getThemeIcon("sub_selection.png")))
        self.randPoints.setIcon(QIcon(self.getThemeIcon("random_points.png")))
        self.regPoints.setIcon(QIcon(self.getThemeIcon("regular_points.png")))
        self.vectGrid.setIcon(QIcon(self.getThemeIcon("vector_grid.png")))
        self.selectLocation.setIcon(
            QIcon(self.getThemeIcon("select_location.png")))
        self.layerExtent.setIcon(QIcon(self.getThemeIcon("layer_extent.png")))

        self.geoMenu.setIcon(QIcon(self.getThemeIcon("geoprocessing.png")))
        self.minConvex.setIcon(QIcon(self.getThemeIcon("convex_hull.png")))
        self.dynaBuffer.setIcon(QIcon(self.getThemeIcon("buffer.png")))
        self.intersect.setIcon(QIcon(self.getThemeIcon("intersect.png")))
        self.union.setIcon(QIcon(self.getThemeIcon("union.png")))
        self.symDifference.setIcon(
            QIcon(self.getThemeIcon("sym_difference.png")))
        self.clip.setIcon(QIcon(self.getThemeIcon("clip.png")))
        self.dissolve.setIcon(QIcon(self.getThemeIcon("dissolve.png")))
        self.erase.setIcon(QIcon(self.getThemeIcon("difference.png")))
        self.eliminate.setIcon(QIcon(self.getThemeIcon("eliminate.png")))

        self.conversionMenu.setIcon(QIcon(self.getThemeIcon("geometry.png")))
        self.compGeo.setIcon(QIcon(self.getThemeIcon("export_geometry.png")))
        self.checkGeom.setIcon(QIcon(self.getThemeIcon("check_geometry.png")))
        self.centroids.setIcon(QIcon(self.getThemeIcon("centroids.png")))
        self.delaunay.setIcon(QIcon(self.getThemeIcon("delaunay.png")))
        self.voronoi.setIcon(QIcon(self.getThemeIcon("voronoi.png")))
        self.extNodes.setIcon(QIcon(self.getThemeIcon("extract_nodes.png")))
        self.simplify.setIcon(QIcon(self.getThemeIcon("simplify.png")))
        self.densify.setIcon(QIcon(self.getThemeIcon("densify.png")))
        self.multiToSingle.setIcon(
            QIcon(self.getThemeIcon("multi_to_single.png")))
        self.singleToMulti.setIcon(
            QIcon(self.getThemeIcon("single_to_multi.png")))
        self.polysToLines.setIcon(QIcon(self.getThemeIcon("to_lines.png")))
        self.linesToPolys.setIcon(QIcon(self.getThemeIcon("to_lines.png")))

        self.dataManageMenu.setIcon(QIcon(self.getThemeIcon("management.png")))
        self.define.setIcon(QIcon(self.getThemeIcon("define_projection.png")))
        self.spatJoin.setIcon(QIcon(self.getThemeIcon("join_location.png")))
        self.splitVect.setIcon(QIcon(self.getThemeIcon("split_layer.png")))
        self.mergeShapes.setIcon(QIcon(self.getThemeIcon("merge_shapes.png")))
        self.spatialIndex.setIcon(QIcon(
            self.getThemeIcon("spatial_index.png")))

    def initGui(self):
        if int(self.QgisVersion) < 1:
            QMessageBox.warning(
                self.iface.getMainWindow(), "fTools",
                QCoreApplication.translate("fTools", "QGIS version detected: ")
                + unicode(self.QgisVersion) + ".xx\n" +
                QCoreApplication.translate(
                    "fTools",
                    "This version of fTools requires at least QGIS version 1.0.0\nPlugin will not be enabled."
                ))
            return None
        QObject.connect(self.iface, SIGNAL("currentThemeChanged (QString)"),
                        self.updateThemeIcons)

        self.analysisMenu = QMenu(
            QCoreApplication.translate("fTools", "&Analysis Tools"))
        self.analysisMenu.setObjectName("analysisMenu")
        self.distMatrix = QAction(
            QCoreApplication.translate("fTools", "Distance Matrix..."),
            self.iface.mainWindow())
        self.distMatrix.setObjectName("distMatrix")
        self.sumLines = QAction(
            QCoreApplication.translate("fTools", "Sum Line Lengths..."),
            self.iface.mainWindow())
        self.sumLines.setObjectName("sumLines")
        self.pointsPoly = QAction(
            QCoreApplication.translate("fTools", "Points in Polygon..."),
            self.iface.mainWindow())
        self.pointsPoly.setObjectName("pointsPoly")
        self.compStats = QAction(
            QCoreApplication.translate("fTools", "Basic Statistics..."),
            self.iface.mainWindow())
        self.compStats.setObjectName("compStats")
        self.listUnique = QAction(
            QCoreApplication.translate("fTools", "List Unique Values..."),
            self.iface.mainWindow())
        self.listUnique.setObjectName("listUnique")
        self.nearestNeigh = QAction(
            QCoreApplication.translate("fTools",
                                       "Nearest Neighbour Analysis..."),
            self.iface.mainWindow())
        self.nearestNeigh.setObjectName("nearestNeigh")
        self.meanCoords = QAction(
            QCoreApplication.translate("fTools", "Mean Coordinate(s)..."),
            self.iface.mainWindow())
        self.meanCoords.setObjectName("meanCoords")
        self.intLines = QAction(
            QCoreApplication.translate("fTools", "Line Intersections..."),
            self.iface.mainWindow())
        self.intLines.setObjectName("intLines")
        self.analysisMenu.addActions([
            self.distMatrix, self.sumLines, self.pointsPoly, self.listUnique,
            self.compStats, self.nearestNeigh, self.meanCoords, self.intLines
        ])

        self.researchMenu = QMenu(
            QCoreApplication.translate("fTools", "&Research Tools"))
        self.researchMenu.setObjectName("researchMenu")
        self.randSel = QAction(
            QCoreApplication.translate("fTools", "Random Selection..."),
            self.iface.mainWindow())
        self.randSel.setObjectName("randSel")
        self.randSub = QAction(
            QCoreApplication.translate("fTools",
                                       "Random Selection Within Subsets..."),
            self.iface.mainWindow())
        self.randSub.setObjectName("randSub")
        self.randPoints = QAction(
            QCoreApplication.translate("fTools", "Random Points..."),
            self.iface.mainWindow())
        self.randPoints.setObjectName("randPoints")
        self.regPoints = QAction(
            QCoreApplication.translate("fTools", "Regular Points..."),
            self.iface.mainWindow())
        self.regPoints.setObjectName("regPoints")
        self.vectGrid = QAction(
            QCoreApplication.translate("fTools", "Vector Grid..."),
            self.iface.mainWindow())
        self.vectGrid.setObjectName("vectGrid")
        self.selectLocation = QAction(
            QCoreApplication.translate("fTools", "Select by Location..."),
            self.iface.mainWindow())
        self.selectLocation.setObjectName("selectLocation")
        self.layerExtent = QAction(
            QCoreApplication.translate("fTools",
                                       "Polygon from Layer Extent..."),
            self.iface.mainWindow())
        self.layerExtent.setObjectName("layerExtent")
        self.researchMenu.addActions([
            self.randSel, self.randSub, self.randPoints, self.regPoints,
            self.vectGrid, self.selectLocation, self.layerExtent
        ])

        self.geoMenu = QMenu(
            QCoreApplication.translate("fTools", "&Geoprocessing Tools"))
        self.geoMenu.setObjectName("geoMenu")
        self.minConvex = QAction(
            QCoreApplication.translate("fTools", "Convex Hull(s)..."),
            self.iface.mainWindow())
        self.minConvex.setObjectName("minConvex")
        self.dynaBuffer = QAction(
            QCoreApplication.translate("fTools", "Buffer(s)..."),
            self.iface.mainWindow())
        self.dynaBuffer.setObjectName("dynaBuffer")
        self.intersect = QAction(
            QCoreApplication.translate("fTools", "Intersect..."),
            self.iface.mainWindow())
        self.intersect.setObjectName("intersect")
        self.union = QAction(QCoreApplication.translate("fTools", "Union..."),
                             self.iface.mainWindow())
        self.union.setObjectName("union")
        self.symDifference = QAction(
            QCoreApplication.translate("fTools", "Symetrical Difference..."),
            self.iface.mainWindow())
        self.symDifference.setObjectName("symDifference")
        self.clip = QAction(QCoreApplication.translate("fTools", "Clip..."),
                            self.iface.mainWindow())
        self.clip.setObjectName("clip")
        self.dissolve = QAction(
            QCoreApplication.translate("fTools", "Dissolve..."),
            self.iface.mainWindow())
        self.dissolve.setObjectName("dissolve")
        self.erase = QAction(
            QCoreApplication.translate("fTools", "Difference..."),
            self.iface.mainWindow())
        self.erase.setObjectName("erase")
        self.eliminate = QAction(
            QCoreApplication.translate("fTools",
                                       "Eliminate Sliver Polygons..."),
            self.iface.mainWindow())
        self.eliminate.setObjectName("eliminate")
        self.geoMenu.addActions([
            self.minConvex, self.dynaBuffer, self.intersect, self.union,
            self.symDifference, self.clip, self.erase, self.dissolve,
            self.eliminate
        ])

        self.conversionMenu = QMenu(
            QCoreApplication.translate("fTools", "G&eometry Tools"))
        self.conversionMenu.setObjectName("conversionMenu")
        self.compGeo = QAction(
            QCoreApplication.translate("fTools",
                                       "Export/Add Geometry Columns..."),
            self.iface.mainWindow())
        self.compGeo.setObjectName("compGeo")
        self.checkGeom = QAction(
            QCoreApplication.translate("fTools", "Check Geometry Validity..."),
            self.iface.mainWindow())
        self.checkGeom.setObjectName("checkGeom")
        self.centroids = QAction(
            QCoreApplication.translate("fTools", "Polygon Centroids..."),
            self.iface.mainWindow())
        self.centroids.setObjectName("centroids")
        self.delaunay = QAction(
            QCoreApplication.translate("fTools", "Delaunay Triangulation..."),
            self.iface.mainWindow())
        self.delaunay.setObjectName("delaunay")
        self.voronoi = QAction(
            QCoreApplication.translate("fTools", "Voronoi Polygons..."),
            self.iface.mainWindow())
        self.voronoi.setObjectName("voronoi")
        self.extNodes = QAction(
            QCoreApplication.translate("fTools", "Extract Nodes..."),
            self.iface.mainWindow())
        self.extNodes.setObjectName("extNodes")
        self.simplify = QAction(
            QCoreApplication.translate("fTools", "Simplify Geometries..."),
            self.iface.mainWindow())
        self.simplify.setObjectName("simplify")
        self.densify = QAction(
            QCoreApplication.translate("fTools", "Densify Geometries..."),
            self.iface.mainWindow())
        self.densify.setObjectName("densify")
        self.multiToSingle = QAction(
            QCoreApplication.translate("fTools",
                                       "Multipart to Singleparts..."),
            self.iface.mainWindow())
        self.multiToSingle.setObjectName("multiToSingle")
        self.singleToMulti = QAction(
            QCoreApplication.translate("fTools",
                                       "Singleparts to Multipart..."),
            self.iface.mainWindow())
        self.singleToMulti.setObjectName("singleToMulti")
        self.polysToLines = QAction(
            QCoreApplication.translate("fTools", "Polygons to Lines..."),
            self.iface.mainWindow())
        self.polysToLines.setObjectName("polysToLines")
        self.linesToPolys = QAction(
            QCoreApplication.translate("fTools", "Lines to Polygons..."),
            self.iface.mainWindow())
        self.linesToPolys.setObjectName("linesToPolys")
        self.conversionMenu.addActions([
            self.checkGeom, self.compGeo, self.centroids, self.delaunay,
            self.voronoi, self.simplify, self.densify, self.multiToSingle,
            self.singleToMulti, self.polysToLines, self.linesToPolys,
            self.extNodes
        ])

        self.dataManageMenu = QMenu(
            QCoreApplication.translate("fTools", "&Data Management Tools"))
        self.dataManageMenu.setObjectName("dataManageMenu")
        self.define = QAction(
            QCoreApplication.translate("fTools",
                                       "Define Current Projection..."),
            self.iface.mainWindow())
        self.define.setObjectName("define")
        self.spatJoin = QAction(
            QCoreApplication.translate("fTools",
                                       "Join Attributes by Location..."),
            self.iface.mainWindow())
        self.spatJoin.setObjectName("spatJoin")
        self.splitVect = QAction(
            QCoreApplication.translate("fTools", "Split Vector Layer..."),
            self.iface.mainWindow())
        self.splitVect.setObjectName("splitVect")
        self.mergeShapes = QAction(
            QCoreApplication.translate("fTools", "Merge Shapefiles to One..."),
            self.iface.mainWindow())
        self.mergeShapes.setObjectName("mergeShapes")
        self.spatialIndex = QAction(
            QCoreApplication.translate("fTools", "Create Spatial Index..."),
            self.iface.mainWindow())
        self.spatialIndex.setObjectName("spatialIndex")
        self.dataManageMenu.addActions([
            self.define, self.spatJoin, self.splitVect, self.mergeShapes,
            self.spatialIndex
        ])

        self.updateThemeIcons("theme")

        self.menu = self.iface.vectorMenu()
        self.menu.addMenu(self.analysisMenu)
        self.menu.addMenu(self.researchMenu)
        self.menu.addMenu(self.geoMenu)
        self.menu.addMenu(self.conversionMenu)
        self.menu.addMenu(self.dataManageMenu)

        QObject.connect(self.distMatrix, SIGNAL("triggered()"),
                        self.dodistMatrix)
        QObject.connect(self.sumLines, SIGNAL("triggered()"), self.dosumLines)
        QObject.connect(self.pointsPoly, SIGNAL("triggered()"),
                        self.dopointsPoly)
        QObject.connect(self.compStats, SIGNAL("triggered()"),
                        self.docompStats)
        QObject.connect(self.listUnique, SIGNAL("triggered()"),
                        self.dolistUnique)
        QObject.connect(self.nearestNeigh, SIGNAL("triggered()"),
                        self.donearestNeigh)
        QObject.connect(self.meanCoords, SIGNAL("triggered()"),
                        self.domeanCoords)
        QObject.connect(self.intLines, SIGNAL("triggered()"), self.dointLines)

        QObject.connect(self.randSel, SIGNAL("triggered()"), self.dorandSel)
        QObject.connect(self.randSub, SIGNAL("triggered()"), self.dorandSub)
        QObject.connect(self.randPoints, SIGNAL("triggered()"),
                        self.dorandPoints)
        QObject.connect(self.regPoints, SIGNAL("triggered()"),
                        self.doregPoints)
        QObject.connect(self.vectGrid, SIGNAL("triggered()"), self.dovectGrid)
        QObject.connect(self.selectLocation, SIGNAL("triggered()"),
                        self.doselectLocation)
        QObject.connect(self.layerExtent, SIGNAL("triggered()"), self.doextent)

        QObject.connect(self.minConvex, SIGNAL("triggered()"),
                        self.dominConvex)
        QObject.connect(self.intersect, SIGNAL("triggered()"),
                        self.dointersect)
        QObject.connect(self.dissolve, SIGNAL("triggered()"), self.dodissolve)
        QObject.connect(self.symDifference, SIGNAL("triggered()"),
                        self.dosymdifference)
        QObject.connect(self.erase, SIGNAL("triggered()"), self.doerase)
        QObject.connect(self.union, SIGNAL("triggered()"), self.dounion)
        QObject.connect(self.clip, SIGNAL("triggered()"), self.doclip)
        QObject.connect(self.dynaBuffer, SIGNAL("triggered()"),
                        self.dodynaBuffer)
        QObject.connect(self.eliminate, SIGNAL("triggered()"),
                        self.doEliminate)

        QObject.connect(self.multiToSingle, SIGNAL("triggered()"),
                        self.domultiToSingle)
        QObject.connect(self.singleToMulti, SIGNAL("triggered()"),
                        self.dosingleToMulti)
        QObject.connect(self.checkGeom, SIGNAL("triggered()"),
                        self.docheckGeom)
        QObject.connect(self.simplify, SIGNAL("triggered()"), self.doSimplify)
        QObject.connect(self.densify, SIGNAL("triggered()"), self.doDensify)
        QObject.connect(self.centroids, SIGNAL("triggered()"),
                        self.docentroids)
        QObject.connect(self.delaunay, SIGNAL("triggered()"), self.dodelaunay)
        QObject.connect(self.voronoi, SIGNAL("triggered()"), self.dovoronoi)
        QObject.connect(self.polysToLines, SIGNAL("triggered()"),
                        self.dopolysToLines)
        QObject.connect(self.linesToPolys, SIGNAL("triggered()"),
                        self.dolinesToPolys)
        QObject.connect(self.compGeo, SIGNAL("triggered()"), self.docompGeo)
        QObject.connect(self.extNodes, SIGNAL("triggered()"), self.doextNodes)

        QObject.connect(self.define, SIGNAL("triggered()"), self.dodefine)
        QObject.connect(self.spatJoin, SIGNAL("triggered()"), self.dospatJoin)
        QObject.connect(self.splitVect, SIGNAL("triggered()"),
                        self.dosplitVect)
        QObject.connect(self.mergeShapes, SIGNAL("triggered()"),
                        self.doMergeShapes)
        QObject.connect(self.spatialIndex, SIGNAL("triggered()"),
                        self.doSpatIndex)

    def unload(self):
        self.menu.removeAction(self.analysisMenu.menuAction())
        self.menu.removeAction(self.researchMenu.menuAction())
        self.menu.removeAction(self.geoMenu.menuAction())
        self.menu.removeAction(self.conversionMenu.menuAction())
        self.menu.removeAction(self.dataManageMenu.menuAction())

    def doSimplify(self):
        d = doSimplify.Dialog(self.iface, 1)
        d.show()
        d.exec_()

    def doDensify(self):
        d = doSimplify.Dialog(self.iface, 2)
        d.show()
        d.exec_()

    def dopolysToLines(self):
        d = doGeometry.GeometryDialog(self.iface, 4)
        d.exec_()

    def dolinesToPolys(self):
        d = doGeometry.GeometryDialog(self.iface, 11)
        d.exec_()

    def docheckGeom(self):
        d = doValidate.ValidateDialog(self.iface)
        d.show()
        d.exec_()

    def domultiToSingle(self):
        d = doGeometry.GeometryDialog(self.iface, 2)
        d.exec_()

    def dosingleToMulti(self):
        d = doGeometry.GeometryDialog(self.iface, 1)
        d.exec_()

    def doselectLocation(self):
        d = doSelectByLocation.Dialog(self.iface)
        d.exec_()

    def domeanCoords(self):
        d = doMeanCoords.Dialog(self.iface, 1)
        d.exec_()

    def dominConvex(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 2)
        d.exec_()

    def dodynaBuffer(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 1)
        d.exec_()

    def dointersect(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 5)
        d.exec_()

    def dodissolve(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 4)
        d.exec_()

    def doerase(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 3)
        d.exec_()

    def dosymdifference(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 7)
        d.exec_()

    def dounion(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 6)
        d.exec_()

    def doclip(self):
        d = doGeoprocessing.GeoprocessingDialog(self.iface, 8)
        d.exec_()

    def donearestNeigh(self):
        d = doVisual.VisualDialog(self.iface, 4)
        d.exec_()

    def dodistMatrix(self):
        d = doPointDistance.Dialog(self.iface)
        d.exec_()

    def docentroids(self):
        d = doGeometry.GeometryDialog(self.iface, 7)
        d.exec_()

    def dodelaunay(self):
        d = doGeometry.GeometryDialog(self.iface, 8)
        d.exec_()

    def dovoronoi(self):
        d = doGeometry.GeometryDialog(self.iface, 10)
        d.exec_()

    def doextent(self):
        d = doGeometry.GeometryDialog(self.iface, 9)
        d.exec_()

    def dosumLines(self):
        d = doSumLines.Dialog(self.iface)
        d.exec_()

    def dopointsPoly(self):
        d = doPointsInPolygon.Dialog(self.iface)
        d.show()
        d.exec_()

    def dorandSel(self):
        d = doRandom.Dialog(self.iface)
        d.exec_()

    def dorandSub(self):
        d = doSubsetSelect.Dialog(self.iface)
        d.exec_()

    def dorandPoints(self):
        d = doRandPoints.Dialog(self.iface)
        d.exec_()

    def doregPoints(self):
        d = doRegPoints.Dialog(self.iface)
        d.exec_()

    def dovectGrid(self):
        d = doVectorGrid.Dialog(self.iface)
        d.exec_()

    def doextNodes(self):
        d = doGeometry.GeometryDialog(self.iface, 3)
        d.exec_()

    def dointLines(self):
        d = doIntersectLines.Dialog(self.iface)
        d.exec_()

    def dosplitVect(self):
        d = doVectorSplit.Dialog(self.iface)
        d.show()
        d.exec_()

    def docompGeo(self):
        d = doGeometry.GeometryDialog(self.iface, 5)
        d.exec_()

    def dolistUnique(self):
        d = doVisual.VisualDialog(self.iface, 2)
        d.exec_()

    def docompStats(self):
        d = doVisual.VisualDialog(self.iface, 3)
        d.exec_()

    def dodefine(self):
        d = doDefineProj.Dialog(self.iface)
        d.exec_()

    def dospatJoin(self):
        d = doSpatialJoin.Dialog(self.iface)
        d.exec_()

    def doMergeShapes(self):
        d = doMergeShapes.Dialog(self.iface)
        d.show()
        d.exec_()

    def doSpatIndex(self):
        d = doSpatialIndex.Dialog(self.iface)
        d.show()
        d.exec_()

    def doEliminate(self):
        d = doEliminate.Dialog(self.iface)
        d.exec_()
Example #52
0
class MainWindow(QMainWindow, object):
    """
    QMainWindow displays pipeline
    Parameters
    ----------
    port : str
        used port to communicate with pipeline
        Note: The firewall must be configure to accept input/output on this port
    """
    def __init__(self, port):
        super(MainWindow, self).__init__()
        self.setupUi(port)

    def setupUi(self, port):
        self.setObjectName("MainWindow")
        self.resize(600, 600)
        self.centralwidget = QWidget(self)
        p = self.centralwidget.palette()
        self.centralwidget.setAutoFillBackground(True)
        p.setColor(self.centralwidget.backgroundRole(), QColor(126, 135, 152))
        self.centralwidget.setPalette(p)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 808, 25))
        self.menubar.setObjectName("menubar")
        self.menuFile = QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)
        self.actionQuit = QAction(self)
        self.actionQuit.setObjectName("actionQuit")
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionQuit)
        self.menubar.addAction(self.menuFile.menuAction())
        self.actionReset = QAction(self)
        self.actionReset.setObjectName("reset")
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionReset)
        self.menubar.addAction(self.menuFile.menuAction())
        # add other GUI objects
        self.graph_widget = GraphWidget(self.statusbar)
        self.gridLayout.addWidget(self.graph_widget, 1, 11, 10, 10)
        pixmap = QPixmap(':/images/cta-logo-mini.png')
        lbl = QLabel()
        lbl.setPixmap(pixmap)
        self.gridLayout.addWidget(lbl, 0, 0)
        p = self.graph_widget.palette()
        self.graph_widget.setAutoFillBackground(True)
        p.setColor(self.graph_widget.backgroundRole(),
                   QColor(255, 255, 255))  # QColor(226, 235, 252))
        self.graph_widget.setPalette(p)
        self.quitButton = QPushButton()  # self.centralwidget)
        self.quitButton.setObjectName("quitButton")
        self.quitButton.setText(
            QApplication.translate("MainWindow", "Quit", None,
                                   QApplication.UnicodeUTF8))
        self.gridLayout.addWidget(self.quitButton, 12, 0, 1, 1)
        self.info_label = InfoLabel(0, 4)
        self.info_label.setAutoFillBackground(True)
        self.gridLayout.addWidget(self.info_label, 1, 0, 1, 5)
        #self.info_label.setAlignment(PyQt4.Qt.AlignCenter);
        palette = QPalette()
        palette.setColor(self.info_label.backgroundRole(), Qt.lightGray)
        self.info_label.setPalette(palette)
        QObject.connect(self.quitButton, SIGNAL("clicked()"), self.stop)
        QObject.connect(self.actionQuit, SIGNAL("triggered()"), self.stop)
        QMetaObject.connectSlotsByName(self)
        self.retranslateUi()
        QObject.connect(self.actionQuit, SIGNAL("triggered()"), self.close)
        QMetaObject.connectSlotsByName(self)
        # Create GuiConnexion for ZMQ comminucation with pipeline
        self.guiconnection = GuiConnexion(gui_port=port,
                                          statusBar=self.statusbar)
        self.guiconnection.message.connect(self.graph_widget.pipechange)
        self.guiconnection.message.connect(self.info_label.pipechange)
        self.guiconnection.reset_message.connect(self.graph_widget.reset)
        self.guiconnection.reset_message.connect(self.info_label.reset)
        self.guiconnection.mode_message.connect(self.info_label.mode_receive)
        QObject.connect(self.actionReset, SIGNAL("triggered()"),
                        self.guiconnection.reset)
        QMetaObject.connectSlotsByName(self)
        # start the process
        self.guiconnection.start()

    def retranslateUi(self):
        self.setWindowTitle(
            QApplication.translate("ctapipe flow based GUI",
                                   "ctapipe flow based GUI", None,
                                   QApplication.UnicodeUTF8))
        self.menuFile.setTitle(
            QApplication.translate("MainWindow", "File", None,
                                   QApplication.UnicodeUTF8))
        self.actionQuit.setText(
            QApplication.translate("MainWindow", "Quit", None,
                                   QApplication.UnicodeUTF8))
        self.actionReset.setText(
            QApplication.translate("MainWindow", "Reset", None,
                                   QApplication.UnicodeUTF8))

    def stop(self):
        """Method connect (via Qt slot) to exit button
        Stops self.guiconnection (for ZMQ communication) process.
        Close main_windows
        """
        self.guiconnection.finish()
        self.guiconnection.join()
        self.close()

    def closeEvent(self, event):
        self.guiconnection.finish()
        self.guiconnection.join()
        event.accept()  # let the window close
Example #53
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 menubar 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.translator = None
        self.toolbar = None
        self.actions = []  # list of all QActions we create for InaSAFE
        self.setup_i18n()
        #print self.tr('InaSAFE')
        custom_logging.setup_logger()
        # For enable/disable the keyword editor icon
        self.iface.currentLayerChanged.connect(self.layer_changed)

    #noinspection PyArgumentList
    def setup_i18n(self, preferred_locale=None):
        """Setup internationalisation for the plugin.

        See if QGIS wants to override the system locale
        and then see if we can get a valid translation file
        for whatever locale is effectively being used.

        :param preferred_locale: If set will override any other way of
            determining locale.
        :type preferred_locale: str, None
        :raises: TranslationLoadException
        """
        myOverrideFlag = QSettings().value('locale/overrideFlag', False)

        if preferred_locale is not None:
            myLocaleName = preferred_locale
        elif myOverrideFlag:
            myLocaleName = QSettings().value('locale/userLocale', '')
        else:
            myLocaleName = QLocale.system().name()
            # NOTES: we split the locale name because we need the first two
            # character i.e. 'id', 'af, etc
            myLocaleName = str(myLocaleName).split('_')[0]

        # Also set the system locale to the user overridden local
        # so that the inasafe library functions gettext will work
        # .. see:: :py:func:`common.utilities`
        os.environ['LANG'] = str(myLocaleName)

        LOGGER.debug('%s %s %s %s' %
                     (preferred_locale, myOverrideFlag,
                      QLocale.system().name(), os.environ['LANG']))

        myRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        myTranslationPath = os.path.join(
            myRoot, 'safe_qgis', 'i18n',
            'inasafe_' + str(myLocaleName) + '.qm')

        if os.path.exists(myTranslationPath):
            self.translator = QTranslator()
            myResult = self.translator.load(myTranslationPath)
            if not myResult:
                myMessage = 'Failed to load translation for %s' % myLocaleName
                raise TranslationLoadError(myMessage)
            # noinspection PyTypeChecker
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' %
                     (myTranslationPath, os.path.exists(myTranslationPath)))

    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
        return QCoreApplication.translate('Plugin', message)

    def add_action(self, action, add_to_toolbar=True):
        """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

        """
        # 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)

    #noinspection PyCallByClass
    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')
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe_qgis.widgets.dock import Dock
        self.dockWidget = None
        #--------------------------------------
        # Create action for plugin dockable window (show/hide)
        #--------------------------------------
        # pylint: disable=W0201
        self.actionDock = QAction(QIcon(':/plugins/inasafe/icon.svg'),
                                  self.tr('Toggle InaSAFE Dock'),
                                  self.iface.mainWindow())
        self.actionDock.setObjectName('InaSAFEDockToggle')
        self.actionDock.setStatusTip(self.tr('Show/hide InaSAFE dock widget'))
        self.actionDock.setWhatsThis(self.tr('Show/hide InaSAFE dock widget'))
        self.actionDock.setCheckable(True)
        self.actionDock.setChecked(True)
        self.actionDock.triggered.connect(self.toggle_dock_visibility)
        self.add_action(self.actionDock)

        #--------------------------------------
        # Create action for keywords editor
        #--------------------------------------
        self.actionKeywordsDialog = QAction(
            QIcon(':/plugins/inasafe/show-keyword-editor.svg'),
            self.tr('InaSAFE Keyword Editor'), self.iface.mainWindow())
        self.actionKeywordsDialog.setStatusTip(
            self.tr('Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setWhatsThis(
            self.tr('Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setEnabled(False)

        self.actionKeywordsDialog.triggered.connect(self.show_keywords_editor)

        self.add_action(self.actionKeywordsDialog)

        #--------------------------------------
        # Create action for reset icon
        #--------------------------------------
        self.actionResetDock = QAction(
            QIcon(':/plugins/inasafe/reset-dock.svg'), self.tr('Reset Dock'),
            self.iface.mainWindow())
        self.actionResetDock.setStatusTip(self.tr('Reset the InaSAFE Dock'))
        self.actionResetDock.setWhatsThis(self.tr('Reset the InaSAFE Dock'))
        self.actionResetDock.triggered.connect(self.reset_dock)

        self.add_action(self.actionResetDock)

        #--------------------------------------
        # Create action for options dialog
        #--------------------------------------
        self.actionOptions = QAction(
            QIcon(':/plugins/inasafe/configure-inasafe.svg'),
            self.tr('InaSAFE Options'), self.iface.mainWindow())
        self.actionOptions.setStatusTip(self.tr('Open InaSAFE options dialog'))
        self.actionOptions.setWhatsThis(self.tr('Open InaSAFE options dialog'))
        self.actionOptions.triggered.connect(self.show_options)

        self.add_action(self.actionOptions)

        #--------------------------------------
        # Create action for impact functions doc dialog
        #--------------------------------------
        self.actionFunctionBrowser = QAction(
            QIcon(':/plugins/inasafe/show-impact-functions.svg'),
            self.tr('InaSAFE Impact Functions Browser'),
            self.iface.mainWindow())
        self.actionFunctionBrowser.setStatusTip(
            self.tr('Open InaSAFE Impact Functions Browser'))
        self.actionFunctionBrowser.setWhatsThis(
            self.tr('Open InaSAFE Impact Functions Browser'))
        self.actionFunctionBrowser.triggered.connect(
            self.show_function_browser)

        self.add_action(self.actionFunctionBrowser)

        # Short cut for Open Impact Functions Doc
        self.keyAction = QAction("Test Plugin", self.iface.mainWindow())
        self.iface.registerMainWindowAction(self.keyAction, "F7")
        self.keyAction.triggered.connect(self.shortcut_f7)

        #---------------------------------------
        # Create action for minimum needs dialog
        #---------------------------------------
        self.actionMinimumNeeds = QAction(
            QIcon(':/plugins/inasafe/show-minimum-needs.svg'),
            self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow())
        self.actionMinimumNeeds.setStatusTip(
            self.tr('Open InaSAFE minimum needs tool'))
        self.actionMinimumNeeds.setWhatsThis(
            self.tr('Open InaSAFE minimum needs tool'))
        self.actionMinimumNeeds.triggered.connect(self.show_minimum_needs)

        self.add_action(self.actionMinimumNeeds)

        #---------------------------------------
        # Create action for converter dialog
        #---------------------------------------
        self.actionConverter = QAction(
            QIcon(':/plugins/inasafe/show-converter-tool.svg'),
            self.tr('InaSAFE Converter'), self.iface.mainWindow())
        self.actionConverter.setStatusTip(self.tr('Open InaSAFE Converter'))
        self.actionConverter.setWhatsThis(self.tr('Open InaSAFE Converter'))
        self.actionConverter.triggered.connect(self.show_shakemap_importer)

        self.add_action(self.actionConverter)

        #---------------------------------------
        # Create action for batch runner dialog
        #---------------------------------------
        self.actionBatchRunner = QAction(
            QIcon(':/plugins/inasafe/show-batch-runner.svg'),
            self.tr('InaSAFE Batch Runner'), self.iface.mainWindow())
        self.actionBatchRunner.setStatusTip(
            self.tr('Open InaSAFE Batch Runner'))
        self.actionBatchRunner.setWhatsThis(
            self.tr('Open InaSAFE Batch Runner'))
        self.actionBatchRunner.triggered.connect(self.show_batch_runner)

        self.add_action(self.actionBatchRunner)

        #---------------------------------------
        # Create action for batch runner dialog
        #---------------------------------------
        self.actionSaveScenario = QAction(
            QIcon(':/plugins/inasafe/save-as-scenario.svg'),
            self.tr('Save current scenario'), self.iface.mainWindow())

        myMessage = self.tr('Save current scenario to text file')
        self.actionSaveScenario.setStatusTip(myMessage)
        self.actionSaveScenario.setWhatsThis(myMessage)
        # noinspection PyUnresolvedReferences
        self.actionSaveScenario.triggered.connect(self.save_scenario)
        self.add_action(self.actionSaveScenario)

        #--------------------------------------
        # Create action for import OSM Dialog
        #--------------------------------------
        self.actionImportDlg = QAction(
            QIcon(':/plugins/inasafe/show-osm-download.svg'),
            self.tr('InaSAFE OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.actionImportDlg.setStatusTip(
            self.tr('InaSAFE OpenStreetMap Downloader'))
        self.actionImportDlg.setWhatsThis(
            self.tr('InaSAFE OpenStreetMap Downloader'))
        self.actionImportDlg.triggered.connect(self.show_osm_downloader)

        self.add_action(self.actionImportDlg)

        #--------------------------------------
        # create dockwidget and tabify it with the legend
        #--------------------------------------
        self.dockWidget = Dock(self.iface)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockWidget)
        myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend')

        if myLegendTab:
            self.iface.mainWindow().tabifyDockWidget(myLegendTab,
                                                     self.dockWidget)
            self.dockWidget.raise_()

        #
        # Hook up a slot for when the dock is hidden using its close button
        # or  view-panels
        #
        self.dockWidget.visibilityChanged.connect(self.toggle_inasafe_action)

        # pylint: disable=W0201

    def clear_modules(self):
        """Unload inasafe functions and try to return QGIS to before InaSAFE.
        """
        from safe.impact_functions import core

        core.unload_plugins()
        # next lets force remove any inasafe related modules
        myModules = []
        for myModule in sys.modules:
            if 'inasafe' in myModule:
                # Check if it is really one of our modules i.e. exists in the
                #  plugin directory
                myTokens = myModule.split('.')
                myPath = ''
                for myToken in myTokens:
                    myPath += os.path.sep + myToken
                myParent = os.path.abspath(
                    os.path.join(__file__, os.path.pardir, os.path.pardir))
                myFullPath = os.path.join(myParent, myPath + '.py')
                if os.path.exists(os.path.abspath(myFullPath)):
                    LOGGER.debug('Removing: %s' % myModule)
                    myModules.append(myModule)
        for myModule in myModules:
            del (sys.modules[myModule])
        for myModule in sys.modules:
            if 'inasafe' in myModule:
                print myModule

        # Lets also clean up all the path additions that were made
        myPackagePath = os.path.abspath(
            os.path.join(os.path.dirname(__file__), os.path.pardir))
        LOGGER.debug('Path to remove: %s' % myPackagePath)
        # We use a list comprehension to ensure duplicate entries are removed
        LOGGER.debug(sys.path)
        sys.path = [y for y in sys.path if myPackagePath 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
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(myAction)
        self.iface.mainWindow().removeDockWidget(self.dockWidget)
        self.iface.mainWindow().removeToolBar(self.toolbar)
        self.dockWidget.setVisible(False)
        self.dockWidget.destroy()
        self.iface.currentLayerChanged.disconnect(self.layer_changed)

        self.clear_modules()

    def toggle_inasafe_action(self, checked):
        """Check or uncheck 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.actionDock.setChecked(checked)

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

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

        myDialog = MinimumNeeds(self.iface.mainWindow())
        myDialog.exec_()  # modal

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

        myDialog = OptionsDialog(self.iface, self.dockWidget,
                                 self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_keywords_editor(self):
        """Show the keywords editor."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.keywords_dialog import KeywordsDialog

        if self.iface.activeLayer() is None:
            return
        myDialog = KeywordsDialog(self.iface.mainWindow(), self.iface,
                                  self.dockWidget)
        myDialog.exec_()  # modal

    def show_function_browser(self):
        """Show the impact function browser tool."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.function_browser import FunctionBrowser

        myDialog = FunctionBrowser(self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_shakemap_importer(self):
        """Show the converter dialog."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.shakemap_importer import ShakemapImporter

        myDialog = ShakemapImporter(self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_osm_downloader(self):
        """Show the OSM buildings downloader dialog."""
        from safe_qgis.tools.osm_downloader import OsmDownloader

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

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

        myDialog = BatchDialog(parent=self.iface.mainWindow(),
                               iface=self.iface,
                               dock=self.dockWidget)
        myDialog.exec_()  # modal

    def save_scenario(self):
        """Save current scenario to text file,"""
        self.dockWidget.save_current_scenario()

    def reset_dock(self):
        """Reset the dock to its default state."""
        self.dockWidget.get_layers()

    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 layer is None:
            self.actionKeywordsDialog.setEnabled(False)
        else:
            self.actionKeywordsDialog.setEnabled(True)

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()
Example #54
0
class previewDlg(QMainWindow):
    '''
    classdocs
    '''
    def __init__(self, parent, comp, basePMCheck, model):
        '''
        Constructor
        '''

        QMainWindow.__init__(self, parent)

        self.basePMCheck = basePMCheck
        #         self.ui = Ui_Previewself.grbPageProperty()
        #         self.ui.setupUi(self)
        self.resize(1000, 700)
        self.setWindowTitle("Preview Dialog")
        self.view = QgsComposerView(self)
        viewLayout = QGridLayout()
        viewLayout.setSpacing(0)
        viewLayout.setMargin(0)
        mHorizontalRuler = QgsComposerRuler(QgsComposerRuler.Horizontal)
        mVerticalRuler = QgsComposerRuler(QgsComposerRuler.Vertical)
        mRulerLayoutFix = QWidget()
        mRulerLayoutFix.setAttribute(Qt.WA_NoMousePropagation)
        mRulerLayoutFix.setBackgroundRole(QPalette.Window)
        mRulerLayoutFix.setFixedSize(mVerticalRuler.rulerSize(),
                                     mHorizontalRuler.rulerSize())
        viewLayout.addWidget(mRulerLayoutFix, 0, 0)
        viewLayout.addWidget(mHorizontalRuler, 0, 1)
        viewLayout.addWidget(mVerticalRuler, 1, 0)

        self.view.setContentsMargins(0, 0, 0, 0)
        self.view.setHorizontalRuler(mHorizontalRuler)
        self.view.setVerticalRuler(mVerticalRuler)
        viewLayout.addWidget(self.view, 1, 1)

        #         self.scene = comp

        self.view.setZoomLevel(1.0)
        self.view.setComposition(comp)
        self.scene = self.view.composition()
        layout = QVBoxLayout()
        hLayout = QHBoxLayout()
        hLayout.addLayout(viewLayout)

        self.mapItem = self.scene.getComposerMapById(0)

        self.view.scale(2.8, 2.8)
        self.view.setPreviewModeEnabled(True)

        self.toolBarAction = self.addToolBar("composer action")
        self.actionMapRefresh = QAction(self)
        self.actionMapRefresh.setObjectName("actionMapRefresh")
        icon3 = QIcon("Resource/Refresh.png")
        self.actionMapRefresh.setIcon(icon3)
        self.actionMapRefresh.setToolTip("Refresh")
        # self.textItemAction.setCheckable(True)
        self.connect(self.actionMapRefresh, SIGNAL("triggered()"),
                     self.actionMapRefresh_triggered)
        self.toolBarAction.addAction(self.actionMapRefresh)

        # # self.templeteCreateAction = QAction(self)
        # # self.templeteCreateAction.setObjectName("createTempleteAction")
        # # icon4 = QIcon("Resource\\templetepointer.png")
        # # self.templeteCreateAction.setIcon(icon4)
        # # self.templeteCreateAction.setToolTip("Create Templete")
        # # self.templeteCreateAction.setCheckable(True)
        # # self.connect(self.templeteCreateAction, SIGNAL("triggered()"), self.createTempleteAction)
        # # self.toolBar.addAction(self.templeteCreateAction)
        # layout.insertWidget(0, self.toolBar)

        #         self.scene.selectedItemChanged.connect(self.selectedItemDisplay)
        self.view.selectedItemChanged.connect(self.selectedItemDisplay)

        self.view.cursorPosChanged.connect(self.cursorPosChangedEvent)
        #         self.connect(self.view, SIGNAL("selectedItemChanged(QgsComposerItem)"),self, SLOT("selectedItemDisplay(QgsComposerItem)"))
        #         self.scene.composerLabelAdded.connect(self.composerLabelAddedEvent)
        self.view.itemRemoved.connect(self.deleteItem)
        # self.connect( self.view, SIGNAL( "actionFinished()" ), self.setSelectionTool)

        #listen out for position updates from the QgsComposerView
        self.propertyWidget = QWidget(self)
        hLayout.addWidget(self.propertyWidget)
        self.propertyWidget.setObjectName("propertyWidget")
        self.propertyWidget.resize(222, 302)
        self.vLayout_3 = QVBoxLayout(self.propertyWidget)
        self.vLayout_3.setObjectName("vLayout_3")
        self.groupBox = QGroupBox(self.propertyWidget)
        self.groupBox.setObjectName("groupBox")
        self.horizontalLayout_2 = QHBoxLayout(self.groupBox)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.frame = QFrame(self.groupBox)
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)
        self.frame.setObjectName("frame")
        self.verticalLayout = QVBoxLayout(self.frame)
        self.verticalLayout.setObjectName("verticalLayout")
        self.label = QLabel(self.frame)
        self.label.setObjectName("label")
        self.verticalLayout.addWidget(self.label)
        self.labelText = QPlainTextEdit(self.frame)
        self.labelText.setObjectName("labelText")
        self.verticalLayout.addWidget(self.labelText)
        self.btnLabelFont = QPushButton(self.frame)
        self.btnLabelFont.setObjectName("btnLabelFont")
        self.verticalLayout.addWidget(self.btnLabelFont)
        self.btnLabelColor = QPushButton(self.frame)
        self.btnLabelColor.setObjectName("btnLabelColor")
        self.verticalLayout.addWidget(self.btnLabelColor)
        self.frame_2 = QFrame(self.frame)
        self.frame_2.setFrameShape(QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.horizontalLayout = QHBoxLayout(self.frame_2)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.label_2 = QLabel(self.frame_2)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.spinLabelRotation = QSpinBox(self.frame_2)
        self.spinLabelRotation.setObjectName("spinLabelRotation")
        self.spinLabelRotation.setMinimum(-360)
        self.spinLabelRotation.setMaximum(360)
        self.horizontalLayout.addWidget(self.spinLabelRotation)
        self.verticalLayout.addWidget(self.frame_2)
        self.chbBackgroundEnable = QCheckBox(self.frame)
        self.chbBackgroundEnable.setChecked(True)
        self.chbBackgroundEnable.setObjectName("chbBackgroundEnable")
        self.verticalLayout.addWidget(self.chbBackgroundEnable)
        self.horizontalLayout_2.addWidget(self.frame)
        self.vLayout_3.addWidget(self.groupBox)

        self.resolutionFrame = QFrame(self.frame)
        self.resolutionFrame.setFrameShape(QFrame.StyledPanel)
        self.resolutionFrame.setFrameShadow(QFrame.Raised)
        self.resolutionFrame.setObjectName("resolutionFrame")
        self.horizontalLayout4 = QHBoxLayout(self.resolutionFrame)
        self.horizontalLayout4.setObjectName("horizontalLayout4")
        self.label_resolution = QLabel(self.resolutionFrame)
        self.label_resolution.setObjectName("label_resolution")
        self.label_resolution.setText("Print Resolution (dpi):")
        self.horizontalLayout4.addWidget(self.label_resolution)
        self.spinResolution = QSpinBox(self.resolutionFrame)
        self.spinResolution.setObjectName("spinResolution")
        self.spinResolution.setMinimum(0)
        self.spinResolution.setMaximum(1000)
        self.spinResolution.setValue(300)
        self.horizontalLayout4.addWidget(self.spinResolution)
        #         self.verticalLayout.addWidget(self.frame_2)
        self.vLayout_3.addWidget(self.resolutionFrame)

        self.gbTable = GroupBox(self.propertyWidget)
        self.gbTable.Caption = "Table"
        self.vLayout_3.addWidget(self.gbTable)

        self.mTableView = QTableView(self.gbTable)
        self.gbTable.Add = self.mTableView
        hHeder = self.mTableView.horizontalHeader()
        hHeder.setVisible(False)
        vHeder = self.mTableView.verticalHeader()
        vHeder.setVisible(False)
        # self.mTableView.setFixedHeight(70)
        # self.mTableView.setFixedWidth(comp.paperWidth() - 40)

        # self.stdItemModel = QStandardItemModel()
        # self.

        self.spaceItem = QSpacerItem(20, 40, QSizePolicy.Minimum,
                                     QSizePolicy.Expanding)
        self.vLayout_3.addItem(self.spaceItem)

        self.groupBox.setTitle("Label Property")
        self.label.setText("Label Text:")
        self.btnLabelFont.setText("Label Font")
        self.btnLabelColor.setText("Label Color")
        self.label_2.setText("Label Rotation:")
        self.chbBackgroundEnable.setText("Background Enable")
        self.groupBox.setEnabled(False)
        self.connect(self.btnLabelFont, SIGNAL("clicked()"),
                     self.btnLabelFontClick)
        self.connect(self.btnLabelColor, SIGNAL("clicked()"),
                     self.btnLabelColorClick)
        self.connect(self.chbBackgroundEnable, SIGNAL("clicked()"),
                     self.chbBackgroundEnableClick)
        self.labelText.textChanged.connect(self.labelTextChanged)
        self.spinLabelRotation.valueChanged.connect(
            self.spinLabelRotationValueChanged)
        layout.addLayout(hLayout)
        #
        self.btnBack = QPushButton()
        self.btnBack.setText("back")
        footerLayout = QHBoxLayout()
        footerLayout.addWidget(self.btnBack)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        footerLayout.addWidget(self.buttonBox)
        layout.addLayout(footerLayout)
        self.setLayout(layout)

        deleteItemKey = QShortcut(QKeySequence(Qt.Key_Delete), self)
        deleteItemKey.activated.connect(self.deleteItem)

        # self.btnBack.clicked.connect(self.back)
        self.connect(self.buttonBox, SIGNAL("accepted()"), self.acceptMethod)
        self.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)
        self.btnCancel = self.buttonBox.button(QDialogButtonBox.Cancel)
        self.view.setCurrentTool(QgsComposerView.Select)

        self.btnLabelColor.setVisible(False)
        # self.btnBack.setVisible(False)
        self.chbBackgroundEnable.setVisible(False)
        #         self.view.emit(SIGNAL("actionFinished"))

        #         if self.scene.plotStyle() != QgsComposition.Preview:
        #         self.scene.setPlotStyle(QgsComposition.Preview)
        #         self.mapItem.setPreviewMode(QgsComposerMap.Render)
        #         self.mapItem.updateCachedImage()
        #         self.mapItem.setSelected(True)
        self.mComposition = comp
        self.composerMapItem = self.mComposition.composerMapItems()[0]
        self.composerMapItem.setUpdatesEnabled(True)
        self.mStdModel = model

        self.mTableView.setModel(self.mStdModel)
        self.mTableView.setSpan(0, 0, 1, 6)
        self.mTableView.setSpan(1, 0, 1, 2)
        self.mTableView.setSpan(2, 0, 2, 1)
        self.mTableView.setSpan(4, 0, 1, 2)
        self.mTableView.setSpan(5, 0, 1, 2)
        self.mTableView.setSpan(6, 0, 1, 2)

        self.mTableView.setSpan(0, 6, 1, 8)
        self.mTableView.setSpan(1, 7, 1, 4)
        self.mTableView.setSpan(1, 11, 1, 3)
        self.mTableView.setSpan(2, 7, 1, 4)
        self.mTableView.setSpan(2, 11, 1, 3)

    def acceptMethod(self):
        # self.mStdModel.setItem(0, QStandardItem("nnnnnnnn"))
        filePath = QFileDialog.getSaveFileName(
            self, "Save PDF File", QCoreApplication.applicationDirPath(),
            "pdf files(*.pdf )")
        if filePath == "":
            return
        self.mComposition.clearSelection()
        self.mComposition.setPrintResolution(self.spinResolution.value())
        resultPdf = self.mComposition.exportAsPDF(filePath)
        if resultPdf:
            message = QMessageBox.information(self, "Result",
                                              "Successful export PDF")
        else:
            message = QMessageBox.information(self, "Result",
                                              "Don't export PDF")

    def rePresent(self, comp, model):
        self.mComposition = comp
        self.mStdModel = model
        self.view.setComposition(comp)
        self.scene = self.view.composition()

    def back(self):
        self.done(2)

    def spinLabelRotationValueChanged(self, rotationValue):
        self.selectedLabelItem.setItemRotation(rotationValue)

    def cursorPosChangedEvent(self, scenePointF):
        self.scenePoint = scenePointF
#         i = 100

    def labelTextChanged(self):
        self.selectedLabelItem.beginCommand(
            "Label text changed", QgsComposerMergeCommand.ComposerLabelSetText)
        self.selectedLabelItem.blockSignals(True)
        self.selectedLabelItem.setText(self.labelText.toPlainText())
        self.selectedLabelItem.update()
        self.selectedLabelItem.blockSignals(False)
        self.selectedLabelItem.endCommand()

    def chbBackgroundEnableClick(self):
        if self.chbBackgroundEnable.isChecked():
            self.selectedLabelItem.setBackgroundEnabled(True)
            self.mapItem.updateCachedImage()
        else:
            self.selectedLabelItem.setBackgroundEnabled(False)
            self.mapItem.updateCachedImage()

    def btnLabelFontClick(self):
        dlgFont = QFontDialog(self)
        dlgFont.setCurrentFont(self.selectedLabelItem.font())
        result = dlgFont.exec_()
        if result == 1:
            self.labelFont = dlgFont.selectedFont()
        else:
            self.labelFont = QFont()

        self.selectedLabelItem.setFont(self.labelFont)

    def btnLabelColorClick(self):
        dlgColor = QColorDialog(self)
        dlgColor.setCurrentColor(self.selectedLabelItem.fontColor())
        result = dlgColor.exec_()
        if result == 1:
            self.labelColor = dlgColor.selectedColor()
            self.selectedLabelItem.setFontColor(self.labelColor)

    def createTempleteAction(self):
        if self.templeteCreateAction.isChecked() and self.basePMCheck:
            font = QFont("Arial", 13)
            font.setItalic(True)
            self.compLabel1 = QgsComposerLabel(self.scene)
            self.compLabel1.setFont(font)
            self.compLabel1.setText("South China Sea")
            self.compLabel1.setBackgroundEnabled(False)
            self.compLabel1.setItemPosition(156, 100)
            self.compLabel1.adjustSizeToText()
            self.compLabel1.setItemRotation(60)
            #             mapitem = self.scene.composerMapItems()
            #             mapitem[0].addItem(self.compLabel1)
            self.scene.addItem(self.compLabel1)

            self.compLabel2 = QgsComposerLabel(self.scene)
            self.compLabel2.setFont(font)
            self.compLabel2.setText("Straits Of Malacca")
            self.compLabel2.setBackgroundEnabled(False)
            self.compLabel2.setItemPosition(35, 100)
            self.compLabel2.adjustSizeToText()
            self.compLabel2.setItemRotation(60)
            self.scene.addItem(self.compLabel2)

            font.setItalic(False)
            self.compLabel3 = QgsComposerLabel(self.scene)
            self.compLabel3.setFont(font)
            self.compLabel3.setBackgroundEnabled(False)
            self.compLabel3.setText("THAILAND")
            self.compLabel3.setItemPosition(68, 60)
            self.compLabel3.adjustSizeToText()
            #             self.compLabel3.setItemRotation(0.5)
            self.scene.addItem(self.compLabel3)
            #             self.templeteCreateAction.setChecked(False)

            self.compLabel4 = QgsComposerLabel(self.scene)
            self.compLabel4.setFont(font)
            self.compLabel4.setBackgroundEnabled(False)
            self.compLabel4.setText("SINGAPORE")
            self.compLabel4.setItemPosition(141, 218)
            self.compLabel4.adjustSizeToText()
            #             self.compLabel3.setItemRotation(0.5)
            self.scene.addItem(self.compLabel4)
            self.templeteCreateAction.setChecked(False)
            self.compLabel4.setSelected(True)
        elif self.templeteCreateAction.isChecked(
        ) and self.basePMCheck == False:
            font = QFont("Arial", 14)
            font.setItalic(True)
            self.compLabel5 = QgsComposerLabel(self.scene)
            self.compLabel5.setFont(font)
            self.compLabel5.setText("South China Sea")
            self.compLabel5.setBackgroundEnabled(False)
            self.compLabel5.setItemPosition(108, 86)
            self.compLabel5.adjustSizeToText()
            self.compLabel5.setItemRotation(-45)
            #             mapitem = self.scene.composerMapItems()
            #             mapitem[0].addItem(self.compLabel1)
            self.scene.addItem(self.compLabel5)

            self.compLabel6 = QgsComposerLabel(self.scene)
            self.compLabel6.setFont(font)
            self.compLabel6.setText("Sulu Sea")
            self.compLabel6.setBackgroundEnabled(False)
            self.compLabel6.setItemPosition(236, 38)
            self.compLabel6.adjustSizeToText()
            self.compLabel6.setItemRotation(45)
            self.scene.addItem(self.compLabel6)

            font.setItalic(False)
            self.compLabel7 = QgsComposerLabel(self.scene)
            self.compLabel7.setFont(font)
            self.compLabel7.setBackgroundEnabled(False)
            self.compLabel7.setText("Celebes Sea")
            self.compLabel7.setItemPosition(242, 112)
            self.compLabel7.adjustSizeToText()
            self.compLabel7.setItemRotation(-45)
            #             self.compLabel3.setItemRotation(0.5)
            self.scene.addItem(self.compLabel7)
            #             self.templeteCreateAction.setChecked(False)

            self.compLabel8 = QgsComposerLabel(self.scene)
            self.compLabel8.setFont(font)
            self.compLabel8.setBackgroundEnabled(False)
            self.compLabel8.setText("INDONESIA\n(Kalimantan)")
            self.compLabel8.setItemPosition(172, 148, 32, 16)
            #             self.compLabel8.setHAlign(Qt.AlignHCenter)
            #             self.compLabel8.setVAlign(Qt.AlignVCenter)
            #             self.compLabel8.setFrameEnabled(False)
            #             self.compLabel8.setItemPosition()
            #             self.compLabel8.adjustSizeToText()
            #             self.compLabl3.setItemRotation(0.5)
            self.scene.addItem(self.compLabel8)

            self.compLabel9 = QgsComposerLabel(self.scene)
            self.compLabel9.setFont(font)
            self.compLabel9.setBackgroundEnabled(False)
            self.compLabel9.setText("BRUNEI")
            self.compLabel9.setItemPosition(136, 83)
            self.compLabel9.adjustSizeToText()
            #             self.compLabl3.setItemRotation(0.5)
            self.scene.addItem(self.compLabel9)
            self.templeteCreateAction.setChecked(False)

        pass

    def actionMapRefresh_triggered(self):

        self.view.setCurrentTool(QgsComposerView.AddRectangle)

    def setSelectionTool(self):
        self.view.deleteSelectedItems()
        font = QFont("Arial", 14)
        newLabelItem = QgsComposerLabel(self.scene)
        newLabelItem.setText("QGIS")
        newLabelItem.setFont(font)

        newLabelItem.setItemPosition(self.scenePoint.x(), self.scenePoint.y())
        newLabelItem.adjustSizeToText()

        self.scene.addItem(newLabelItem)
        #         selectItemPoint = self.scene.composerItemAt(self.scenePoint)
        newLabelItem.setSelected(True)
        self.groupBox.setEnabled(True)
        self.selectedLabelItem = newLabelItem
        #         txt = self.selectedLabelItem.text()
        #         textDoc = QTextDocument(txt)
        self.labelText.setPlainText(self.selectedLabelItem.text())
        #         self.scene.setSelectedItem(self.newLabelItem)

        self.view.setCurrentTool(QgsComposerView.Select)
        #         self.selectedLabelItem = self.view.currentTool()
        self.textItemAction.setChecked(False)

    def selectedItemDisplay(self, item):

        if self.scene.plotStyle() != QgsComposition.Preview:
            self.scene.setPlotStyle(QgsComposition.Preview)
            self.mapItem.setPreviewMode(QgsComposerMap.Render)
            self.mapItem.updateCachedImage()
        item._class_ = QgsComposerLabel
        #         selectedItems = self.scene.selectedComposerItems(True)
        #         if isinstance(item, QgsComposerItem):
        #             self.selectedLabelItem = item
        #         if isinstance(item, QGraphicsRectItem):
        #             self.selectedLabelItem = item
        if isinstance(item, QgsComposerLabel):
            self.selectedLabelItem = item
            self.groupBox.setEnabled(True)
            self.labelText.setPlainText(self.selectedLabelItem.text())
            self.spinLabelRotation.setValue(self.selectedLabelItem.rotation())
        else:
            self.groupBox.setEnabled(False)
#         print "debug"
        itemName = self.view.currentTool()
        if itemName == 5:
            item.setText("label")
        pass

    def deleteItem(self):
        self.view.deleteSelectedItems()
        def addActions():
            actn = QAction(winLegend)
            actn.setIcon(qgis.utils.iface.actionShowSelectedLayers().icon())
            actn.setIconText('Show selected layers')
            actn.setObjectName('showLayer')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)

            actn = QAction(winLegend)
            actn.setIcon(qgis.utils.iface.actionHideSelectedLayers().icon())
            actn.setIconText('Hide selected layers')
            actn.setObjectName('hideLayer')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)

            actn = QAction(winLegend)
            actn.setIcon(qgis.utils.iface.actionRemoveLayer().icon())
            actn.setIconText('Remove selected layers')
            actn.setObjectName('removeLayer')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)

            toolBar.addSeparator()

            actn = QAction(winLegend)
            actn.setIcon(qgis.utils.iface.actionDuplicateLayer().icon())
            actn.setIconText('Add selected layers from main map')
            actn.setObjectName('addLayer')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)

            actn = QAction(winLegend)
            actn.setIcon(
                QIcon(
                    os.path.join(os.path.dirname(__file__),
                                 'mActionCurrentLayer.png')))
            actn.setIconText('Current layer for main map')
            actn.setObjectName('currentLayer')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)

            actn = QAction(winLegend)
            actn.setIcon(
                QIcon(
                    os.path.join(os.path.dirname(__file__),
                                 'mActionAddGroup.png')))
            actn.setObjectName('syncGroup')
            actn.triggered.connect(self.onAction)
            toolBar.addAction(actn)
Example #56
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 menubar 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.translator = None
        self.toolbar = None
        self.actions = []  # list of all QActions we create for InaSAFE
        self.setup_i18n()
        #print self.tr('InaSAFE')
        custom_logging.setup_logger()
        # For enable/disable the keyword editor icon
        self.iface.currentLayerChanged.connect(self.layer_changed)

    #noinspection PyArgumentList
    def setup_i18n(self, preferred_locale=None):
        """Setup internationalisation for the plugin.

        See if QGIS wants to override the system locale
        and then see if we can get a valid translation file
        for whatever locale is effectively being used.

        :param preferred_locale: If set will override any other way of
            determining locale.
        :type preferred_locale: str, None
        :raises: TranslationLoadException
        """
        myOverrideFlag = QSettings().value('locale/overrideFlag', False)

        if preferred_locale is not None:
            myLocaleName = preferred_locale
        elif myOverrideFlag:
            myLocaleName = QSettings().value('locale/userLocale', '')
        else:
            myLocaleName = QLocale.system().name()
            # NOTES: we split the locale name because we need the first two
            # character i.e. 'id', 'af, etc
            myLocaleName = str(myLocaleName).split('_')[0]

        # Also set the system locale to the user overridden local
        # so that the inasafe library functions gettext will work
        # .. see:: :py:func:`common.utilities`
        os.environ['LANG'] = str(myLocaleName)

        LOGGER.debug('%s %s %s %s' % (
            preferred_locale,
            myOverrideFlag,
            QLocale.system().name(),
            os.environ['LANG']))

        myRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        myTranslationPath = os.path.join(
            myRoot, 'safe_qgis', 'i18n',
            'inasafe_' + str(myLocaleName) + '.qm')

        if os.path.exists(myTranslationPath):
            self.translator = QTranslator()
            myResult = self.translator.load(myTranslationPath)
            if not myResult:
                myMessage = 'Failed to load translation for %s' % myLocaleName
                raise TranslationLoadError(myMessage)
            # noinspection PyTypeChecker
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' % (
            myTranslationPath,
            os.path.exists(myTranslationPath)))

    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
        return QCoreApplication.translate('Plugin', message)

    def add_action(self, action, add_to_toolbar=True):
        """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

        """
        # 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)

    #noinspection PyCallByClass
    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')
        # Import dock here as it needs to be imported AFTER i18n is set up
        from safe_qgis.widgets.dock import Dock
        self.dockWidget = None
        #--------------------------------------
        # Create action for plugin dockable window (show/hide)
        #--------------------------------------
        # pylint: disable=W0201
        self.actionDock = QAction(
            QIcon(':/plugins/inasafe/icon.svg'),
            self.tr('Toggle InaSAFE Dock'), self.iface.mainWindow())
        self.actionDock.setObjectName('InaSAFEDockToggle')
        self.actionDock.setStatusTip(self.tr(
            'Show/hide InaSAFE dock widget'))
        self.actionDock.setWhatsThis(self.tr(
            'Show/hide InaSAFE dock widget'))
        self.actionDock.setCheckable(True)
        self.actionDock.setChecked(True)
        self.actionDock.triggered.connect(self.toggle_dock_visibility)
        self.add_action(self.actionDock)

        #--------------------------------------
        # Create action for keywords editor
        #--------------------------------------
        self.actionKeywordsDialog = QAction(
            QIcon(':/plugins/inasafe/show-keyword-editor.svg'),
            self.tr('InaSAFE Keyword Editor'),
            self.iface.mainWindow())
        self.actionKeywordsDialog.setStatusTip(self.tr(
            'Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setWhatsThis(self.tr(
            'Open InaSAFE keywords editor'))
        self.actionKeywordsDialog.setEnabled(False)

        self.actionKeywordsDialog.triggered.connect(self.show_keywords_editor)

        self.add_action(self.actionKeywordsDialog)

        #--------------------------------------
        # Create action for reset icon
        #--------------------------------------
        self.actionResetDock = QAction(
            QIcon(':/plugins/inasafe/reset-dock.svg'),
            self.tr('Reset Dock'), self.iface.mainWindow())
        self.actionResetDock.setStatusTip(self.tr(
            'Reset the InaSAFE Dock'))
        self.actionResetDock.setWhatsThis(self.tr(
            'Reset the InaSAFE Dock'))
        self.actionResetDock.triggered.connect(self.reset_dock)

        self.add_action(self.actionResetDock)

        #--------------------------------------
        # Create action for options dialog
        #--------------------------------------
        self.actionOptions = QAction(
            QIcon(':/plugins/inasafe/configure-inasafe.svg'),
            self.tr('InaSAFE Options'), self.iface.mainWindow())
        self.actionOptions.setStatusTip(self.tr(
            'Open InaSAFE options dialog'))
        self.actionOptions.setWhatsThis(self.tr(
            'Open InaSAFE options dialog'))
        self.actionOptions.triggered.connect(self.show_options)

        self.add_action(self.actionOptions)

        #--------------------------------------
        # Create action for impact functions doc dialog
        #--------------------------------------
        self.actionFunctionBrowser = QAction(
            QIcon(':/plugins/inasafe/show-impact-functions.svg'),
            self.tr('InaSAFE Impact Functions Browser'),
            self.iface.mainWindow())
        self.actionFunctionBrowser.setStatusTip(self.tr(
            'Open InaSAFE Impact Functions Browser'))
        self.actionFunctionBrowser.setWhatsThis(self.tr(
            'Open InaSAFE Impact Functions Browser'))
        self.actionFunctionBrowser.triggered.connect(
            self.show_function_browser)

        self.add_action(self.actionFunctionBrowser)

        # Short cut for Open Impact Functions Doc
        self.keyAction = QAction("Test Plugin", self.iface.mainWindow())
        self.iface.registerMainWindowAction(self.keyAction, "F7")
        self.keyAction.triggered.connect(self.shortcut_f7)

        #---------------------------------------
        # Create action for minimum needs dialog
        #---------------------------------------
        self.actionMinimumNeeds = QAction(
            QIcon(':/plugins/inasafe/show-minimum-needs.svg'),
            self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow())
        self.actionMinimumNeeds.setStatusTip(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.actionMinimumNeeds.setWhatsThis(self.tr(
            'Open InaSAFE minimum needs tool'))
        self.actionMinimumNeeds.triggered.connect(self.show_minimum_needs)

        self.add_action(self.actionMinimumNeeds)

        #---------------------------------------
        # Create action for converter dialog
        #---------------------------------------
        self.actionConverter = QAction(
            QIcon(':/plugins/inasafe/show-converter-tool.svg'),
            self.tr('InaSAFE Converter'), self.iface.mainWindow())
        self.actionConverter.setStatusTip(self.tr(
            'Open InaSAFE Converter'))
        self.actionConverter.setWhatsThis(self.tr(
            'Open InaSAFE Converter'))
        self.actionConverter.triggered.connect(self.show_shakemap_importer)

        self.add_action(self.actionConverter)

        #---------------------------------------
        # Create action for batch runner dialog
        #---------------------------------------
        self.actionBatchRunner = QAction(
            QIcon(':/plugins/inasafe/show-batch-runner.svg'),
            self.tr('InaSAFE Batch Runner'), self.iface.mainWindow())
        self.actionBatchRunner.setStatusTip(self.tr(
            'Open InaSAFE Batch Runner'))
        self.actionBatchRunner.setWhatsThis(self.tr(
            'Open InaSAFE Batch Runner'))
        self.actionBatchRunner.triggered.connect(self.show_batch_runner)

        self.add_action(self.actionBatchRunner)

        #---------------------------------------
        # Create action for batch runner dialog
        #---------------------------------------
        self.actionSaveScenario = QAction(
            QIcon(':/plugins/inasafe/save-as-scenario.svg'),
            self.tr('Save current scenario'), self.iface.mainWindow())

        myMessage = self.tr('Save current scenario to text file')
        self.actionSaveScenario.setStatusTip(myMessage)
        self.actionSaveScenario.setWhatsThis(myMessage)
        # noinspection PyUnresolvedReferences
        self.actionSaveScenario.triggered.connect(self.save_scenario)
        self.add_action(self.actionSaveScenario)

        #--------------------------------------
        # Create action for import OSM Dialog
        #--------------------------------------
        self.actionImportDlg = QAction(
            QIcon(':/plugins/inasafe/show-osm-download.svg'),
            self.tr('InaSAFE OpenStreetMap Downloader'),
            self.iface.mainWindow())
        self.actionImportDlg.setStatusTip(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.actionImportDlg.setWhatsThis(self.tr(
            'InaSAFE OpenStreetMap Downloader'))
        self.actionImportDlg.triggered.connect(self.show_osm_downloader)

        self.add_action(self.actionImportDlg)

        #--------------------------------------
        # create dockwidget and tabify it with the legend
        #--------------------------------------
        self.dockWidget = Dock(self.iface)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockWidget)
        myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend')

        if myLegendTab:
            self.iface.mainWindow().tabifyDockWidget(
                myLegendTab, self.dockWidget)
            self.dockWidget.raise_()

        #
        # Hook up a slot for when the dock is hidden using its close button
        # or  view-panels
        #
        self.dockWidget.visibilityChanged.connect(self.toggle_inasafe_action)

        # pylint: disable=W0201

    def clear_modules(self):
        """Unload inasafe functions and try to return QGIS to before InaSAFE.
        """
        from safe.impact_functions import core

        core.unload_plugins()
        # next lets force remove any inasafe related modules
        myModules = []
        for myModule in sys.modules:
            if 'inasafe' in myModule:
                # Check if it is really one of our modules i.e. exists in the
                #  plugin directory
                myTokens = myModule.split('.')
                myPath = ''
                for myToken in myTokens:
                    myPath += os.path.sep + myToken
                myParent = os.path.abspath(os.path.join(
                    __file__, os.path.pardir, os.path.pardir))
                myFullPath = os.path.join(myParent, myPath + '.py')
                if os.path.exists(os.path.abspath(myFullPath)):
                    LOGGER.debug('Removing: %s' % myModule)
                    myModules.append(myModule)
        for myModule in myModules:
            del (sys.modules[myModule])
        for myModule in sys.modules:
            if 'inasafe' in myModule:
                print myModule

        # Lets also clean up all the path additions that were made
        myPackagePath = os.path.abspath(os.path.join(
            os.path.dirname(__file__), os.path.pardir))
        LOGGER.debug('Path to remove: %s' % myPackagePath)
        # We use a list comprehension to ensure duplicate entries are removed
        LOGGER.debug(sys.path)
        sys.path = [y for y in sys.path if myPackagePath 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
        for myAction in self.actions:
            self.iface.removePluginMenu(self.tr('InaSAFE'), myAction)
            self.iface.removeToolBarIcon(myAction)
        self.iface.mainWindow().removeDockWidget(self.dockWidget)
        self.iface.mainWindow().removeToolBar(self.toolbar)
        self.dockWidget.setVisible(False)
        self.dockWidget.destroy()
        self.iface.currentLayerChanged.disconnect(self.layer_changed)

        self.clear_modules()

    def toggle_inasafe_action(self, checked):
        """Check or uncheck 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.actionDock.setChecked(checked)

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

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

        myDialog = MinimumNeeds(self.iface.mainWindow())
        myDialog.exec_()  # modal

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

        myDialog = OptionsDialog(
            self.iface,
            self.dockWidget,
            self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_keywords_editor(self):
        """Show the keywords editor."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.keywords_dialog import KeywordsDialog

        if self.iface.activeLayer() is None:
            return
        myDialog = KeywordsDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dockWidget)
        myDialog.exec_()  # modal

    def show_function_browser(self):
        """Show the impact function browser tool."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.function_browser import FunctionBrowser

        myDialog = FunctionBrowser(self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_shakemap_importer(self):
        """Show the converter dialog."""
        # import here only so that it is AFTER i18n set up
        from safe_qgis.tools.shakemap_importer import ShakemapImporter

        myDialog = ShakemapImporter(self.iface.mainWindow())
        myDialog.exec_()  # modal

    def show_osm_downloader(self):
        """Show the OSM buildings downloader dialog."""
        from safe_qgis.tools.osm_downloader import OsmDownloader

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

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

        myDialog = BatchDialog(
            parent=self.iface.mainWindow(),
            iface=self.iface,
            dock=self.dockWidget)
        myDialog.exec_()  # modal

    def save_scenario(self):
        """Save current scenario to text file,"""
        self.dockWidget.save_current_scenario()

    def reset_dock(self):
        """Reset the dock to its default state."""
        self.dockWidget.get_layers()

    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 layer is None:
            self.actionKeywordsDialog.setEnabled(False)
        else:
            self.actionKeywordsDialog.setEnabled(True)

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()
Example #57
0
def create_action(
        icon_path,
        text,
        callback,
        enabled_flag=True,
        status_tip=None,
        whats_this=None,
        parent=None,
        object_name=None):

    """
    # adapted from RedLayers by E. Ferreguti
    Create an action.

    :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 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.

    :param object_name: Optional name to identify objects during customization
    :type object_name: str

    :returns: The action that was created.
    :rtype: QAction
    """

    icon = QIcon(icon_path)

    action = QAction(icon, text, parent)
    if callback:
        action.triggered.connect(callback)
    action.setEnabled(enabled_flag)

    if status_tip:
        action.setStatusTip(status_tip)

    if whats_this:
        action.setWhatsThis(whats_this)

    if object_name:
        action.setObjectName(object_name)

    return action
Example #58
0
class RECS:
    """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',
            'RECS_HOME_{}.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
        self.initdlg=InitTaskDialog()
        self.selectdlg = SelectTaskDialog()
        self.loginDlg=LogInDialog()
        self.taskMgrDlg=TaskManagerDialog()
        self.taskInfoDlg=taskInfo()
        self.taskFeaturesDlg=taskFeatures()
        #self.loadmapDlg=LoadMapDialog()
        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Task')
        self.logIn()
        self.selectTask()
        self.actions = []

        self.toolbar = self.iface.addToolBar(u'Recs')
        self.toolbar.setObjectName(u'Recs')


        # layer.editingStarted.connect(editLayer() )




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

    # 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('Tasks', 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.toolbar.addAction(action)

        if add_to_menu:
            # self.menu = QMenu( "&Task", self.iface.mainWindow().menuBar() )
            action = self.iface.mainWindow().menuBar().actions()
            lastAction = action[-1]
            self.iface.addPluginToMenu(
                self.menu,
                lastAction)

        self.actions.append(lastAction)

        return action

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

        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        """ Task menu setting """
        self.menu = QMenu(self.iface.mainWindow())
        self.menu.setObjectName("task_menu_object")
        self.menu.setTitle("Task")





        """ Task """
        self.action_tasks = QAction(QIcon('::/plugins/RECS/aacadisicon.png'), "Tasks", self.iface.mainWindow())
        self.action_tasks.setObjectName("Task_action_object")
        self.action_tasks.setWhatsThis("Task Initialized")
        #QtCore.QObject.connect(self.action_tasks, SIGNAL("triggered()"), self.tasks)

        """ Initializing Task """
        self.action_init_task = QAction(QIcon('::/plugins/RECS/aacadisicon.png'), "Initialize ", self.iface.mainWindow())
        self.action_init_task.setObjectName("Task_action_object")
        self.action_init_task.setWhatsThis("Task Initialize")
        QtCore.QObject.connect(self.action_init_task, SIGNAL("triggered()"), self.initTask)


        """ Select Task """
        self.action_select_task = QAction(QIcon(':/plugins/RECS/aacadisicon.png'), "Select Task", self.iface.mainWindow())
        self.action_select_task.setObjectName("Task_Select_object")
        self.action_select_task.setWhatsThis("Select Task")
        QtCore.QObject.connect(self.action_select_task, SIGNAL("triggered()"), self.selectTask)

        """ Reload Task """
        self.action_reload_task = QAction(QIcon(':/plugins/RECS/aacadisicon.png'), "Reload Task", self.iface.mainWindow())
        self.action_reload_task.setObjectName("Task_Reload_object")
        self.action_reload_task.setWhatsThis("Reload Task")
        QtCore.QObject.connect(self.action_reload_task, SIGNAL("triggered()"), self.taskManager)

        """ Edit Task """
        self.action_edit_task = QAction(QIcon(':/plugins/RECS/aacadisicon.png'), "Edit Task", self.iface.mainWindow())
        self.action_edit_task.setObjectName("Task_Edit_object")
        self.action_edit_task.setWhatsThis("Edit Task")
        QtCore.QObject.connect(self.action_edit_task, SIGNAL("triggered()"), self.editLayer)


        """ Finish Task """
        self.action_finish_task = QAction(QIcon(':/plugins/RECS/aacadisicon.png'), "Finish Task", self.iface.mainWindow())
        self.action_finish_task.setObjectName("Task_Finish_object")
        self.action_finish_task.setWhatsThis("Edit Task")
        QtCore.QObject.connect(self.action_finish_task, SIGNAL("triggered()"), self.finishEditngLayer)


        """ Add action to the menu list """
        #self.menuTask.addAction(self.action_tasks)

        self.menu.addAction(self.action_init_task)
        self.menu.addAction(self.action_select_task)
        self.menu.addAction(self.action_reload_task)
        self.menu.addAction(self.action_edit_task)
        self.menu.addAction(self.action_finish_task)

        """ Add menu to the menubar """
        menubar=self.iface.mainWindow().menuBar()
        menubar.insertMenu(self.iface.firstRightStandardMenu().menuAction(),self.menu)



        """ Add icon to the toolbar """
        #self.iface.addPluginToMenu(u"&load Map", self.action_loadmap)
        #self.iface.addToolBarIcon(self.action_init_task)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(
                self.tr(u'&Task_Manager'),
                action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar
    def initTask(self):

        layers = self.iface.legendInterface().layers()
        #layer_list = []
        for layer in layers:
           #layer_list.append(layer.name())
           if layer.name() == 'PARCEL':
            self.iface.setActiveLayer(layer)
        self.initdlg.show()
        #layer_list=list(set(layer_list))
        #self.initdlg.comboBox.addItems(layer_list)
        self.initdlg.setFixedSize(self.initdlg.size())
        result = self.initdlg.exec_()
        if result:
            pass
    def selectTask(self):
        self.selectdlg.show()
        self.selectdlg.setFixedSize(self.selectdlg.size())

        self.selectdlg.loadLayer()
        self.selectdlg.populate()
        result = self.selectdlg.exec_()
        if result:
            # self.selectdlg.close()
            pass
    def showTaskInfo(self):
        self.taskInfoDlg.show()
        t_id = self.taskMgrDlg.retTaskID()
        self.taskInfoDlg.getAttribData(t_id)
        #self.taskInfoDlg.populate()
    def taskManager(self):

        if self.taskMgrDlg.isVisible():
            self.taskMgrDlg.loadTaskClicked()
            # self.taskMgrDlg.close()
            # self.apdockwidget.close()
        else:
            self.taskMgrDlg.show()
            self.apdockwidget = QDockWidget("Task Manager", self.iface.mainWindow())
            self.apdockwidget.setWindowFlags(Qt.FramelessWindowHint)
            self.apdockwidget.setWidget(self.taskMgrDlg)
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.apdockwidget)
            self.taskMgrDlg.populate()
            self.taskFeatures()




        # rows = self.taskMgrDlg.taskListTable.rowCount()
        # createdByList=[]
        #
        #
        # for row in range(0,rows):
        #     createdByItems=self.taskMgrDlg.taskListTable.item(row,1)
        #     createdByList.append(createdByItems.text())
        #
        #
        # createdByList=list(set(createdByList))
        # self.taskMgrDlg.createByComboBox.addItems(createdByList)
        # self.taskMgrDlg.createByComboBox.setCurrentIndex(createdByList.index())
        self.menu = QtGui.QMenu()
        #newTask=self.menu.addAction("New Task",self.newTask,"")
        newTask = self.menu.addAction("New Task", self.newTaskEvent)
        loadTask = self.menu.addAction("Load Task", self.loadTaskEvent)
        cancelTask = self.menu.addAction("Cancel Task", self.cancelTaskEvent)
        showTaskArea = self.menu.addAction("Show Task Area", self.showTaskAreaEvent)
        noTask=self.menu.addAction("No Task",self.noTaskEvent)
        showTaskInfo=self.menu.addAction("Show Task Info",self.showTaskInfoEvent)
        updateFeature=self.menu.addAction("Update Features",self.updateFeatureEvent)

        self.taskMgrDlg.taskListTable.addAction(newTask)
        self.taskMgrDlg.taskListTable.addAction(loadTask)
        self.taskMgrDlg.taskListTable.addAction(cancelTask)
        self.taskMgrDlg.taskListTable.addAction(showTaskArea)
        self.taskMgrDlg.taskListTable.addAction(noTask)
        self.taskMgrDlg.taskListTable.addAction(showTaskInfo)
        self.taskMgrDlg.taskListTable.addAction(updateFeature)
        self.taskMgrDlg.taskListTable.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.taskMgrDlg.taskListTable.customContextMenuRequested.connect(self.contextMenuEvent)
        result = self.taskMgrDlg.exec_()
        if result:
            self.taskMgrDlg.populate()
        #self.connect(self.dateTimeEdit,SIGNAL("dateTimeChange
    def contextMenuEvent(self, point):
        self.menu.exec_(self.taskMgrDlg.taskListTable.mapToGlobal(point))
    def newTaskEvent(self):
        self.initTask()
    def loadTaskEvent(self):
        self.taskMgrDlg.loadTaskClicked()
        t_id = self.taskMgrDlg.retTaskID()
        self.taskFeaturesDlg.populate(t_id)
    def cancelTaskEvent(self):
        self.taskMgrDlg.cancelTask()
    def showTaskAreaEvent(self):
        self.taskMgrDlg.showTaskAreaClicked()
    def noTaskEvent(self):
        print "noTask Called"
    def showTaskInfoEvent(self):
        self.showTaskInfo()
    def updateFeatureEvent(self):
        print "updateFeature"
    def logIn(self):

        self.loginDlg.show()
        self.loginDlg.setWindowFlags(Qt.FramelessWindowHint)
        result = self.loginDlg.exec_()
        if result:
            pass
    def loadLayer(self):
        self.mlr = None
        # QgsMapLayerRegistry.instance().removeAllMapLayers()
        self.mlr = QgsMapLayerRegistry.instance()
        uri = QgsDataSourceURI()
        uri.setConnection("172.20.0.71", "5432", "ncrprs_db", "postgres", "123456")
        uri.setDataSource("recs", "t_parcel", "parcelgeometry", "")
        vlayer = QgsVectorLayer(uri.uri(), "Parcel", "postgres")
        if vlayer.isValid():
            self.mlr.addMapLayer(vlayer)
        else:
            QMessageBox.information(None, "Unable to Laod Data", "Unable to Load Layers from the Database!")
            return None
    def editLayer(self):
        global taskLayer
        global featCount
        layers = self.iface.legendInterface().layers()
        for layer in layers:
            if layer.name() == 'TaskLayer':
                taskLayer = layer
                taskLayerID=layer.id()
                self.iface.setActiveLayer(taskLayer)
        featCount = taskLayer.featureCount()
        print featCount
        taskLayer.startEditing()
        QgsProject.instance().setSnapSettingsForLayer(taskLayerID,True,2,1,20,True)
    def finishEditngLayer(self):

        """
        change the edits to GML again to detect the changes

        """
        print featCount
        taskLayer_shape = iface.activeLayer()
        QgsVectorFileWriter.writeAsVectorFormat(taskLayer_shape,"Z:\\GMLEdited\\temp.gml","utf-8",None,"GML")

        #QgsMapLayerRegistry.instance().removeAllMapLayers()
        iface.addVectorLayer("Z:\\GMLEdited\\temp.gml","EditedTaskLayer","ogr")
        """
        Compare the two gml geometries
        """

        doc_edited = xml.dom.minidom.parse("Z:\\GMLEdited\\temp.gml")
        doc_origion = xml.dom.minidom.parse("Z:\\GMLFile\\ogrGML.gml")
        editedParcel = doc_edited.getElementsByTagName("gml:featureMember")
        epLength = editedParcel.length
        print epLength
        obj = GeometryEdit()
        if epLength > featCount:
           obj.split(doc_edited,doc_origion)
           print "split"
        elif epLength < featCount:
            obj.merge(doc_edited,doc_origion)
            print "merge"
        else:
            obj.updateGeom()
            print "update"
    def taskFeatures(self):
        self.taskFeaturesDlg.show()
        self.apdockwidget = QDockWidget("Features Of Current Task", self.iface.mainWindow())
        self.apdockwidget.setWindowFlags(Qt.FramelessWindowHint)
        self.apdockwidget.setWidget(self.taskFeaturesDlg)
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.apdockwidget)


        self.menu_feature = QtGui.QMenu()
        #newTask=self.menu.addAction("New Task",self.newTask,"")
        editAttr = self.menu_feature.addAction("Edit", self.editEvent)
        self.taskFeaturesDlg.currentTaskTable.addAction(editAttr)
        self.taskFeaturesDlg.currentTaskTable.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.taskFeaturesDlg.currentTaskTable.customContextMenuRequested.connect(self.contextMenuEvent2)

        #self.connect(self.dateTimeEdit,SIGNAL("dateTimeChange
    def contextMenuEvent2(self, point):
        self.menu_feature.exec_(self.taskFeaturesDlg.currentTaskTable.mapToGlobal(point))
    def editEvent(self):
        self.showTaskInfo()
Example #59
0
class Plugin(object):
    """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
        """
        # Register all the impact functions
        register_impact_functions()
        # Save reference to the QGIS interface
        self.iface = iface
        self.dock_widget = None
        self.action_import_dialog = None
        self.action_save_scenario = None
        self.action_batch_runner = None
        self.action_shake_converter = None
        self.action_minimum_needs = None
        self.action_minimum_needs_config = None
        self.action_impact_merge_dlg = None
        self.key_action = None
        self.action_options = None
        self.action_keywords_wizard = None
        self.action_function_centric_wizard = None
        self.action_extent_selector = None
        self.translator = None
        self.toolbar = None
        self.wizard = None
        self.actions = []  # list of all QActions we create for InaSAFE
        self.action_dock = None
        self.action_toggle_rubberbands = None
        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)

    # noinspection PyArgumentList
    def change_i18n(self, new_locale):
        """Change internationalisation for the plugin.

        Override the system locale  and then see if we can get a valid
        translation file for whatever locale is effectively being used.

        :param new_locale: The new locale i.e. 'id', 'af', etc.
        :type new_locale: str

        :raises: TranslationLoadException
        """

        os.environ['INASAFE_LANG'] = str(new_locale)

        LOGGER.debug('%s %s %s' % (
            new_locale, QLocale.system().name(), os.environ['INASAFE_LANG']))

        root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
        translation_path = os.path.join(
            root, 'safe_qgis', 'i18n',
            'inasafe_' + str(new_locale) + '.qm')

        if os.path.exists(translation_path):
            self.translator = QTranslator()
            result = self.translator.load(translation_path)
            if not result:
                message = 'Failed to load translation for %s' % new_locale
                raise TranslationLoadError(message)
            # noinspection PyTypeChecker,PyCallByClass
            QCoreApplication.installTranslator(self.translator)

        LOGGER.debug('%s %s' % (
            translation_path, os.path.exists(translation_path)))

    # 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 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

        """
        # 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)

    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)

    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_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)

    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)

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

    def _create_impact_merge_action(self):
        """Create action for impact layer merge Dialog."""
        icon = resources_path('img', 'icons', 'show-impact-merge.svg')
        self.action_impact_merge_dlg = QAction(
            QIcon(icon),
            self.tr('Impact Layer Merger'),
            self.iface.mainWindow())
        self.action_impact_merge_dlg.setStatusTip(self.tr(
            'Impact Layer Merger'))
        self.action_impact_merge_dlg.setWhatsThis(self.tr(
            'Impact Layer Merger'))
        self.action_impact_merge_dlg.triggered.connect(self.show_impact_merge)
        self.add_action(
            self.action_impact_merge_dlg, 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)
        settings = QSettings()
        flag = bool(settings.value(
            'inasafe/showRubberBands', False, 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)."""
        final_release = release_status() == 'final'
        settings = QSettings()
        self.developer_mode = settings.value(
            'inasafe/developer_mode', False, type=bool)
        if not final_release and self.developer_mode:
            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_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_()

    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_osm_downloader_action()
        self._create_add_osm_layer_action()
        self._create_add_petajakarta_layer_action()
        self._create_shakemap_converter_action()
        self._create_minimum_needs_action()
        self._create_test_layers_action()
        self._add_spacer_to_menu()
        self._create_batch_runner_action()
        self._create_impact_merge_action()
        self._create_save_scenario_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())

    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)

    def clear_modules(self):
        """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.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)

    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 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.user_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.show_next_analysis_extent)
        # 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_impact_merge(self):
        """Show the impact layer merge dialog."""
        # import here only so that it is AFTER i18n set up
        from safe.gui.tools.impact_merge_dialog import ImpactMergeDialog

        dialog = ImpactMergeDialog(self.iface.mainWindow())
        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(
            self.iface,
            self.dock_widget,
            self.iface.mainWindow())
        dialog.exec_()  # modal

    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())
        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)
        dialog.show()  # non 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)
        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'))
        registry = QgsMapLayerRegistry.instance()

        # For older versions we just add directly to the top of legend
        if QGis.QGIS_VERSION_INT < 20400:
            # True flag adds layer directly to legend
            registry.addMapLayer(layer, True)
            return
        # Otherwise try to add it as the last layer in the list
        # False flag prevents layer being added to legend
        registry.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)
        QgsMapLayerRegistry.instance().addMapLayer(layer)

    def add_petajakarta_layer(self):
        """Add petajakarta layer to the map.

        This uses the PetaJakarta API to fetch the latest floods in JK. See
        https://petajakarta.org/banjir/en/data/api/#aggregates
        """
        from safe.gui.tools.peta_jakarta_dialog import PetaJakartaDialog
        dialog = PetaJakartaDialog(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 _disable_keyword_tools(self):
        """Internal helper to disable the keyword and wizard actions."""
        self.action_keywords_wizard.setEnabled(False)

    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:
            self._disable_keyword_tools()
            return
        if not hasattr(layer, 'providerType'):
            self._disable_keyword_tools()
            return
        if layer.providerType() == 'wms':
            self._disable_keyword_tools()
            return
        if is_raster_layer(layer) and layer.bandCount() > 1:
            self._disable_keyword_tools()
            return

        self.action_keywords_wizard.setEnabled(True)

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()