Ejemplo n.º 1
0
    def selectOutput(self):
        if isinstance(self.output, OutputDirectory):
            self.selectDirectory()
        else:
            popupMenu = QMenu()

            actionSaveToTempFile = QAction(
                self.tr('Save to a temporary file'), self.btnSelect)
            actionSaveToTempFile.triggered.connect(self.saveToTemporaryFile)
            popupMenu.addAction(actionSaveToTempFile)

            actionSaveToFile = QAction(
                self.tr('Save to file...'), self.btnSelect)
            actionSaveToFile.triggered.connect(self.selectFile)
            popupMenu.addAction(actionSaveToFile)

            if isinstance(self.output, OutputVector) \
                    and self.alg.provider.supportsNonFileBasedOutput():
                actionSaveToMemory = QAction(
                    self.tr('Save to memory layer'), self.btnSelect)
                actionSaveToMemory.triggered.connect(self.saveToMemory)
                popupMenu.addAction(actionSaveToMemory)
                actionSaveToPostGIS = QAction(
                    self.tr('Save to PostGIS table...'), self.btnSelect)
                actionSaveToPostGIS.triggered.connect(self.saveToPostGIS)
                settings = QSettings()
                settings.beginGroup('/PostgreSQL/connections/')
                names = settings.childGroups()
                settings.endGroup()
                actionSaveToPostGIS.setEnabled(bool(names))
                popupMenu.addAction(actionSaveToPostGIS)

            popupMenu.exec_(QCursor.pos())
Ejemplo n.º 2
0
    def manageActions(self, modelindex, menu):
        """
        Returns the list of actions to be loaded into the context menu
        of this node when a user right clicks in the treeview.
        Default actions are for expanding/collapsing child nodes.
        To be inherited by subclasses for additional custom actions.
        """
        nullAction = QAction(NO_ACTION_ICON,
                             QApplication.translate("BaseSTRNode", "No User Action"),
                             self.parentWidget())
        nullAction.setEnabled(False)

        if not self._view is None:
            if self._view.isExpanded(modelindex):
                self._expand_action.setEnabled(False)
                self._collapse_action.setEnabled(True)

            else:
                self._expand_action.setEnabled(True)
                self._collapse_action.setEnabled(False)

        #Disconnect then reconnect signals
        if self.signalReceivers(self._expand_action) > 0:
            self._expand_action.triggered.disconnect()

        if self.signalReceivers(self._collapse_action) > 0:
            self._collapse_action.triggered.disconnect()

        #Connect expand/collapse signals to the respective actions
        self._expand_action.triggered.connect(lambda:self._on_expand(modelindex))
        self._collapse_action.triggered.connect(lambda: self._on_collapse(modelindex))

        menu.addAction(self._expand_action)
        menu.addAction(self._collapse_action)
Ejemplo n.º 3
0
 def __init__(self):
     QObject.__init__(self)
     self._createdActions = []
     self._createdSeparators = []
     self._createdMenus = []
     self._currentDocument = core.workspace().currentDocument()  # probably None
     
     for menu in _MENUS:
         if menu[2]:
             menuObj = core.actionManager().addMenu(menu[0], menu[1], QIcon(':/enkiicons/' + menu[2]))
         else:
             menuObj = core.actionManager().addMenu(menu[0], menu[1])
         menuObj.setEnabled(False)
         self._createdMenus.append(menuObj)
     
     for item in _ACTIONS:
         if isinstance(item, tuple):  # action
             command, path, text, shortcut, icon = item
             actObject = QAction(text, self)
             if shortcut:
                 actObject.setShortcut(shortcut)
             if icon:
                 actObject.setIcon(QIcon(':/enkiicons/' + icon))
             actObject.setData(command)
             actObject.setEnabled(False)
             actObject.triggered.connect(self.onAction)
             core.actionManager().addAction(path, actObject)
             self._createdActions.append(actObject)
         else:  # separator
             menuPath = item
             menu = core.actionManager().menu(menuPath)
             self._createdSeparators.append(menu.addSeparator())
     
     core.workspace().currentDocumentChanged.connect(self.onCurrentDocumentChanged)
Ejemplo n.º 4
0
 def __init__(self):
     QObject.__init__(self)
     self._createdActions = []
     self._createdMenus = []
     self._currentDocument = core.workspace().currentDocument()  # probably None
     model = core.actionManager()
     
     for menu in _MENUS:
         if menu[2]:
             menuObj = model.addMenu(menu[0], menu[1], QIcon(':/enkiicons/' + menu[2]))
         else:
             menuObj = model.addMenu(menu[0], menu[1])
         menuObj.setEnabled(False)
         self._createdMenus.append(menuObj)
     
     for command, path, text, shortcut, icon in _ACTIONS:
         actObject = QAction(text, self)
         if shortcut:
             actObject.setShortcut(shortcut)
         if icon:
             actObject.setIcon(QIcon(':/enkiicons/' + icon))
         actObject.setData(command)
         actObject.setEnabled(False)
         actObject.triggered.connect(self.onAction)
         model.addAction(path, actObject)
         self._createdActions.append(actObject)
     
     core.workspace().currentDocumentChanged.connect(self.onCurrentDocumentChanged)
Ejemplo n.º 5
0
def layercontextmenu( layer, pos, parent=None, volumeEditor = None ):
    '''Show a context menu to manipulate properties of layer.

    layer -- a volumina layer instance
    pos -- QPoint 

    '''
    def onExport():
        
        if _has_lazyflow:
            inputArray = layer.datasources[0].request((slice(None),)).wait()
            expDlg = ExportDialog(parent = menu)
            g = Graph()
            piper = OpArrayPiper(g)
            piper.inputs["Input"].setValue(inputArray)
            expDlg.setInput(piper.outputs["Output"],g)
        expDlg.show()
        
    menu = QMenu("Menu", parent)
    title = QAction("%s" % layer.name, menu)
    title.setEnabled(False)
    
    export = QAction("Export...",menu)
    export.setStatusTip("Export Layer...")
    export.triggered.connect(onExport)
    
    menu.addAction(title)
    menu.addAction(export)
    menu.addSeparator()
    _add_actions( layer, menu )
    menu.exec_(pos)    
Ejemplo n.º 6
0
def layercontextmenu( layer, pos, parent=None ):
    '''Show a context menu to manipulate properties of layer.

    layer -- a volumina layer instance
    pos -- QPoint 

    '''
    menu = QMenu("Menu", parent)

    # Title
    title = QAction("%s" % layer.name, menu)
    title.setEnabled(False)
    menu.addAction(title)

    # Export
    global _has_lazyflow
    if _has_lazyflow:    
        export = QAction("Export...",menu)
        export.setStatusTip("Export Layer...")
        export.triggered.connect( partial( get_settings_and_export_layer, layer, menu ) )

    menu.addAction(export)
    menu.addSeparator()
    _add_actions( layer, menu )

    # Layer-custom context menu items
    menu.addSeparator()
    for name, callback in layer.contexts:
        action = QAction(name, menu)
        action.triggered.connect(callback)
        menu.addAction(action)

    menu.exec_(pos)
Ejemplo n.º 7
0
 def manageActions(self,modelindex,menu):
     '''
     Returns a menu for managing social tenure relationship information.
     '''
     editReceivers = self.signalReceivers(self.editAction)
     if editReceivers > 0:
         self.editAction.triggered.disconnect()
         
     deleteReceivers = self.signalReceivers(self.deleteAction)
     if deleteReceivers > 0:
         self.deleteAction.triggered.disconnect()
         
     #Add new entities menu
     entityAddMenu = QMenu(QApplication.translate("STRNode","Add"),self.parentWidget())
     entityAddMenu.setIcon(QIcon(":/plugins/stdm/images/icons/add.png"))
     
     #Define actions for adding related STR entities
     confAction = QAction(QIcon(":/plugins/stdm/images/icons/conflict.png"),
                              QApplication.translate("STRNode","Conflict Information"),self._view)
     confAction.triggered.connect(lambda: self.onCreateConflict(modelindex))
     #Check if conflict information already exists. If so, then no need of defining twice
     if self.strModel.hasConflict():
         confAction.setEnabled(False)
     entityAddMenu.addAction(confAction)
     
     taxAction = QAction(QIcon(":/plugins/stdm/images/icons/receipt.png"),
                              QApplication.translate("STRNode","Tax Information"),self._view)
     taxAction.triggered.connect(lambda: self.onCreateTaxation(modelindex))
     if self.strModel.hasTaxation():
         taxAction.setEnabled(False)
     entityAddMenu.addAction(taxAction)
     
     #Add source documents menu
     addSrcDocMenu = QMenu(QApplication.translate("STRNode","Source Documents"),self.parentWidget())
     addSrcDocMenu.setIcon(QIcon(":/plugins/stdm/images/icons/attachment.png"))
     titleDeedAction = QAction(QApplication.translate("STRNode","Title Deed"),self._view)
     titleDeedAction.triggered.connect(lambda: self.onAddSourceDocument(TITLE_DEED))
     addSrcDocMenu.addAction(titleDeedAction)
     notaryRefAction = QAction(QApplication.translate("STRNode","Notary Reference"),self._view)
     notaryRefAction.triggered.connect(lambda: self.onAddSourceDocument(NOTARY_REF))
     addSrcDocMenu.addAction(notaryRefAction)
     statRefPaperAction = QAction(QApplication.translate("STRNode","Statutory Reference Paper"),self._view)
     statRefPaperAction.triggered.connect(lambda: self.onAddSourceDocument(STATUTORY_REF_PAPER))
     addSrcDocMenu.addAction(statRefPaperAction)
     surveyorRefAction = QAction(QApplication.translate("STRNode","Surveyor Reference"),self._view)
     surveyorRefAction.triggered.connect(lambda: self.onAddSourceDocument(SURVEYOR_REF))
     addSrcDocMenu.addAction(surveyorRefAction)
     
     entityAddMenu.addMenu(addSrcDocMenu)
     
     menu.addMenu(entityAddMenu)
     menu.addAction(self.editAction)
     menu.addAction(self.deleteAction)
     
     #Disable if the user does not have permission.
     if not self.parentWidget()._canEdit:
         menu.setEnabled(False)
         
     self.editAction.triggered.connect(lambda: self.onEdit(modelindex))
     self.deleteAction.triggered.connect(lambda: self.onDelete(modelindex))
Ejemplo n.º 8
0
class TestPlugin3:
    def __init__(self, iface):
        self.iface = iface
        self.plugin_dir = os.path.dirname(__file__)
        self.name = u'Test Plugin 3'
        self.action = None
        self.icon_path = os.path.join(
            self.plugin_dir, 'images', 'test_plugin_3.png')

    # noinspection PyPep8Naming
    def initGui(self):
        icon = QIcon(self.icon_path)
        self.action = QAction(icon, u'Run', self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.action.setEnabled(True)

        self.iface.addPluginToMenu(self.name, self.action)

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

    def run(self):
        QMessageBox.information(None, 'Testing',
                                "Test information dialog from plugin: \n\n{0}"
                                .format(self.name))
Ejemplo n.º 9
0
    def build_columns_menu(self):
        columns_menu = QMenu(self)

        available_columns = self.core.get_available_columns()
        accounts = self.core.get_all_accounts()

        if len(accounts) == 0:
            empty_menu = QAction(i18n.get("no_registered_accounts"), self)
            empty_menu.setEnabled(False)
            columns_menu.addAction(empty_menu)
        else:
            for account in accounts:
                name = "%s (%s)" % (account.username, i18n.get(account.protocol_id))
                account_menu = QAction(name, self)

                if len(available_columns[account.id_]) > 0:
                    available_columns_menu = QMenu(self)
                    for column in available_columns[account.id_]:
                        item = QAction(column.slug, self)
                        if column.__class__.__name__ == "List":
                            # FIXME: Uncomment this after fixing the error with get_list_id in libturpial
                            # column_id = "-".join([account.id_, column.id_])
                            # item.triggered.connect(partial(self.add_column, column_id))
                            continue
                        else:
                            item.triggered.connect(partial(self.add_column, column.id_))
                        available_columns_menu.addAction(item)

                    account_menu.setMenu(available_columns_menu)
                else:
                    account_menu.setEnabled(False)
                columns_menu.addAction(account_menu)

        return columns_menu
Ejemplo n.º 10
0
class ItemAutoConnecter( QObject ):
    def __init__( self, scene ):
        QObject.__init__( self, scene )
        self.scene = scene

        self._action = QAction( "Auto Connect Items", self )
        self.connect( self._action, SIGNAL( 'triggered( bool )' ), self.autoConnect )

    def action( self ):
        return self._action

    def updateAction( self ):
        self._action.setEnabled( self.canConnect() )

    def canConnect( self ):
        # Get all items sort by y position
        items = sorted( self.scene.graph.items(), key = lambda item: item.scenePos().y() )

        # We need at least two items
        if len( items ) < 2:
            #print "Less than two items"
            return False

        # Top is source, bottom is sink
        if len( items[0].requiresPorts ) != 0 or len( items[-1].providesPorts ) != 0:
            #print "Top must be bottom and bottom sink"
            return False

        # Only single port items in between
        if len( items ) > 2 and set( sum( [ [ len( item.requiresPorts ), len( item.providesPorts ) ] for item in items[1:-1] ], [] ) ) != set([1]):
            #print "There are items with multiple ports"
            return False

        # Ports sequence
        ports = [ items[0].providesPorts[0] ] + sum( [ [ item.requiresPorts[0], item.providesPorts[0] ] for item in items[1:-1] ], [] ) + [ items[-1].requiresPorts[0] ]
        # Cancel if ports are already connected
        if max( [ len( self.scene.graph.outEdges( p ) ) for p in ports[0::2] ] ) != 0 or \
           max( [ len( self.scene.graph.inEdges( p ) ) for p in ports[1::2] ] ) != 0:
            #print "Already connected"
            return False

        datatypes = [ p.datatype for p in ports ]
        if False in [ datatypes[i] == datatypes[i+1] for i in range( 0, len( datatypes ), 2 ) ]:
            return False

        return True

    # TODO allow more cases, respect already connected edges
    def autoConnect( self ):
        # Get all items sort by y position
        items = sorted( self.scene.graph.items(), key = lambda item: item.scenePos().y() )

        # Connect?
        if not self.canConnect():
            return

        ports = [ items[0].providesPorts[0] ] + sum( [ [ item.requiresPorts[0], item.providesPorts[0] ] for item in items[1:-1] ], [] ) + [ items[-1].requiresPorts[0] ]

        for i in range( 0, len( ports ), 2 ):
            self.scene.graph.addEdge( ports[i], ports[i+1] )
Ejemplo n.º 11
0
    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):


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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)

        return action
Ejemplo n.º 12
0
def init():
    action = QAction("Open audio in Audacity", mw)
    action.setShortcut('Ctrl+Shift+A')
    action.setEnabled(True)

    mw.connect(action, SIGNAL('triggered()'), open_in_audacity)
    mw.form.menuTools.addAction(action)
Ejemplo n.º 13
0
 def create_action(self, name, shortcut, status_tip, callback, enabled=True):
     action = QAction(name, self)
     action.setShortcut(shortcut)
     action.setStatusTip(status_tip)
     action.triggered.connect(callback)
     action.setEnabled(enabled)
     return action
Ejemplo n.º 14
0
    def addNewAction(
            self,
            iconPath,
            text,
            callback=None,
            enabled=True,
            checkable=False,
            addToMenu=True,
            addToToolbar=True,
            tip=None,
            whatsThis=None,
            parent=None):
        """Add a toolbar icon to the toolbar"""

        if parent is None:
            parent = self.iface.mainWindow()
        action = QAction(QIcon(iconPath), text, parent)
        if tip is not None:
            action.setStatusTip(tip)
        if whatsThis is not None:
            action.setWhatsThis(whatsThis)

        if callback is not None:
            action.triggered.connect(callback)
        action.setEnabled(enabled)
        action.setCheckable(checkable)

        self.addAction(action, addToMenu, addToToolbar)
        return action
Ejemplo n.º 15
0
    def _initialize_tree_specific_menu_entries(self,
                                               tree_instance,
                                               menu_reference,
                                               is_main_tree):
        """ Creates standard menu entries (that are used for both trees)
            for the given tree_instance
            @param tree_instance: Tree object that
                should be used.
            @param menu_reference: QMenu object where to add the menu entries
            @param is_main_tree: to differ between main and second tree.

        """

        exchange_action = QAction("Exchange", self)
        QObject.connect(
            exchange_action,
            SIGNAL('triggered()'),
            lambda: self._menu_exchange_tree_elements(tree_instance))

        menu_reference.addAction(exchange_action)

        data_up_action = QAction("DataUp", self)
        QObject.connect(
            data_up_action,
            SIGNAL('triggered()'),
            #call data up move
            lambda: QMessageBox.information(self.main_window, "Info",
                        '''The following were susscessully moved up: '''
                        + "".join(tree_operations.data_up_move(tree_instance))))
        menu_reference.addAction(data_up_action)

        data_down_action = QAction("DataDown", self)
        QObject.connect(
            data_down_action,
            SIGNAL('triggered()'),
            #call data down move
            lambda: QMessageBox.information(self.main_window, "Info",
                        '''The following were successfully moved down: '''
                        + "".join(tree_operations.data_down_move(tree_instance)
                        )))

        menu_reference.addAction(data_down_action)

        data_replace_action = QAction("Replace", self)
        QObject.connect(
            data_replace_action,
            SIGNAL('triggered()'),
            lambda: self._menu_change_label_of_selected_elements(tree_instance,
                                                                 is_main_tree))
        menu_reference.addAction(data_replace_action)

        data_search_and_replace_action = QAction("Search and replace", self)
        QObject.connect(
            data_search_and_replace_action,
            SIGNAL('triggered()'),
            lambda: tree_operations.data_search_and_replace(self.main_window,
                                                  tree_instance))
        menu_reference.addAction(data_search_and_replace_action)
        data_search_and_replace_action.setEnabled(False)
Ejemplo n.º 16
0
 def addBranch(self, branch):
     a = QAction(self)
     a.setCheckable(True)
     if branch == vcs.app_repo.current_branch():
         a.setChecked(True)
         a.setEnabled(False)
     self._acts[branch] = a
     self.setBranchStatus(branch)
Ejemplo n.º 17
0
 def createAction(self, model):
     """ @type model: ButtonModelMixin"""
     action = QAction(self.button)
     action.setText(model.getButtonName())
     action.setEnabled(model.buttonIsEnabled())
     action.triggered.connect(model.buttonTriggered)
     model.observable().attach(ButtonModelMixin.BUTTON_STATE_CHANGED_EVENT, self.modelChanged)
     self.models[model] = action
     return action
class FieldPyculatorPlugin:

    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # i18n support
        override_locale = QSettings().value('locale/overrideFlag', False, type=bool)
        if not override_locale:
            locale_full_name = QLocale.system().name()
        else:
            locale_full_name = QSettings().value('locale/userLocale', '', type=unicode)

        self.locale_path = currentPath + '/i18n/field_pyculator_' + locale_full_name[0:2] + '.qm'
        if path.exists(self.locale_path):
            self.translator = QTranslator()
            self.translator.load(self.locale_path)
            QCoreApplication.installTranslator(self.translator)

    def tr(self, text):
        return QCoreApplication.translate('FieldPyculatorPlugin', text)

    def initGui(self):
        # Create action that will start plugin configuration
        self.action = QAction(QIcon(':/plugins/fieldpyculatorplugin/icon.png'),
                              self.tr('FieldPyculator'), self.iface.mainWindow())
        # connect the action to the run method
        QObject.connect(self.action, SIGNAL('triggered()'), self.run)

        # Add toolbar button and menu item
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(self.tr('&FieldPyculator'), self.action)

        # track layer changing
        QObject.connect(self.iface, SIGNAL('currentLayerChanged( QgsMapLayer* )'), self.layer_changed)

        # check already selected layers
        self.layer_changed()

    def unload(self):
        # Remove the plugin menu item and icon
        self.iface.removePluginMenu(self.tr('&FieldPyculator'), self.action)
        self.iface.removeToolBarIcon(self.action)
        # Remove layer changing tracking
        QObject.disconnect(self.iface, SIGNAL('currentLayerChanged( QgsMapLayer* )'), self.layer_changed)

    def layer_changed(self):
        layer = self.iface.activeLayer()
        if (layer is None) or (layer.type() != QgsMapLayer.VectorLayer):
            self.action.setEnabled(False)
        else:
            self.action.setEnabled(True)

    def run(self):
        # create and show the dialog
        self.dlg = FieldPyculatorDialog(self.iface)
        # show the dialog
        self.dlg.show()
Ejemplo n.º 19
0
 def populate_switch_effect_menu(self, target_menu, checked_item):
     effect_menu = QMenu(i18n("Effect"), target_menu)
     for preset in LADSPAEffects().effects():
         action = QAction(preset["preset_name"],effect_menu)
         effect_menu.addAction(action)
         if checked_item == preset["label"]:
             action.setCheckable(True)
             action.setChecked(True)
             action.setEnabled(False)
     target_menu.addMenu(effect_menu)
Ejemplo n.º 20
0
 def __init__(self):
     QMainWindow.__init__(self)
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.loadTranslations()
     self.settings = QSettings("LVK Inc", "DataCenters")   
     self.resourcesGraphEditor = ResourcesGraphEditor()
     self.demandGraphEditor = DemandGraphEditor()
     self.randomDialog = RandomDemandDialog()
     self.Vis = Vis()
     self.graphvis = GraphVis(self)
     self.demands = {}
     self.project = Project()
     # TODO: Captain, we have a problem!
     # For some reason, in Python 2.7 QSettings converts dicts to QVariant
     # So the ini file is undecypherable
     # This works fine in Python 3.2 by the way
     #if self.settings.value("vis"):
         #self.Vis.canvas.settings = self.settings.value("vis")
     #self.graphvis.settings = self.settings.value("graphVis")
     self.settingsDialog = SettingsDialog(self.Vis.canvas.settings, self.graphvis.settings)
     self.settingsDialog.ui.backup.setChecked(self.settings.value("backup").toBool())
     self.settingsDialog.ui.autosave.setChecked(self.settings.value("autosave").toBool())
     self.settingsDialog.ui.interval.setValue(self.settings.value("interval").toInt()[0])
     i = 0
     for s in self.languages:
         self.settingsDialog.ui.languages.addItem(s)
         if s == str(self.settings.value("language").toString()):
             self.settingsDialog.ui.languages.setCurrentIndex(i)
         i += 1
     self.resourcesGraphEditor.setData(self.project.resources)
     for i in range(self.MaxRecentFiles):
         a = QAction(self)
         a.setVisible(False)
         a.setEnabled(False)
         if i <= 9:
             a.setShortcut(QKeySequence(self.tr("Alt+") + str(i + 1)))
         QObject.connect(a, SIGNAL("triggered()"), self.OpenRecentFile);
         self.ui.menuFile.insertAction(self.ui.actionExit, a)
         self.recentFileActions.append(a)
     self.UpdateRecentFileActions()
     self.basename = self.windowTitle()
     self.demandGraphEditor.demand_changed.connect(self.demandChanged)
     self.backupTimer = QTimer()
     self.backupTimer.setInterval(60000)
     self.backupTimer.setSingleShot(False)
     QObject.connect(self.backupTimer, SIGNAL("timeout()"), self.Backup)
     self.autosaveTimer = QTimer()
     self.autosaveTimer.setInterval(60000)
     self.autosaveTimer.setSingleShot(False)
     QObject.connect(self.autosaveTimer, SIGNAL("timeout()"), self.Autosave)
     self.Translate(str(self.settings.value("language", "English").toString()))
     self.projFilter = self.tr("Data centers projects (*.dcxml)")
     self.setWindowTitle(self.tr("Untitled") + " - " + self.basename)
     self.loadPlugins()
Ejemplo n.º 21
0
    def add_action( self, icon_path,  text, callback, enabled_flag=True,  add_to_menu=True, add_to_toolbar=True, status_tip=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

        :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 add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)

        return action
Ejemplo n.º 22
0
def layercontextmenu( layer, pos, parent=None, volumeEditor = None ):
    '''Show a context menu to manipulate properties of layer.

    layer -- a volumina layer instance
    pos -- QPoint 

    '''
    def onExport():
        sourceTags = [True for l in layer.datasources]
        for i, source in enumerate(layer.datasources):
            if not hasattr(source, "dataSlot"):
                 sourceTags[i] = False
        if not any(sourceTags):
            raise RuntimeError("can not export from a non-lazyflow data source (layer=%r, datasource=%r)" % (type(layer), type(layer.datasources[0])) )


        expDlg = ExportDialog(parent = menu, layername = layer.name)
        if not _has_lazyflow:
            raise RuntimeError("lazyflow not installed") 
        import lazyflow
        dataSlots = [slot.dataSlot for (slot, isSlot) in
                     zip(layer.datasources, sourceTags) if isSlot is True]
        op = lazyflow.operators.OpMultiArrayStacker(dataSlots[0].getRealOperator())
        for slot in dataSlots:
            assert isinstance(slot, lazyflow.graph.Slot), "slot is of type %r" % (type(slot))
            assert isinstance(slot.getRealOperator(), lazyflow.graph.Operator), "slot's operator is of type %r" % (type(slot.getRealOperator()))
        op.AxisFlag.setValue("c")
        op.Images.resize(len(dataSlots))
        for i,islot in enumerate(op.Images):
            islot.connect(dataSlots[i])
        expDlg.setInput(op.Output)

        expDlg.show()
        
    menu = QMenu("Menu", parent)
    title = QAction("%s" % layer.name, menu)
    title.setEnabled(False)
    
    export = QAction("Export...",menu)
    export.setStatusTip("Export Layer...")
    export.triggered.connect(onExport)
    
    menu.addAction(title)
    menu.addAction(export)
    menu.addSeparator()
    _add_actions( layer, menu )

    menu.addSeparator()
    for name, callback in layer.contexts:
        action = QAction(name, menu)
        action.triggered.connect(callback)
        menu.addAction(action)

    menu.exec_(pos)    
Ejemplo n.º 23
0
class Tool(object):
    def __init__(self, name, help_link="", icon=None, enabled=True, checkable=False, popup_menu=False):
        super(Tool, self).__init__()
        self.__icon = icon
        self.__name = name
        self.__parent = None
        self.__enabled = enabled
        self.__checkable = checkable
        self.__help_link = help_link
        self.__is_popup_menu = popup_menu

        self.__action = QAction(self.getIcon(), self.getName(), None)
        self.__action.setIconText(self.getName())
        self.__action.setEnabled(self.isEnabled())
        self.__action.setCheckable(checkable)
        self.__action.triggered.connect(self.trigger)

        HelpCenter.addHelpToAction(self.__action, self.getHelpLink())

    def getIcon(self):
        return self.__icon

    def getName(self):
        return self.__name

    def trigger(self):
        raise NotImplementedError()

    def setParent(self, parent):
        self.__parent = parent
        self.__action.setParent(parent)

    def parent(self):
        return self.__parent

    def isEnabled(self):
        return self.__enabled

    def getHelpLink(self):
        return self.__help_link


    def getAction(self):
        return self.__action

    def setVisible(self, visible):
        self.__action.setVisible(visible)

    def setEnabled(self, enabled):
        self.__action.setEnabled(enabled)

    def isPopupMenu(self):
        return self.__is_popup_menu
Ejemplo n.º 24
0
 def addDockAction(self, iconPath, text, callback=None, enabled=True, checkable=False, tip=None, whatsThis=None):
     action = QAction(QIcon(iconPath), text, self._dock)
     if callback is not None:
         action.triggered.connect(callback)
     action.setEnabled(enabled)
     action.setCheckable(checkable)
     if tip is not None:
         action.setStatusTip(tip)
     if whatsThis is not None:
         action.setWhatsThis(whatsThis)
     self._dock.toolbar.addAction(action)
     # self.actions.append(action)
     return action
Ejemplo n.º 25
0
 def createAction(self, provider):
     icon = QIcon(':/plugins/PosiView/ledgreen.png')
     icon.addFile(':/plugins/PosiView/ledgrey.png', QSize(), QIcon.Disabled, QIcon.Off)
     action = QAction(icon, provider.name, None)
     button = QToolButton()
     button.setDefaultAction(action)
     action.setEnabled(False)
     provider.deviceConnected.connect(action.setEnabled)
     provider.deviceDisconnected.connect(action.setDisabled)
     self.signalMapper.setMapping(action, provider.name)
     action.triggered.connect(self.signalMapper.map)
     self.addAction(action)
     self.actions.append(action)
Ejemplo n.º 26
0
 def context_menu_create_custom(self):
     self.context_menu_create_ports()
     self.context_menu_create_sounddevices()
     action_device = QAction(i18n("Default Sink"), self.popup_menu)
     self.popup_menu.addAction(action_device)
     action_device.setCheckable(True)
     if self.isDefaultSink():
         action_device.setChecked(True)
         action_device.setEnabled(False)
     else:
         action_device.setChecked(False)
         action_device.setEnabled(True)
         action_device.triggered.connect(self.on_set_default_sink_triggered)
Ejemplo n.º 27
0
 def manageActions(self,modelindex,menu):
     '''
     Returns the list of actions to be loaded into the context menu
     of this node when a user right clicks in the treeview.
     Default action is a notification that no action item has been 
     defined for the current node item.
     To be inherited by subclasses for custom actions.
     '''
     nullAction = QAction(NO_ACTION_ICON,
                          QApplication.translate("BaseSTRNode", "No User Action"),self.parentWidget())
     nullAction.setEnabled(False)
     
     menu.addAction(nullAction)
Ejemplo n.º 28
0
def main():
    app = QApplication(sys.argv)

    window = QMainWindow()
    central_widget = QWidget(window)

    start_action = QAction('Start', window)
    stop_action = QAction('Stop', window)
    toolbar = window.addToolBar('Monitor')
    toolbar.addAction(start_action)
    toolbar.addAction(stop_action)

    central_layout = QVBoxLayout(central_widget)

    monitor_name = QLabel(central_widget)
    central_layout.addWidget(monitor_name)

    state_label = QLabel(central_widget)
    central_layout.addWidget(state_label)

    combo_box = QComboBox(central_widget)
    items = [
        ('No keys', AbstractKeyboardMonitor.IGNORE_NO_KEYS),
        ('Modifiers', AbstractKeyboardMonitor.IGNORE_MODIFIER_KEYS),
        ('Modifier combos', AbstractKeyboardMonitor.IGNORE_MODIFIER_COMBOS)]
    for label, userdata in items:
        combo_box.addItem(label, userdata)

    def _update_ignore_keys(index):
        monitor.keys_to_ignore = combo_box.itemData(index).toPyObject()

    combo_box.currentIndexChanged[int].connect(_update_ignore_keys)
    central_layout.addWidget(combo_box)

    central_widget.setLayout(central_layout)
    window.setCentralWidget(central_widget)

    monitor = create_keyboard_monitor(window)
    monitor_name.setText('Using monitor class {0}'.format(
        monitor.__class__.__name__))
    monitor.typingStarted.connect(partial(state_label.setText, 'typing'))
    monitor.typingStopped.connect(partial(state_label.setText, 'not typing'))
    start_action.triggered.connect(monitor.start)
    stop_action.triggered.connect(monitor.stop)
    stop_action.setEnabled(False)
    monitor.started.connect(partial(start_action.setEnabled, False))
    monitor.started.connect(partial(stop_action.setEnabled, True))
    monitor.stopped.connect(partial(start_action.setEnabled, True))
    monitor.stopped.connect(partial(stop_action.setEnabled, False))
    window.show()
    app.exec_()
Ejemplo n.º 29
0
    def __createLayout( self ):
        " Creates the toolbar and layout "

        # Buttons
        printButton = QAction( PixmapCache().getIcon( 'printer.png' ),
                               'Print', self )
        printButton.triggered.connect( self.__onPrint )
        printButton.setEnabled( False )
        printButton.setVisible( False )

        printPreviewButton = QAction(
                PixmapCache().getIcon( 'printpreview.png' ),
                'Print preview', self )
        printPreviewButton.triggered.connect( self.__onPrintPreview )
        printPreviewButton.setEnabled( False )
        printPreviewButton.setVisible( False )

        spacer = QWidget()
        spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding )

        self.lineCounterButton = QAction(
            PixmapCache().getIcon( 'linecounter.png' ),
            'Line counter', self )
        self.lineCounterButton.triggered.connect( self.onLineCounter )

        # The toolbar
        toolbar = QToolBar( self )
        toolbar.setOrientation( Qt.Vertical )
        toolbar.setMovable( False )
        toolbar.setAllowedAreas( Qt.RightToolBarArea )
        toolbar.setIconSize( QSize( 16, 16 ) )
        toolbar.setFixedWidth( 28 )
        toolbar.setContentsMargins( 0, 0, 0, 0 )

        toolbar.addAction( printPreviewButton )
        toolbar.addAction( printButton )
        toolbar.addWidget( spacer )
        toolbar.addAction( self.lineCounterButton )

        self.__importsBar = ImportListWidget( self.__viewer )
        self.__importsBar.hide()

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins( 0, 0, 0, 0 )
        hLayout.setSpacing( 0 )
        hLayout.addWidget( self.__viewer )
        hLayout.addWidget( toolbar )

        self.setLayout( hLayout )
        return
Ejemplo n.º 30
0
    def create_action(self, index_action=None, text='', toolbar=None, menu=None, is_checkable=True, function_name=None, parent=None):
        
        if parent is None:
            parent = self.iface.mainWindow()

        icon = None
        if index_action is not None:
            icon_path = self.icon_folder+index_action+'.png'
            if os.path.exists(icon_path):        
                icon = QIcon(icon_path)
                
        if icon is None:
            action = QAction(text, parent) 
        else:
            action = QAction(icon, text, parent)  
                                    
        if toolbar is not None:
            toolbar.addAction(action)  
             
        if menu is not None:
            self.iface.addPluginToMenu(menu, action)
            
        if index_action is not None:         
            self.actions[index_action] = action
        else:
            self.actions[text] = action
                                     
        if function_name is not None:
            try:
                action.setCheckable(is_checkable) 
                # Management toolbar actions
                if int(index_action) in (19, 21, 24, 25, 27, 28, 99):
                    callback_function = getattr(self.mg, function_name)  
                    action.triggered.connect(callback_function)
                # Edit toolbar actions
                elif int(index_action) in (32, 33, 34, 36):    
                    callback_function = getattr(self.ed, function_name)  
                    action.triggered.connect(callback_function)                    
                # Generic function
                else:        
                    water_soft = function_name[:2] 
                    callback_function = getattr(self, water_soft+'_generic')  
                    action.triggered.connect(partial(callback_function, function_name))
            except AttributeError:
                #print index_action+". Callback function not found: "+function_name
                action.setEnabled(False)                
        else:
            action.setEnabled(False)
            
        return action
Ejemplo n.º 31
0
class ClassesViewer( QWidget ):
    """ The classes viewer widget """

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

        self.filterEdit = None
        self.definitionButton = None
        self.findButton = None
        self.copyPathButton = None
        self.clViewer = None
        self.__createLayout()

        # create the context menu
        self.__menu = QMenu( self )
        self.__jumpMenuItem = self.__menu.addAction( \
                                PixmapCache().getIcon( 'definition.png' ),
                                'Jump to definition', self.__goToDefinition )
        self.__menu.addSeparator()
        self.__findMenuItem = self.__menu.addAction( \
                                PixmapCache().getIcon( 'findusage.png' ),
                                'Find occurences', self.__findWhereUsed )
        self.__menu.addSeparator()
        self.__disasmMenuItem = self.__menu.addAction( \
                                PixmapCache().getIcon( 'disasmmenu.png' ),
                                'Disassemble',
                                self.__onDisassemble )
        self.__menu.addSeparator()
        self.__copyMenuItem = self.__menu.addAction( \
                                PixmapCache().getIcon( 'copytoclipboard.png' ),
                                'Copy path to clipboard',
                                self.clViewer.copyToClipboard )
        self.clViewer.setContextMenuPolicy( Qt.CustomContextMenu )
        self.clViewer.customContextMenuRequested.connect(
                                                self.__handleShowContextMenu )

        GlobalData().project.projectChanged.connect( self.__onProjectChanged )
        self.connect( self.clViewer, SIGNAL( "selectionChanged" ),
                      self.__selectionChanged )
        self.clViewer.openingItem.connect( self.itemActivated )
        self.connect( self.clViewer, SIGNAL( "modelFilesChanged" ),
                      self.modelFilesChanged )

        self.filterEdit.lineEdit().setFocus()
        self.__contextItem = None
        return

    def setTooltips( self, switchOn ):
        " Triggers the tooltips mode "
        self.clViewer.model().sourceModel().setTooltips( switchOn )
        return

    def __createLayout( self ):
        " Helper to create the viewer layout "

        self.clViewer = ClassesBrowser()

        # Toolbar part - buttons
        self.definitionButton = QAction(
                PixmapCache().getIcon( 'definition.png' ),
                'Jump to highlighted item definition', self )
        self.definitionButton.triggered.connect( self.__goToDefinition )
        self.findButton = QAction(
                PixmapCache().getIcon( 'findusage.png' ),
                'Find highlighted item occurences', self )
        self.findButton.triggered.connect( self.__findWhereUsed )
        self.copyPathButton = QAction(
                PixmapCache().getIcon( 'copytoclipboard.png' ),
                'Copy path to clipboard', self )
        self.copyPathButton.triggered.connect( self.clViewer.copyToClipboard )

        self.findNotUsedButton = QAction(
                PixmapCache().getIcon( 'notused.png' ),
                'Unused class analysis', self )
        self.findNotUsedButton.triggered.connect( self.__findNotUsed )
        self.findNotUsedButton.setEnabled( False )

        self.toolbar = QToolBar( self )
        self.toolbar.setMovable( False )
        self.toolbar.setAllowedAreas( Qt.TopToolBarArea )
        self.toolbar.setIconSize( QSize( 16, 16 ) )
        self.toolbar.setFixedHeight( 28 )
        self.toolbar.setContentsMargins( 0, 0, 0, 0 )
        self.toolbar.addAction( self.definitionButton )
        self.toolbar.addAction( self.findButton )
        self.toolbar.addAction( self.copyPathButton )

        filterLabel = QLabel( "  Filter " )
        self.toolbar.addWidget( filterLabel )
        self.filterEdit = CDMComboBox( True, self.toolbar )
        self.filterEdit.setSizePolicy( QSizePolicy.Expanding,
                                       QSizePolicy.Expanding )
        self.filterEdit.lineEdit().setToolTip( "Space separated regular expressions" )
        self.toolbar.addWidget( self.filterEdit )
        self.toolbar.addAction( self.findNotUsedButton )
        self.filterEdit.editTextChanged.connect( self.__filterChanged )
        self.filterEdit.itemAdded.connect( self.__filterItemAdded )
        self.filterEdit.enterClicked.connect( self.__enterInFilter )

        layout = QVBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        layout.addWidget( self.toolbar )
        layout.addWidget( self.clViewer )

        self.setLayout( layout )
        return

    def __filterChanged( self, text ):
        " Triggers when the filter text changed "
        self.clViewer.setFilter( text )
        self.clViewer.updateCounter()
        return

    def __selectionChanged( self, index ):
        " Handles the changed selection "
        if index is None:
            self.__contextItem = None
        else:
            self.__contextItem = self.clViewer.model().item( index )
        self.__updateButtons()
        return

    def getItemCount( self ):
        " Provides the number of items in the model - total, not only visible "
        return self.clViewer.model().sourceModel().rowCount()

    def itemActivated( self, path, line ):
        " Handles the item activation "
        self.filterEdit.addItem( self.filterEdit.lineEdit().text() )
        return

    def __filterItemAdded( self ):
        " The filter item has been added "
        project = GlobalData().project
        if project.fileName != "":
            project.setFindClassHistory( self.filterEdit.getItems() )
        return

    def __enterInFilter( self ):
        " ENTER key has been clicked in the filter "

        # check if there any records displayed
        if self.clViewer.model().rowCount() == 0:
            return

        # Move the focus to the list and select the first row
        self.clViewer.clearSelection()
        flags = QItemSelectionModel.SelectCurrent | QItemSelectionModel.Rows
        self.clViewer.setSelection( QRect( 0, 0, self.clViewer.width(), 1 ),
                                    flags )
        self.clViewer.setFocus()
        return

    def __onProjectChanged( self, what ):
        " Triggered when a project is changed "

        if what == CodimensionProject.CompleteProject:
            self.__contextItem = None
            self.__updateButtons()
            self.filterEdit.clear()

            project = GlobalData().project
            if project.isLoaded():
                self.filterEdit.editTextChanged.disconnect(
                                                    self.__filterChanged )
                self.filterEdit.addItems( project.findClassHistory )
                self.filterEdit.editTextChanged.connect( self.__filterChanged )
                self.findNotUsedButton.setEnabled( self.getItemCount() > 0 )
            else:
                self.findNotUsedButton.setEnabled( False )
            self.filterEdit.clearEditText()
        return

    def __handleShowContextMenu( self, coord ):
        """ Show the context menu """

        index = self.clViewer.indexAt( coord )
        if not index.isValid():
            return

        # This will update the __contextItem
        self.__selectionChanged( index )

        if self.__contextItem is None:
            return

        self.__jumpMenuItem.setEnabled( self.definitionButton.isEnabled() )
        self.__findMenuItem.setEnabled( self.findButton.isEnabled() )
        self.__copyMenuItem.setEnabled( self.copyPathButton.isEnabled() )

        canDisassemble = self.__contextItem.canGetDisassembler()
        self.__disasmMenuItem.setEnabled( canDisassemble )

        self.__menu.popup( QCursor.pos() )
        return

    def __goToDefinition( self ):
        """ Jump to definition context menu handler """
        if self.__contextItem is not None:
            self.clViewer.openItem( self.__contextItem )
        return

    def __findWhereUsed( self ):
        """ Find where used context menu handler """
        if self.__contextItem is not None:
            GlobalData().mainWindow.findWhereUsed( \
                    self.__contextItem.getPath(),
                    self.__contextItem.sourceObj )
        return

    def __findNotUsed( self ):
        " Runs the unused class analysis "
        GlobalData().mainWindow.onNotUsedClasses()
        return

    def __updateButtons( self ):
        " Updates the toolbar buttons depending on what is selected "

        self.definitionButton.setEnabled( False )
        self.findButton.setEnabled( False )
        self.copyPathButton.setEnabled( False )
        if self.__contextItem is None:
            return

        if self.__contextItem.itemType == DecoratorItemType:
            self.definitionButton.setEnabled( True )
            self.copyPathButton.setEnabled( True )
            return

        if self.__contextItem.itemType in [ FunctionItemType, ClassItemType,
                                            AttributeItemType, GlobalItemType ]:
            self.definitionButton.setEnabled( True )
            self.findButton.setEnabled( True )
            self.copyPathButton.setEnabled( True )
        return

    def onFileUpdated( self, fileName, uuid ):
        " Triggered when the file is updated "
        self.clViewer.onFileUpdated( fileName )
        self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                           self.getItemCount() > 0 )
        return

    def modelFilesChanged( self ):
        " Triggered when the source model has a file or files added or deleted "
        self.findNotUsedButton.setEnabled( GlobalData().project.isLoaded() and \
                                           self.getItemCount() > 0 )
        return

    def __onDisassemble( self ):
        " Disassembling has been requested "
        if self.__contextItem is not None:
            self.clViewer.getDisassembled( self.__contextItem )
Ejemplo n.º 32
0
class BreakPointViewer(QWidget):
    " Implements the break point viewer for a debugger "

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

        self.__currentItem = None
        self.__createLayout(bpointsModel)

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        self.connect(GlobalData().project, SIGNAL('projectAboutToUnload'),
                     self.__onProjectAboutToUnload)
        self.connect(self.bpointsList, SIGNAL("selectionChanged"),
                     self.__onSelectionChanged)
        self.connect(bpointsModel, SIGNAL('BreakpoinsChanged'),
                     self.__onModelChanged)
        return

    def setFocus(self):
        " Sets the widget focus "
        self.bpointsList.setFocus()
        return

    def __createLayout(self, bpointsModel):
        " Creates the widget layout "

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(0, 0, 0, 0)
        verticalLayout.setSpacing(0)

        self.headerFrame = QFrame()
        self.headerFrame.setFrameStyle(QFrame.StyledPanel)
        self.headerFrame.setAutoFillBackground(True)
        headerPalette = self.headerFrame.palette()
        headerBackground = headerPalette.color(QPalette.Background)
        headerBackground.setRgb(min(headerBackground.red() + 30, 255),
                                min(headerBackground.green() + 30, 255),
                                min(headerBackground.blue() + 30, 255))
        headerPalette.setColor(QPalette.Background, headerBackground)
        self.headerFrame.setPalette(headerPalette)
        self.headerFrame.setFixedHeight(24)

        self.__breakpointLabel = QLabel("Breakpoints")

        fixedSpacer = QSpacerItem(3, 3)

        headerLayout = QHBoxLayout()
        headerLayout.setContentsMargins(0, 0, 0, 0)
        headerLayout.addSpacerItem(fixedSpacer)
        headerLayout.addWidget(self.__breakpointLabel)
        self.headerFrame.setLayout(headerLayout)

        self.bpointsList = BreakPointView(self, bpointsModel)

        self.__editButton = QAction(PixmapCache().getIcon('bpprops.png'),
                                    "Edit breakpoint properties", self)
        self.__editButton.triggered.connect(self.__onEdit)
        self.__editButton.setEnabled(False)

        self.__jumpToCodeButton = QAction(
            PixmapCache().getIcon('gotoline.png'), "Jump to the code", self)
        self.__jumpToCodeButton.triggered.connect(self.__onJumpToCode)
        self.__jumpToCodeButton.setEnabled(False)

        self.__enableButton = QAction(PixmapCache().getIcon('bpenable.png'),
                                      "Enable selected breakpoint", self)
        self.__enableButton.triggered.connect(self.__onEnableDisable)
        self.__enableButton.setEnabled(False)

        self.__disableButton = QAction(PixmapCache().getIcon('bpdisable.png'),
                                       "Disable selected breakpoint", self)
        self.__disableButton.triggered.connect(self.__onEnableDisable)
        self.__disableButton.setEnabled(False)

        self.__enableAllButton = QAction(
            PixmapCache().getIcon('bpenableall.png'),
            "Enable all the breakpoint", self)
        self.__enableAllButton.triggered.connect(self.__onEnableAll)
        self.__enableAllButton.setEnabled(False)

        self.__disableAllButton = QAction(
            PixmapCache().getIcon('bpdisableall.png'),
            "Disable all the breakpoint", self)
        self.__disableAllButton.triggered.connect(self.__onDisableAll)
        self.__disableAllButton.setEnabled(False)

        self.__delButton = QAction(PixmapCache().getIcon('delitem.png'),
                                   "Delete selected breakpoint", self)
        self.__delButton.triggered.connect(self.__onDel)
        self.__delButton.setEnabled(False)

        self.__delAllButton = QAction(PixmapCache().getIcon('bpdelall.png'),
                                      "Delete all the breakpoint", self)
        self.__delAllButton.triggered.connect(self.__onDelAll)
        self.__delAllButton.setEnabled(False)

        # Toolbar
        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Horizontal)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedHeight(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addAction(self.__editButton)
        self.toolbar.addAction(self.__jumpToCodeButton)
        fixedSpacer2 = QWidget()
        fixedSpacer2.setFixedWidth(5)
        self.toolbar.addWidget(fixedSpacer2)
        self.toolbar.addAction(self.__enableButton)
        self.toolbar.addAction(self.__enableAllButton)
        fixedSpacer3 = QWidget()
        fixedSpacer3.setFixedWidth(5)
        self.toolbar.addWidget(fixedSpacer3)
        self.toolbar.addAction(self.__disableButton)
        self.toolbar.addAction(self.__disableAllButton)
        expandingSpacer = QWidget()
        expandingSpacer.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        fixedSpacer4 = QWidget()
        fixedSpacer4.setFixedWidth(5)
        self.toolbar.addWidget(fixedSpacer4)
        self.toolbar.addWidget(expandingSpacer)
        self.toolbar.addAction(self.__delButton)
        fixedSpacer5 = QWidget()
        fixedSpacer5.setFixedWidth(5)
        self.toolbar.addWidget(fixedSpacer5)
        self.toolbar.addAction(self.__delAllButton)

        verticalLayout.addWidget(self.headerFrame)
        verticalLayout.addWidget(self.toolbar)
        verticalLayout.addWidget(self.bpointsList)
        return

    def clear(self):
        " Clears the content "
        self.__onDelAll()
        self.__updateBreakpointsLabel()
        self.__currentItem = None
        return

    def __updateBreakpointsLabel(self):
        " Updates the breakpoints header label "
        enableCount, \
        disableCount = self.bpointsList.model().sourceModel().getCounts()
        total = enableCount + disableCount
        if total > 0:
            self.__breakpointLabel.setText("Breakpoints (total: " +
                                           str(total) + ")")
        else:
            self.__breakpointLabel.setText("Breakpoints")
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what != CodimensionProject.CompleteProject:
            return

        self.clear()
        model = self.bpointsList.model().sourceModel()
        project = GlobalData().project
        if project.isLoaded():
            bpoints = project.breakpoints
        else:
            bpoints = Settings().breakpoints

        for bp in bpoints:
            newBpoint = Breakpoint()
            try:
                if not newBpoint.deserialize(bp):
                    # Non valid
                    continue
            except:
                continue
            # Need to check if it still points to a breakable line
            line = newBpoint.getLineNumber()
            fileName = newBpoint.getAbsoluteFileName()
            breakableLines = getBreakpointLines(fileName, None, True)
            if breakableLines is not None and line in breakableLines:
                model.addBreakpoint(newBpoint)
            else:
                logging.warning("Breakpoint at " + fileName + ":" + str(line) +
                                " does not point to a breakable "
                                "line anymore (the file is invalid or was "
                                "modified outside of the "
                                "IDE etc.). The breakpoint is deleted.")
        return

    def __onProjectAboutToUnload(self):
        " Triggered before the project is unloaded "
        self.__serializeBreakpoints()
        return

    def __serializeBreakpoints(self):
        " Saves the breakpoints into a file "
        model = self.bpointsList.model().sourceModel()

        project = GlobalData().project
        if project.isLoaded():
            project.setBreakpoints(model.serialize())
        else:
            Settings().breakpoints = model.serialize()
        return

    def __onSelectionChanged(self, index):
        " Triggered when the current item is changed "
        if index is None:
            self.__currentItem = None
        else:
            srcModel = self.bpointsList.model().sourceModel()
            sindex = self.bpointsList.toSourceIndex(index)
            self.__currentItem = srcModel.getBreakPointByIndex(sindex)
        self.__updateButtons()
        return

    def __updateButtons(self):
        " Updates the buttons status "

        enableCount, \
        disableCount = self.bpointsList.model().sourceModel().getCounts()

        if self.__currentItem is None:
            self.__editButton.setEnabled(False)
            self.__enableButton.setEnabled(False)
            self.__disableButton.setEnabled(False)
            self.__jumpToCodeButton.setEnabled(False)
            self.__delButton.setEnabled(False)
        else:
            self.__editButton.setEnabled(True)
            self.__enableButton.setEnabled(not self.__currentItem.isEnabled())
            self.__disableButton.setEnabled(self.__currentItem.isEnabled())
            self.__jumpToCodeButton.setEnabled(True)
            self.__delButton.setEnabled(True)

        self.__enableAllButton.setEnabled(disableCount > 0)
        self.__disableAllButton.setEnabled(enableCount > 0)
        self.__delAllButton.setEnabled(enableCount + disableCount > 0)
        return

    def __onEnableDisable(self):
        " Triggered when a breakpoint should be enabled/disabled "
        if self.__currentItem is None:
            return

        if self.__currentItem.isEnabled():
            self.bpointsList.disableBreak()
        else:
            self.bpointsList.enableBreak()
        return

    def __onEdit(self):
        " Triggered when a breakpoint should be edited "
        if self.__currentItem is None:
            return

        dlg = BreakpointEditDialog(self.__currentItem)
        if dlg.exec_() == QDialog.Accepted:
            newBpoint = dlg.getData()
            if newBpoint == self.__currentItem:
                return
            model = self.bpointsList.model().sourceModel()
            index = model.getBreakPointIndex(
                self.__currentItem.getAbsoluteFileName(),
                self.__currentItem.getLineNumber())
            model.setBreakPointByIndex(index, newBpoint)
            self.bpointsList.layoutDisplay()
        return

    def __onJumpToCode(self):
        " Triggered when should jump to source "
        if self.__currentItem is None:
            return
        self.bpointsList.jumpToCode(self.__currentItem.getAbsoluteFileName(),
                                    self.__currentItem.getLineNumber())
        return

    def __onEnableAll(self):
        " Triggered when all the breakpoints should be enabled "
        self.bpointsList.enableAllBreaks()
        return

    def __onDisableAll(self):
        " Triggered when all the breakpoints should be disabled "
        self.bpointsList.disableAllBreaks()
        return

    def __onDel(self):
        " Triggered when a breakpoint should be deleted "
        if self.__currentItem is None:
            return
        self.bpointsList.deleteBreak()
        return

    def __onDelAll(self):
        " Triggered when all the breakpoints should be deleted "
        self.bpointsList.deleteAllBreaks()
        return

    def __onModelChanged(self):
        " Triggered when something has changed in any of the breakpoints "
        self.__updateBreakpointsLabel()
        self.__updateButtons()
        self.bpointsList.layoutDisplay()

        self.__serializeBreakpoints()
        return
Ejemplo n.º 33
0
class GeometryCopier:
    def __init__(self, iface):
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path(
        ) + "/python/plugins/geometry_copier"
        # initialize locale
        locale_path = ""
        if sip.getapi("QVariant") > 1:
            # new API style
            locale = QSettings().value("locale/userLocale")[0:2]
        else:
            # the old API style
            locale = QSettings().value("locale/userLocale").toString()[0:2]

        if QFileInfo(self.plugin_dir).exists():
            locale_path = self.plugin_dir + "/i18n/geometry_copier_" + locale + ".qm"

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

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

    def initGui(self):
        # Create action that will start plugin configuration
        self.copy_action = QAction(
            QIcon(':/plugins/geometrycopier/mActionEditCopyGeom.png'),
            self.tr(u"Copy geometry"), self.iface.mainWindow())

        self.insert_action = QAction(
            QIcon(':/plugins/geometrycopier/mActionEditPasteGeom.png'),
            self.tr(u"Insert geometry"), self.iface.mainWindow())

        # connect the action to the run method
        QObject.connect(self.copy_action, SIGNAL("triggered()"),
                        self.copy_geometry)
        QObject.connect(self.insert_action, SIGNAL("triggered()"),
                        self.insert_geometry)

        # Add hotkeys
        self.iface.registerMainWindowAction(self.copy_action, "F7")
        self.iface.registerMainWindowAction(self.insert_action, "F8")

        # Add toolbar button and menu item
        self.iface.digitizeToolBar().addAction(self.copy_action)
        self.iface.digitizeToolBar().addAction(self.insert_action)
        self.iface.addPluginToVectorMenu(u"&Geometry copier", self.copy_action)
        self.iface.addPluginToVectorMenu(u"&Geometry copier",
                                         self.insert_action)

        # Add global signals
        QObject.connect(self.iface,
                        SIGNAL('currentLayerChanged(QgsMapLayer *)'),
                        self.check_buttons_state)
        QObject.connect(self.iface.mapCanvas(),
                        SIGNAL('selectionChanged(QgsMapLayer *)'),
                        self.check_buttons_state)
        QObject.connect(self.iface.actionToggleEditing(),
                        SIGNAL('triggered()'), self.check_buttons_state)

        #iface.actionToggleEditing().triggered

        # init state
        self.check_buttons_state(None)

    def unload(self):
        self.iface.unregisterMainWindowAction(self.copy_action)
        self.iface.unregisterMainWindowAction(self.insert_action)
        self.iface.removePluginVectorMenu(u"&Geometry copier",
                                          self.copy_action)
        self.iface.removePluginVectorMenu(u"&Geometry copier",
                                          self.insert_action)
        self.iface.digitizeToolBar().removeAction(self.copy_action)
        self.iface.digitizeToolBar().removeAction(self.insert_action)
        QObject.disconnect(self.iface,
                           SIGNAL('currentLayerChanged(QgsMapLayer *)'),
                           self.check_buttons_state)
        QObject.disconnect(self.iface.mapCanvas(),
                           SIGNAL('selectionChanged(QgsMapLayer *)'),
                           self.check_buttons_state)
        QObject.disconnect(self.iface.actionToggleEditing(),
                           SIGNAL('triggered()'), self.check_buttons_state)

    def check_buttons_state(self, layer=None):
        layer = self.iface.activeLayer()
        if not isinstance(layer, QgsVectorLayer):
            self.copy_action.setDisabled(True)
            self.insert_action.setDisabled(True)
            return
        sel_feat_count = layer.selectedFeatureCount()
        if sel_feat_count != 1:
            self.copy_action.setDisabled(True)
            self.insert_action.setDisabled(True)
            return
        self.copy_action.setEnabled(True)  # copy button can be pressed!
        if not layer.isEditable(
        ) or not self._geom_buffer or self._geom_buffer.type(
        ) != layer.geometryType():
            self.insert_action.setDisabled(True)
            return
        self.insert_action.setEnabled(
            True)  # insert button can be pressed! (type geom??)

    def copy_geometry(self):
        layer = self.iface.activeLayer()
        if not isinstance(layer, QgsVectorLayer):
            QMessageBox.information(
                None, self.tr('Geometry was not copied'),
                self.tr('Select any vector layer and feature!'))
            return
        sel_feat_count = layer.selectedFeatureCount()
        if sel_feat_count != 1:
            QMessageBox.information(None, self.tr('Geometry was not copied'),
                                    self.tr('Select one feature!'))
            return
        feature = layer.selectedFeatures()[0]
        self._geom_buffer = QgsGeometry(feature.geometry())
        self.check_buttons_state()

    def insert_geometry(self):
        layer = self.iface.activeLayer()
        if not isinstance(layer, QgsVectorLayer):
            QMessageBox.information(
                None, self.tr('Geometry can\'t be inserted'),
                self.tr(
                    'Select any vector layer and feature for inserting geom!'))
            return
        if not self._geom_buffer:
            QMessageBox.information(None,
                                    self.tr('Geometry can\'t be inserted'),
                                    self.tr('Buffer is empty!'))
            return
        if not layer.isEditable():
            QMessageBox.critical(None, self.tr('Geometry can\'t be inserted'),
                                 self.tr('Layer is not editable!'))
            return
        if self._geom_buffer.type() != layer.geometryType(
        ):  # and layer.geometryType() != 2:
            QMessageBox.critical(
                None, self.tr('Geometry can\'t be inserted'),
                self.tr('Target layer has other geometry type!'))
            return
        sel_feat_count = layer.selectedFeatureCount()
        if sel_feat_count != 1:
            QMessageBox.critical(
                None, self.tr('Geometry can\'t be inserted'),
                self.tr('Select one feature for inserting geom!'))
            return
        feature = layer.selectedFeatures()[0]
        layer.changeGeometry(feature.id(), QgsGeometry(self._geom_buffer))
        self.iface.mapCanvas().refresh()

    def tr(self, text):
        return QCoreApplication.translate('GeometryCopier', text)
Ejemplo n.º 34
0
    def add_action(
        self,
        name,
        icon_path,
        text,
        callback,
        toggle_flag=False,
        enabled_flag=True,
        checkable_flag=False,
        visible_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 name: Objectname of the action. Serves also as key for the stored actions.
        :type name: str

        :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 toggle_flag: A flag indicating if the action should connect
            the toggled or triggered signal by default.
            Defaults to triggered (False)
        :type toggle_flag: bool

        :param checkable_flag: A flag indicating if the action should be checkable
            by default. Defaults to False.
        :type checkable: bool

        :param visible_flag: A flag indicating if the action should be displayed
            by default. Defaults to True.
        :type visible: 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.setObjectName(name)
        if toggle_flag:
            action.toggled.connect(callback)
        else:
            action.triggered.connect(callback)
        action.setEnabled(enabled_flag)
        action.setCheckable(checkable_flag)
        action.setVisible(visible_flag)

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions[name] = action

        return action
Ejemplo n.º 35
0
class VariableEditor(QWidget):
    """An editor widget for a variable.

    Can edit the variable name, and its attributes dictionary.

    """
    variable_changed = Signal()

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setup_gui()

    def setup_gui(self):
        layout = QVBoxLayout()
        self.setLayout(layout)

        self.main_form = QFormLayout()
        self.main_form.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        layout.addLayout(self.main_form)

        self._setup_gui_name()
        self._setup_gui_labels()

    def _setup_gui_name(self):
        self.name_edit = QLineEdit()
        self.main_form.addRow("Name:", self.name_edit)
        self.name_edit.editingFinished.connect(self.on_name_changed)

    def _setup_gui_labels(self):
        vlayout = QVBoxLayout()
        vlayout.setContentsMargins(0, 0, 0, 0)
        vlayout.setSpacing(1)

        self.labels_edit = QTreeView()
        self.labels_edit.setEditTriggers(QTreeView.CurrentChanged)
        self.labels_edit.setRootIsDecorated(False)

        self.labels_model = DictItemsModel()
        self.labels_edit.setModel(self.labels_model)

        self.labels_edit.selectionModel().selectionChanged.connect(
            self.on_label_selection_changed)

        # Necessary signals to know when the labels change
        self.labels_model.dataChanged.connect(self.on_labels_changed)
        self.labels_model.rowsInserted.connect(self.on_labels_changed)
        self.labels_model.rowsRemoved.connect(self.on_labels_changed)

        vlayout.addWidget(self.labels_edit)
        hlayout = QHBoxLayout()
        hlayout.setContentsMargins(0, 0, 0, 0)
        hlayout.setSpacing(1)
        self.add_label_action = QAction("+",
                                        self,
                                        toolTip="Add a new label.",
                                        triggered=self.on_add_label,
                                        enabled=False,
                                        shortcut=QKeySequence(
                                            QKeySequence.New))

        self.remove_label_action = QAction(unicodedata.lookup("MINUS SIGN"),
                                           self,
                                           toolTip="Remove selected label.",
                                           triggered=self.on_remove_label,
                                           enabled=False,
                                           shortcut=QKeySequence(
                                               QKeySequence.Delete))

        button_size = gui.toolButtonSizeHint()
        button_size = QSize(button_size, button_size)

        button = QToolButton(self)
        button.setFixedSize(button_size)
        button.setDefaultAction(self.add_label_action)
        hlayout.addWidget(button)

        button = QToolButton(self)
        button.setFixedSize(button_size)
        button.setDefaultAction(self.remove_label_action)
        hlayout.addWidget(button)
        hlayout.addStretch(10)
        vlayout.addLayout(hlayout)

        self.main_form.addRow("Labels:", vlayout)

    def set_data(self, var):
        """Set the variable to edit.
        """
        self.clear()
        self.var = var

        if var is not None:
            self.name_edit.setText(var.name)
            self.labels_model.set_dict(dict(var.attributes))
            self.add_label_action.setEnabled(True)
        else:
            self.add_label_action.setEnabled(False)
            self.remove_label_action.setEnabled(False)

    def get_data(self):
        """Retrieve the modified variable.
        """
        name = str(self.name_edit.text())
        labels = self.labels_model.get_dict()

        # Is the variable actually changed.
        if not self.is_same():
            var = type(self.var)(name)
            var.attributes.update(labels)
            self.var = var
        else:
            var = self.var

        return var

    def is_same(self):
        """Is the current model state the same as the input.
        """
        name = str(self.name_edit.text())
        labels = self.labels_model.get_dict()

        return self.var and name == self.var.name and labels == self.var.attributes

    def clear(self):
        """Clear the editor state.
        """
        self.var = None
        self.name_edit.setText("")
        self.labels_model.set_dict({})

    def maybe_commit(self):
        if not self.is_same():
            self.commit()

    def commit(self):
        """Emit a ``variable_changed()`` signal.
        """
        self.variable_changed.emit()

    @Slot()
    def on_name_changed(self):
        self.maybe_commit()

    @Slot()
    def on_labels_changed(self, *args):
        self.maybe_commit()

    @Slot()
    def on_add_label(self):
        self.labels_model.appendRow([QStandardItem(""), QStandardItem("")])
        row = self.labels_model.rowCount() - 1
        index = self.labels_model.index(row, 0)
        self.labels_edit.edit(index)

    @Slot()
    def on_remove_label(self):
        rows = self.labels_edit.selectionModel().selectedRows()
        if rows:
            row = rows[0]
            self.labels_model.removeRow(row.row())

    @Slot()
    def on_label_selection_changed(self):
        selected = self.labels_edit.selectionModel().selectedRows()
        self.remove_label_action.setEnabled(bool(len(selected)))
Ejemplo n.º 36
0
    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

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

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

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

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

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

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

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

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

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

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

        # Create the dialog (after translation) and keep reference
        self.dlg = VectorTileBulderDialog()

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)

        return action
Ejemplo n.º 37
0
class FindInFilesViewer(QWidget):
    " Find in files viewer tab widget "

    lastEntered = None

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

        global searchTooltip
        searchTooltip = Tooltip()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__bufferChangeconnected = False

        # Prepare members for reuse
        self.__noneLabel = QLabel("\nNo results available")

        self.__noneLabel.setFrameShape(QFrame.StyledPanel)
        self.__noneLabel.setAlignment(Qt.AlignHCenter)
        self.__headerFont = self.__noneLabel.font()
        self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4)
        self.__noneLabel.setFont(self.__headerFont)
        self.__noneLabel.setAutoFillBackground(True)
        noneLabelPalette = self.__noneLabel.palette()
        noneLabelPalette.setColor(QPalette.Background,
                                  GlobalData().skin.nolexerPaper)
        self.__noneLabel.setPalette(noneLabelPalette)

        # Keep pylint happy
        self.printButton = None
        self.clearButton = None
        self.printPreviewButton = None

        self.__createLayout(parent)

        self.__updateButtonsStatus()

        GlobalData().project.projectChanged.connect(self.__onProjectChanged)
        return

    def __createLayout(self, parent):
        " Creates the toolbar and layout "

        # Buttons
        self.printButton = QAction(PixmapCache().getIcon('printer.png'),
                                   'Print', self)
        #printButton.setShortcut( 'Ctrl+' )
        self.printButton.triggered.connect(self.__onPrint)
        self.printButton.setVisible(False)

        self.printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        #printPreviewButton.setShortcut( 'Ctrl+' )
        self.printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear',
                                   self)
        self.clearButton.triggered.connect(self.__clear)

        # The toolbar
        self.toolbar = QToolBar(self)
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.RightToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)

        self.toolbar.addAction(self.printPreviewButton)
        self.toolbar.addAction(self.printButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        self.__resultsTree = FindResultsTreeWidget()
        self.__resultsTree.setAlternatingRowColors(True)
        self.__resultsTree.setRootIsDecorated(True)
        self.__resultsTree.setItemsExpandable(True)
        self.__resultsTree.setUniformRowHeights(True)
        self.__resultsTree.setItemDelegate(NoOutlineHeightDelegate(4))
        headerLabels = ["File name / line", "Text"]
        self.__resultsTree.setHeaderLabels(headerLabels)
        self.__resultsTree.itemActivated.connect(self.__resultActivated)
        self.__resultsTree.itemClicked.connect(self.__resultClicked)
        self.__resultsTree.setMouseTracking(True)
        self.__resultsTree.itemEntered.connect(self.__itemEntered)
        self.__resultsTree.hide()

        self.__hLayout = QHBoxLayout()
        self.__hLayout.setContentsMargins(0, 0, 0, 0)
        self.__hLayout.setSpacing(0)
        self.__hLayout.addWidget(self.toolbar)
        self.__hLayout.addWidget(self.__noneLabel)
        self.__hLayout.addWidget(self.__resultsTree)

        self.setLayout(self.__hLayout)
        return

    def getResultsTree(self):
        " Provides a reference to the results tree "
        return self.__resultsTree

    def __updateButtonsStatus(self):
        " Updates the buttons status "
        self.printButton.setEnabled(self.__reportShown)
        self.printPreviewButton.setEnabled(self.__reportShown)
        self.clearButton.setEnabled(self.__reportShown)
        return

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def setFocus(self):
        " Overridden setFocus "
        self.__hLayout.setFocus()
        return

    def __onProjectChanged(self, what):
        " Triggered when a project is changed "
        if what == CodimensionProject.CompleteProject:
            self.__clear()
        return

    def __clear(self):
        " Clears the content of the vertical layout "
        if not self.__reportShown:
            return

        # Disconnect the buffer change signal if it is connected
        if self.__bufferChangeconnected:
            self.__bufferChangeconnected = False
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.disconnect(
                self.__resultsTree.onBufferModified)

        self.__resultsTree.resetCache()
        self.__resultsTree.clear()
        self.__resultsTree.hide()
        self.__noneLabel.show()

        self.__reportRegexp = None
        self.__reportResults = []
        self.__reportShown = False
        self.__updateButtonsStatus()
        return

    def showReport(self, regexp, results):
        " Shows the find in files results "
        self.__clear()
        self.__noneLabel.hide()

        self.__reportRegexp = regexp
        self.__reportResults = results

        # Add the complete information
        totalMatched = 0
        for item in results:
            matched = len(item.matches)
            totalMatched += matched
            if matched == 1:
                matchText = " (1 match)"
            else:
                matchText = " (" + str(matched) + " matches)"
            columns = [item.fileName, matchText]
            fileItem = MatchTableFileItem(columns, item.bufferUUID)
            fileItem.setIcon(0, getFileIcon(detectFileType(item.fileName)))
            if item.tooltip != "":
                fileItem.setToolTip(0, item.tooltip)
            self.__resultsTree.addTopLevelItem(fileItem)

            # Matches
            for match in item.matches:
                columns = [str(match.line), match.text]
                matchItem = MatchTableItem(columns, match.tooltip)
                fileItem.addChild(matchItem)
            fileItem.setExpanded(True)

        # Update the header with the total number of matches
        headerLabels = [
            "File name / line (total files: " + str(len(results)) + ")",
            "Text (total matches: " + str(totalMatched) + ")"
        ]
        self.__resultsTree.setHeaderLabels(headerLabels)

        # Resizing the table
        self.__resultsTree.header().resizeSections(
            QHeaderView.ResizeToContents)

        # Show the complete information
        self.__resultsTree.show()
        self.__resultsTree.buildCache()

        self.__reportShown = True
        self.__updateButtonsStatus()

        # Connect the buffer change signal if not connected yet
        if not self.__bufferChangeconnected:
            self.__bufferChangeconnected = True
            mainWindow = GlobalData().mainWindow
            editorsManager = mainWindow.editorsManagerWidget.editorsManager
            editorsManager.bufferModified.connect(
                self.__resultsTree.onBufferModified)
        return

    def __resultClicked(self, item, column):
        " Handles the single click "
        hideSearchTooltip()
        return

    def __resultActivated(self, item, column):
        " Handles the double click (or Enter) on a match "
        if type(item) == MatchTableItem:
            fileName = str(item.parent().data(0, Qt.DisplayRole).toString())
            lineNumber = int(item.data(0, Qt.DisplayRole).toString())
            GlobalData().mainWindow.openFile(fileName, lineNumber)
            hideSearchTooltip()
            return

    def __itemEntered(self, item, column):
        " Triggered when the mouse cursor entered a row "

        if type(item) != MatchTableItem:
            self.lastEntered = item
            hideSearchTooltip()
            return

        if column != 1:
            # Show the tooltip only for the column with results
            self.lastEntered = None
            hideSearchTooltip()
            return

        # Memorize the row height for proper tooltip displaying later
        global cellHeight
        cellHeight = self.__resultsTree.visualItemRect(item).height()

        if self.lastEntered != item or not inside:
            item.itemEntered()
            self.lastEntered = item
        return
Ejemplo n.º 38
0
class LogViewer(QWidget):
    """ The log (+stdout, +stderr) viewer widget """
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.__isEmpty = True
        self.__copyAvailable = False
        self.clearButton = None
        self.messages = None
        self.copyButton = None
        self.selectAllButton = None
        self.__createLayout(parent)

        # create the context menu
        self.__menu = QMenu(self)
        self.__selectAllMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('selectall.png'), 'Select All',
            self.messages.selectAll)
        self.__copyMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('copytoclipboard.png'), 'Copy',
            self.messages.copy)
        self.__menu.addSeparator()
        self.__clearMenuItem = self.__menu.addAction(
            PixmapCache().getIcon('trash.png'), 'Clear', self.__clear)

        self.messages.setContextMenuPolicy(Qt.CustomContextMenu)
        self.messages.customContextMenuRequested.connect(
            self.__handleShowContextMenu)
        self.messages.copyAvailable.connect(self.__onCopyAvailable)

        self.cNormalFormat = self.messages.currentCharFormat()
        self.cErrorFormat = self.messages.currentCharFormat()
        self.cErrorFormat.setForeground(QBrush(QColor(Qt.red)))
        self.__updateToolbarButtons()
        return

    def __createLayout(self, parent):
        " Helper to create the viewer layout "

        # Messages list area
        self.messages = QPlainTextEdit(parent)
        self.messages.setLineWrapMode(QPlainTextEdit.NoWrap)
        self.messages.setFont(QFont(GlobalData().skin.baseMonoFontFace))
        self.messages.setReadOnly(True)
        self.messages.setMaximumBlockCount(MAX_LINES)

        # Default font size is good enough for most of the systems.
        # 12.0 might be good only in case of the XServer on PC (Xming).
        # self.messages.setFontPointSize( 12.0 )

        # Buttons
        self.selectAllButton = QAction(PixmapCache().getIcon('selectall.png'),
                                       'Select all', self)
        self.selectAllButton.triggered.connect(self.messages.selectAll)
        self.copyButton = QAction(PixmapCache().getIcon('copytoclipboard.png'),
                                  'Copy to clipboard', self)
        self.copyButton.triggered.connect(self.messages.copy)
        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                   'Clear all', self)
        self.clearButton.triggered.connect(self.__clear)

        # Toolbar
        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Vertical)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.LeftToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedWidth(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addAction(self.selectAllButton)
        self.toolbar.addAction(self.copyButton)
        self.toolbar.addWidget(spacer)
        self.toolbar.addAction(self.clearButton)

        # layout
        layout = QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(self.toolbar)
        layout.addWidget(self.messages)

        self.setLayout(layout)
        return

    def __handleShowContextMenu(self, coord):
        """ Show the context menu """

        self.__selectAllMenuItem.setEnabled(not self.__isEmpty)
        self.__copyMenuItem.setEnabled(self.__copyAvailable)
        self.__clearMenuItem.setEnabled(not self.__isEmpty)

        self.__menu.popup(QCursor.pos())
        return

    def __appendText(self, txt, isError):
        " Append the text "

        if len(txt) == 0:
            return

        self.__isEmpty = False
        cursor = self.messages.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.messages.setTextCursor(cursor)
        if isError:
            self.messages.setCurrentCharFormat(self.cErrorFormat)
        else:
            self.messages.setCurrentCharFormat(self.cNormalFormat)
        self.messages.insertPlainText(txt)
        self.messages.insertPlainText('\n')
        self.messages.ensureCursorVisible()
        self.__updateToolbarButtons()
        return

    def appendMessage(self, txt):
        " Append the regular message "

        self.__appendText(txt, False)
        #QApplication.processEvents()
        return

    def appendError(self, txt):
        " Append the error message "

        self.__appendText(txt, True)
        #QApplication.processEvents()
        return

    def append(self, txt):
        " Decides what the message is - error or not - and append it then "

        if txt.startswith( 'CRITICAL' ) or \
           txt.startswith( 'ERROR' ) or \
           txt.startswith( 'WARNING' ):
            self.appendError(txt)
        else:
            self.appendMessage(txt)
        return

    def __updateToolbarButtons(self):
        " Contextually updates toolbar buttons "

        self.selectAllButton.setEnabled(not self.__isEmpty)
        self.copyButton.setEnabled(self.__copyAvailable)
        self.clearButton.setEnabled(not self.__isEmpty)
        return

    def __clear(self):
        " Triggers when the clear function is selected "
        self.__isEmpty = True
        self.__copyAvailable = False
        self.messages.clear()
        self.__updateToolbarButtons()
        return

    def __onCopyAvailable(self, isAvailable):
        " Triggers on the copyAvailable signal "
        self.__copyAvailable = isAvailable
        self.__updateToolbarButtons()
        return

    def getText(self):
        " Provides the content as a plain text "
        return self.messages.toPlainText()
Ejemplo n.º 39
0
    def add_action(self,
                   icon_name,
                   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_name: Name of the icon for this action. Its a normal file ui/resources.
        :type icon_name: str

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

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

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

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

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

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

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

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

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

        # Create the dialog (after translation) and keep reference
        self.dlg = GeogigPackageCreatorDialog()

        icon = QIcon(
            os.path.join(os.path.dirname(__file__), "ui", "resources",
                         os.path.basename(icon_name)))

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)

        return action
Ejemplo n.º 40
0
class DocumentViewManager(QMainWindow):
    """
    MDI area for displaying supporting documents within a given context e.g.
    supporting documents for a specific household based on the lifetime of the
    'SourceDocumentManager' instance.
    """
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setWindowFlags(Qt.Window)

        self._mdi_area = QMdiArea()
        self._mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self._mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setCentralWidget(self._mdi_area)
        # set the size of mid_area and DocumentViewManager based on the
        # screen size.
        screen = QDesktopWidget().availableGeometry()
        self._mdi_area.resize(screen.width() - 30, screen.height() - 80)
        self.resize(self._mdi_area.size())
        self._mdi_area.subWindowActivated.connect(self.update_actions)
        self._viewer_mapper = QSignalMapper(self)
        self._viewer_mapper.mapped[QWidget].connect(self.set_active_sub_window)

        win_title = QApplication.translate("DocumentViewManager",
                                           "Document Viewer")
        self.setWindowTitle(win_title)
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.statusBar().showMessage(
            QApplication.translate("DocumentViewManager", "Ready"))
        self._doc_viewers = {}

        self._create_menu_actions()
        self.update_actions()

    def center(self):
        """
        Move the Document viewer to the center of the screen.
        """
        # Get the current screens' dimensions...
        screen = QDesktopWidget().availableGeometry()
        # ... and get this windows' dimensions
        mdi_area_size = self.frameGeometry()
        # The horizontal position
        hpos = (screen.width() - mdi_area_size.width()) / 2
        # vertical position
        vpos = (screen.height() - mdi_area_size.height()) / 2
        # repositions the window
        self.move(hpos, vpos)

    def _create_menu_actions(self):
        self._window_menu = self.menuBar().addMenu(
            QApplication.translate("DocumentViewManager", "&Windows"))

        self._close_act = QAction(
            QApplication.translate("DocumentViewManager", "Cl&ose"), self)
        self._close_act.setStatusTip(
            QApplication.translate("DocumentViewManager",
                                   "Close the active document viewer"))
        self._close_act.triggered.connect(self._mdi_area.closeActiveSubWindow)

        self._close_all_act = QAction(
            QApplication.translate("DocumentViewManager", "Close &All"), self)
        self._close_all_act.setStatusTip(
            QApplication.translate("DocumentViewManager",
                                   "Close all the document viewers"))
        self._close_all_act.triggered.connect(
            self._mdi_area.closeAllSubWindows)

        self._tile_act = QAction(
            QApplication.translate("DocumentViewManager", "&Tile"), self)
        self._tile_act.setStatusTip(
            QApplication.translate("DocumentViewManager",
                                   "Tile the document viewers"))
        self._tile_act.triggered.connect(self.tile_windows)

        self._cascade_act = QAction(
            QApplication.translate("DocumentViewManager", "&Cascade"), self)
        self._cascade_act.setStatusTip(
            QApplication.translate("DocumentViewManager",
                                   "Cascade the document viewers"))
        self._cascade_act.triggered.connect(self.cascade_windows)

        self._next_act = QAction(
            QApplication.translate("DocumentViewManager", "Ne&xt"), self)
        self._next_act.setStatusTip(
            QApplication.translate(
                "DocumentViewManager",
                "Move the focus to the next document viewer"))
        self._next_act.triggered.connect(self._mdi_area.activateNextSubWindow)

        self._previous_act = QAction(
            QApplication.translate("DocumentViewManager", "Pre&vious"), self)
        self._previous_act.setStatusTip(
            QApplication.translate(
                "DocumentViewManager",
                "Move the focus to the previous document viewer"))
        self._previous_act.triggered.connect(
            self._mdi_area.activatePreviousSubWindow)

        self._separator_act = QAction(self)
        self._separator_act.setSeparator(True)

        self.update_window_menu()
        self._window_menu.aboutToShow.connect(self.update_window_menu)

    def cascade_windows(self):
        #Cascade document windows
        self._mdi_area.cascadeSubWindows()

    def tile_windows(self):
        #Arrange document windows to occupy the available space in mdi area
        self._mdi_area.tileSubWindows()

    def update_actions(self):
        if self._mdi_area.activeSubWindow():
            has_mdi_child = True

        else:
            has_mdi_child = False

        self._close_act.setEnabled(has_mdi_child)
        self._close_all_act.setEnabled(has_mdi_child)
        self._tile_act.setEnabled(has_mdi_child)
        self._cascade_act.setEnabled(has_mdi_child)
        self._previous_act.setEnabled(has_mdi_child)
        self._next_act.setEnabled(has_mdi_child)
        self._separator_act.setVisible(has_mdi_child)

    def update_window_menu(self):
        self._window_menu.clear()
        self._window_menu.addAction(self._close_act)
        self._window_menu.addAction(self._close_all_act)
        self._window_menu.addSeparator()
        self._window_menu.addAction(self._tile_act)
        self._window_menu.addAction(self._cascade_act)
        self._window_menu.addSeparator()
        self._window_menu.addAction(self._next_act)
        self._window_menu.addAction(self._previous_act)
        self._window_menu.addAction(self._separator_act)

        windows = self._mdi_area.subWindowList()
        self._separator_act.setVisible(len(windows) != 0)

        for i, window in enumerate(windows):
            text = "%d. %s" % (i + 1, window.windowTitle())

            win_action = self._window_menu.addAction(text)
            win_action.setCheckable(True)
            win_action.setChecked(window is self._mdi_area.activeSubWindow())
            win_action.triggered.connect(self._viewer_mapper.map)
            self._viewer_mapper.setMapping(win_action, window)

    def load_viewer(self, document_widget, visible=True):
        """
        Open a new instance of the viewer or activate an existing one if the
        document had been previously loaded.
        :param document_widget: Contains all the necessary information required
        to load the specific document.
        :type document_widget: DocumentWidget
        :param visible: True to show the view manager after the viewer has
        been loaded, otherwise it will be the responsibility of the caller to
        enable visibility.
        :type visible: bool
        :returns: True if the document was successfully loaded, else False.
        :rtype: bool
        """
        doc_identifier = document_widget.file_identifier()

        if doc_identifier in self._doc_viewers:

            doc_sw = self._doc_viewers[doc_identifier]

            self._mdi_area.setActiveSubWindow(doc_sw)
            doc_sw.showNormal()

        else:
            doc_viewer = self._create_viewer(document_widget)

            abs_doc_path = self.absolute_document_path(document_widget)

            if not QFile.exists(abs_doc_path):
                msg = QApplication.translate(
                    "DocumentViewManager",
                    "The selected document does not exist."
                    "\nPlease check the supporting documents' "
                    "repository setting.")
                QMessageBox.critical(
                    self,
                    QApplication.translate("DocumentViewManager",
                                           "Invalid Document"), msg)

                return False

            doc_viewer.load_document(abs_doc_path)

            self._doc_viewers[doc_identifier] = doc_viewer

            self._mdi_area.addSubWindow(doc_viewer)

            doc_viewer.show()

        if not self.isVisible() and visible:
            self.setVisible(True)

        if self.isMinimized():
            self.showNormal()

        self.center()

        return True

    def set_active_sub_window(self, viewer):
        if viewer:
            self._mdi_area.setActiveSubWindow(viewer)

    def absolute_document_path(self, document_widget):
        """
        Build the absolute document path using info from the document widget.
        :param document_widget: Instance of document widget.
        :return: Absolute path of the supporting document.
        :rtype: str
        """
        abs_path = ''

        file_manager = document_widget.fileManager
        if not file_manager is None:
            network_repository = file_manager.networkPath
            file_id = document_widget.file_identifier()
            source_entity = document_widget.doc_source_entity()
            profile_name = current_profile().name
            doc_type = document_widget.doc_type_value().lower().replace(
                ' ', '_')
            file_name, file_extension = guess_extension(
                document_widget.displayName())

            abs_path = network_repository + "/" +profile_name + '/' +\
                       unicode(source_entity) + "/" + unicode(doc_type) + "/" +\
                       unicode(file_id) + unicode(file_extension)

        return abs_path

    def reset(self):
        """
        Removes all document viewers in the view area.
        The QCloseEvent sent to each sub-window will decrement the register.
        """
        self._mdi_area.closeAllSubWindows()

    def _create_viewer(self, document_widget):
        """
        Creates a new instance of a document viewer.
        :param document_widget: Contains all
        the necessary information required
        to load the specific document.
        :return: Document viewer object
        :rtype: DocumentViewer
        """
        doc_viewer = DocumentViewer(self._mdi_area,
                                    document_widget.file_identifier())
        doc_viewer.setAttribute(Qt.WA_DeleteOnClose)
        doc_viewer.setWindowTitle(document_widget.displayName())

        # TODO: Incorporate logic for determining
        # TODO: viewer based on document type
        ph_viewer = PhotoViewer()

        # v_layout = QVBoxLayout()
        # v_layout.addWidget(ph_viewer)
        # doc_viewer.setLayout(v_layout)

        doc_viewer.set_view_widget(ph_viewer)

        doc_viewer.closed.connect(self._on_viewer_closed)

        return doc_viewer

    def remove_viewer(self, viewer_id):
        """
        Close and remove the viewer with the specified viewer ID.
        """
        if viewer_id in self._doc_viewers:
            viewer = self._doc_viewers[viewer_id]
            self._mdi_area.setActiveSubWindow(viewer)
            self._mdi_area.closeActiveSubWindow()

        self._on_viewer_closed(viewer_id)

    def _on_viewer_closed(self, file_id):
        """
        Slot raised when a document viewer is closed.
        """
        if file_id in self._doc_viewers:
            del self._doc_viewers[file_id]
Ejemplo n.º 41
0
class PhotoViewer(QScrollArea):
    """
    Widget for viewing images by incorporating basic navigation options.
    """
    def __init__(self, parent=None, photo_path=""):
        QScrollArea.__init__(self, parent)
        self.setBackgroundRole(QPalette.Dark)

        self._printer = QPrinter()

        self._lbl_photo = QLabel()
        self._lbl_photo.setBackgroundRole(QPalette.Base)
        self._lbl_photo.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored)
        self._lbl_photo.setScaledContents(True)

        self.setWidget(self._lbl_photo)

        self._photo_path = photo_path
        self._ph_image = None
        self._scale_factor = 1.0
        self._aspect_ratio = -1

        self._create_actions()

        if self._photo_path:
            self.load_document(self._photo_path)

    def _create_actions(self):
        """
        Create actions for basic image navigation.
        """
        self._zoom_in_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &In (25%)"), self)
        self._zoom_in_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl++"))
        self._zoom_in_act.setEnabled(False)
        self._zoom_in_act.triggered.connect(self.zoom_in)

        self._zoom_out_act = QAction(
            QApplication.translate("PhotoViewer", "Zoom &Out (25%)"), self)
        self._zoom_out_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+-"))
        self._zoom_out_act.setEnabled(False)
        self._zoom_out_act.triggered.connect(self.zoom_out)

        self._normal_size_act = QAction(
            QApplication.translate("PhotoViewer", "&Normal Size"), self)
        self._normal_size_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+S"))
        self._normal_size_act.setEnabled(False)
        self._normal_size_act.triggered.connect(self.normal_size)

        self._fit_to_window_act = QAction(
            QApplication.translate("PhotoViewer", "&Fit to Window"), self)
        self._fit_to_window_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+F"))
        self._fit_to_window_act.setEnabled(False)
        self._fit_to_window_act.setCheckable(True)
        self._fit_to_window_act.triggered.connect(self.fit_to_window)

        self._print_act = QAction(
            QApplication.translate("PhotoViewer", "&Print"), self)
        self._print_act.setShortcut(
            QApplication.translate("PhotoViewer", "Ctrl+P"))
        self._print_act.setEnabled(False)
        self._print_act.triggered.connect(self.print_photo)

    def zoom_in(self):
        self.scale_photo(1.25)

    def zoom_out(self):
        self.scale_photo(0.8)

    def normal_size(self):
        self._lbl_photo.adjustSize()
        self._scale_factor = 1.0

    def fit_to_window(self):
        fit_to_win = self._fit_to_window_act.isChecked()
        self.setWidgetResizable(fit_to_win)

        if not fit_to_win:
            self.normal_size()

        self.update_actions()

    def print_photo(self):
        print_dialog = QPrintDialog(self._printer, self)

        if print_dialog.exec_() == QDialog.Accepted:
            painter = QPainter(self._printer)
            rect = painter.viewport()
            size = self._lbl_photo.pixmap().size()
            size.scale(rect.size(), Qt.KeepAspectRatio)
            painter.setViewport(rect.x(), rect.y(), size.width(),
                                size.height())
            painter.setWindow(self._lbl_photo.pixmap().rect())
            painter.drawPixmap(0, 0, self._lbl_photo.pixmap())

    def wheelEvent(self, event):
        """
        Zoom the image based on the mouse wheel rotation action.
        :param event: Event containing the wheel rotation info.
        :type event: QWheelEvent
        """
        degrees = event.delta() / 8
        num_steps = degrees / 15

        if num_steps < 0:
            abs_num_steps = abs(num_steps)
            zoom_factor = 1 + (abs_num_steps * 0.25)

        else:
            zoom_factor = 1 - (num_steps * 0.2)

        self.scale_photo(zoom_factor)

    def heightForWidth(self, width):
        if self._aspect_ratio != -1:
            return width / self._aspect_ratio

        else:
            return -1

    def resizeEvent(self, event):
        """
        Event for resizing the widget based on the pixmap's aspect ratio.
        :param event: Contains event parameters for the resize event.
        :type event: QResizeEvent
        """
        super(PhotoViewer, self).resizeEvent(event)

    def update_actions(self):
        self._zoom_out_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._zoom_in_act.setEnabled(not self._fit_to_window_act.isChecked())
        self._normal_size_act.setEnabled(
            not self._fit_to_window_act.isChecked())

    def scale_photo(self, factor):
        """
        :param factor: Value by which the image will be increased/decreased in the view.
        :type factor: float
        """
        if not self._lbl_photo.pixmap().isNull():
            self._scale_factor *= factor
            self._lbl_photo.resize(self._scale_factor *
                                   self._lbl_photo.pixmap().size())

            self._adjust_scroll_bar(self.horizontalScrollBar(), factor)
            self._adjust_scroll_bar(self.verticalScrollBar(), factor)

            self._zoom_in_act.setEnabled(self._scale_factor < 3.0)
            self._zoom_out_act.setEnabled(self._scale_factor > 0.333)

    def _adjust_scroll_bar(self, scroll_bar, factor):
        scroll_bar.setValue(
            int(factor * scroll_bar.value() +
                ((factor - 1) * scroll_bar.pageStep() / 2)))

    def load_document(self, photo_path):
        if photo_path:
            self._ph_image = QImage(photo_path)

            if self._ph_image.isNull():
                return False

            self._photo_path = photo_path

            ph_pixmap = QPixmap.fromImage(self._ph_image)

            self._lbl_photo.setPixmap(ph_pixmap)
            self._scale_factor = 1.0

            self._aspect_ratio = ph_pixmap.width() / ph_pixmap.height()

            self._fit_to_window_act.setEnabled(True)
            self._print_act.setEnabled(True)
            self._fit_to_window_act.trigger()

            self.update_actions()
            return ph_pixmap

        return True

    def photo_location(self):
        """
        :returns: Absolute path of the photo in the central document repository.
        """
        return self._photo_path

    def set_actions(self, menu):
        """
        Add custom actions to the sub-window menu
        """
        menu.addSeparator()
        menu.addAction(self._zoom_in_act)
        menu.addAction(self._zoom_out_act)
        menu.addAction(self._normal_size_act)
        menu.addAction(self._fit_to_window_act)
        menu.addSeparator()
        menu.addAction(self._print_act)
Ejemplo n.º 42
0
class VCSAnnotateViewerTabWidget(QWidget, MainWindowTabWidgetBase):
    " VCS annotate viewer tab widget "

    textEditorZoom = pyqtSignal(int)
    escapePressed = pyqtSignal()

    def __init__(self, parent):

        MainWindowTabWidgetBase.__init__(self)
        QWidget.__init__(self, parent)

        self.__viewer = VCSAnnotateViewer(self)
        self.__viewer.escapePressed.connect(self.__onEsc)
        self.__fileName = ""
        self.__shortName = ""
        self.__fileType = UnknownFileType

        self.__createLayout()
        self.__viewer.zoomTo(Settings().zoom)
        return

    def __onEsc(self):
        " Triggered when Esc is pressed "
        self.escapePressed.emit()
        return

    def __createLayout(self):
        " Creates the toolbar and layout "

        # Buttons
        printButton = QAction(PixmapCache().getIcon('printer.png'), 'Print',
                              self)
        printButton.triggered.connect(self.__onPrint)
        printButton.setEnabled(False)
        printButton.setVisible(False)

        printPreviewButton = QAction(PixmapCache().getIcon('printpreview.png'),
                                     'Print preview', self)
        printPreviewButton.triggered.connect(self.__onPrintPreview)
        printPreviewButton.setEnabled(False)
        printPreviewButton.setVisible(False)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.lineCounterButton = QAction(
            PixmapCache().getIcon('linecounter.png'), 'Line counter', self)
        self.lineCounterButton.triggered.connect(self.onLineCounter)

        # The toolbar
        toolbar = QToolBar(self)
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.RightToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)

        toolbar.addAction(printPreviewButton)
        toolbar.addAction(printButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.lineCounterButton)

        self.__importsBar = ImportListWidget(self.__viewer)
        self.__importsBar.hide()

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins(0, 0, 0, 0)
        hLayout.setSpacing(0)
        hLayout.addWidget(self.__viewer)
        hLayout.addWidget(toolbar)

        self.setLayout(hLayout)
        return

    def updateStatus(self):
        " Updates the toolbar buttons status "
        if self.__fileType == UnknownFileType:
            self.__fileType = self.getFileType()
        isPythonFile = self.__fileType in [PythonFileType, Python3FileType]
        self.lineCounterButton.setEnabled(isPythonFile)
        return

    def onZoomReset(self):
        " Triggered when the zoom reset button is pressed "
        if self.__viewer.zoom != 0:
            self.textEditorZoom.emit(0)
        return True

    def onZoomIn(self):
        " Triggered when the zoom in button is pressed "
        if self.__viewer.zoom < 20:
            self.textEditorZoom.emit(self.__viewer.zoom + 1)
        return True

    def onZoomOut(self):
        " Triggered when the zoom out button is pressed "
        if self.__viewer.zoom > -10:
            self.textEditorZoom.emit(self.__viewer.zoom - 1)
        return True

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def onLineCounter(self):
        " Triggered when line counter button is clicked "
        LineCounterDialog(None, self.__viewer).exec_()
        return

    def setFocus(self):
        " Overridden setFocus "
        self.__viewer.setFocus()
        return

    def onOpenImport(self):
        " Triggered when Ctrl+I is received "
        if self.__fileType not in [PythonFileType, Python3FileType]:
            return True

        # Python file, we may continue
        importLine, lineNo = isImportLine(self.__viewer)
        basePath = os.path.dirname(self.__fileName)

        if importLine:
            lineImports, importWhat = getImportsInLine(self.__viewer.text(),
                                                       lineNo + 1)
            currentWord = str(self.__viewer.getCurrentWord("."))
            if currentWord in lineImports:
                # The cursor is on some import
                path = resolveImport(basePath, currentWord)
                if path != '':
                    GlobalData().mainWindow.openFile(path, -1)
                    return True
                GlobalData().mainWindow.showStatusBarMessage(
                    "The import '" + currentWord + "' is not resolved.", 0)
                return True
            # We are not on a certain import.
            # Check if it is a line with exactly one import
            if len(lineImports) == 1:
                path = resolveImport(basePath, lineImports[0])
                if path == '':
                    GlobalData().mainWindow.showStatusBarMessage(
                        "The import '" + lineImports[0] + "' is not resolved.",
                        0)
                    return True
                # The import is resolved. Check where we are.
                if currentWord in importWhat:
                    # We are on a certain imported name in a resolved import
                    # So, jump to the definition line
                    line = getImportedNameDefinitionLine(path, currentWord)
                    GlobalData().mainWindow.openFile(path, line)
                    return True
                GlobalData().mainWindow.openFile(path, -1)
                return True

            # Take all the imports in the line and resolve them.
            self.__onImportList(basePath, lineImports)
            return True

        # Here: the cursor is not on the import line. Take all the file imports
        # and resolve them
        fileImports = getImportsList(self.__viewer.text())
        if not fileImports:
            GlobalData().mainWindow.showStatusBarMessage(
                "There are no imports.", 0)
            return True
        if len(fileImports) == 1:
            path = resolveImport(basePath, fileImports[0])
            if path == '':
                GlobalData().mainWindow.showStatusBarMessage(
                    "The import '" + fileImports[0] + "' is not resolved.", 0)
                return True
            GlobalData().mainWindow.openFile(path, -1)
            return True

        self.__onImportList(basePath, fileImports)
        return True

    def __onImportList(self, basePath, imports):
        " Works with a list of imports "

        # It has already been checked that the file is a Python one
        resolvedList = resolveImports(basePath, imports)
        if not resolvedList:
            GlobalData().mainWindow.showStatusBarMessage(
                "No imports are resolved.", 0)
            return

        # Display the import selection widget
        self.__importsBar.showResolvedList(resolvedList)
        return

    def resizeEvent(self, event):
        " Resizes the import selection dialogue if necessary "
        QWidget.resizeEvent(self, event)
        self.resizeBars()
        return

    def resizeBars(self):
        " Resize the bars if they are shown "
        if not self.__importsBar.isHidden():
            self.__importsBar.resize()
        self.__viewer.resizeCalltip()
        return

    def onPylint(self):
        return True

    def onPymetrics(self):
        return True

    def onRunScript(self, action=False):
        return True

    def onRunScriptSettings(self):
        return True

    def onProfileScript(self, action=False):
        return True

    def onProfileScriptSettings(self):
        return True

    def onImportDgm(self, action=None):
        return True

    def onImportDgmTuned(self):
        return True

    def shouldAcceptFocus(self):
        return True

    def setAnnotatedContent(self, shortName, text, lineRevisions,
                            revisionInfo):
        " Sets the content "
        self.setShortName(shortName)
        self.__viewer.setAnnotatedContent(shortName, text, lineRevisions,
                                          revisionInfo)
        return

    def writeFile(self, fileName):
        " Writes the text to a file "
        return self.__viewer.writeFile(fileName)

    def updateModificationTime(self, fileName):
        return

    # Mandatory interface part is below

    def getEditor(self):
        " Provides the editor widget "
        return self.__viewer

    def isModified(self):
        " Tells if the file is modified "
        return False

    def getRWMode(self):
        " Tells if the file is read only "
        return "RO"

    def getFileType(self):
        " Provides the file type "
        if self.__fileType == UnknownFileType:
            if self.__shortName:
                self.__fileType = detectFileType(self.__shortName)
        return self.__fileType

    def setFileType(self, typeToSet):
        """ Sets the file type explicitly.
            It needs e.g. for .cgi files which can change its type """
        self.__fileType = typeToSet
        return

    def getType(self):
        " Tells the widget type "
        return MainWindowTabWidgetBase.VCSAnnotateViewer

    def getLanguage(self):
        " Tells the content language "
        if self.__fileType == UnknownFileType:
            self.__fileType = self.getFileType()
        if self.__fileType != UnknownFileType:
            return getFileLanguage(self.__fileType)
        return self.__viewer.getLanguage()

    def getFileName(self):
        " Tells what file name of the widget content "
        return "n/a"

    def setFileName(self, name):
        " Sets the file name "
        raise Exception(
            "Setting a file name for annotate results is not applicable")

    def getEol(self):
        " Tells the EOL style "
        return self.__viewer.getEolIndicator()

    def getLine(self):
        " Tells the cursor line "
        line, pos = self.__viewer.getCursorPosition()
        return int(line)

    def getPos(self):
        " Tells the cursor column "
        line, pos = self.__viewer.getCursorPosition()
        return int(pos)

    def getEncoding(self):
        " Tells the content encoding "
        return self.__viewer.encoding

    def setEncoding(self, newEncoding):
        " Sets the new editor encoding "
        self.__viewer.setEncoding(newEncoding)
        return

    def getShortName(self):
        " Tells the display name "
        return self.__shortName

    def setShortName(self, name):
        " Sets the display name "
        self.__shortName = name
        self.__fileType = detectFileType(name)
        return
Ejemplo n.º 43
0
class QgsAttributeTableDialog(QDialog):
    '''
    classdocs
    '''
    def __init__(self, parent, vectorlayer):
        QDialog.__init__(self, parent)
        #         self.w = QDialog(self)
        self.baseLayer = vectorlayer
        self.canChangeAttributes = self.validate(
            QgsVectorDataProvider.ChangeAttributeValues)
        self.canDeleteFeatures = self.validate(
            QgsVectorDataProvider.DeleteFeatures)
        self.canAddAttributes = self.validate(
            QgsVectorDataProvider.AddAttributes)
        self.canDeleteAttributes = self.validate(
            QgsVectorDataProvider.DeleteAttributes)
        self.canAddFeatures = self.validate(QgsVectorDataProvider.AddFeatures)

        gridLayout = QGridLayout(self)
        self.setLayout(gridLayout)

        self.setWindowTitle("Attribute Table")
        self.setFixedSize(QSize(800, 600))

        editorToolbar = QToolBar()
        editorToolbar.setFixedSize(QSize(768, 48))
        self.actionToggleEditing = QAction(QIcon("Resource\\edit.png"),
                                           "ToggleEditing", self)
        self.actionToggleEditing.triggered.connect(self.toggleEditing)
        if (self.canChangeAttributes or self.canDeleteFeatures
                or self.canAddAttributes or self.canDeleteAttributes
                or self.canAddFeatures) and (not self.baseLayer.isReadOnly()):
            self.actionToggleEditing.setEnabled(True)
        else:
            self.actionToggleEditing.setEnabled(False)
        self.actionToggleEditing.setCheckable(True)
        editorToolbar.addAction(self.actionToggleEditing)

        self.actionSave = QAction(QIcon("Resource\\filesave.png"),
                                  "Save Edits", self)
        self.actionSave.triggered.connect(self.saveEditing)
        self.actionSave.setCheckable(False)
        self.actionSave.setEnabled(False)
        editorToolbar.addAction(self.actionSave)

        self.actiondeleteRows = QAction(
            QIcon("Resource\\mActionDeleteSelected.png"),
            "Delete selected features", self)
        self.actiondeleteRows.triggered.connect(self.deleteRows)
        self.actiondeleteRows.setCheckable(False)
        self.actiondeleteRows.setEnabled(False)
        editorToolbar.addAction(self.actiondeleteRows)

        self.actionUnselectAll = QAction(
            QIcon("Resource\\mActionDeselectAll.png"), "Unselect All", self)
        self.actionUnselectAll.triggered.connect(self.unselectAll)
        self.actionUnselectAll.setCheckable(False)
        self.actionUnselectAll.setEnabled(True)
        editorToolbar.addAction(self.actionUnselectAll)

        self.actionSelectedToZoom = QAction(
            QIcon("Resource\\mActionZoomToSelected.png"),
            "Zoom map to the selected rows", self)
        self.actionSelectedToZoom.triggered.connect(self.selectedToZoom)
        self.actionSelectedToZoom.setCheckable(False)
        self.actionSelectedToZoom.setEnabled(True)
        editorToolbar.addAction(self.actionSelectedToZoom)

        gridLayout.addWidget(editorToolbar, 0, 0, 1, 1)

        self.model = QStandardItemModel()

        #         self.model.itemChanged.connect(self.attributeChanged)
        self.attributeTable = QTableView(self)
        self.attributeTable.setModel(self.model)
        self.attributeTable.setColumnWidth(0, 200)
        self.attributeTable.setColumnWidth(1, 160)
        self.attributeTable.clicked.connect(self.tableSelectionChanged)
        self.attributeTable.setSortingEnabled(True)

        self.changeItemList = []
        self.selectRows = []
        self.isSave = True
        self.initTable()
        gridLayout.addWidget(self.attributeTable, 1, 0, 1, 1)
#         self.attributeTable.selectionChanged.connect(self.selectFeature)

    def tableSelectionChanged(self):
        idxList = self.attributeTable.selectedIndexes()
        if idxList != None and len(idxList) > 0:
            self.baseLayer.removeSelection()
            fidList = []
            for idx in idxList:
                fid = int(self.model.item(idx.row()).text())
                fidList.append(fid)
            self.baseLayer.setSelectedFeatures(fidList)

    def toggleEditing(self):
        if self.baseLayer != None:

            if not self.actionToggleEditing.isChecked():

                if self.isSave:
                    self.baseLayer.commitChanges()
                    self.actionSave.setEnabled(False)
                    self.actiondeleteRows.setEnabled(False)
                    self.model.itemChanged.disconnect(self.attributeChanged)
                    self.toggleEditingTable(False)
                else:
                    button = QMessageBox.warning(
                        self, "Stop Editing",
                        "Do you want to save the changes to layer?",
                        QMessageBox.Save | QMessageBox.Discard
                        | QMessageBox.Cancel)
                    if (button == QMessageBox.Cancel):
                        self.actionToggleEditing.setChecked(True)

                    elif button == QMessageBox.Save:
                        self.saveEditing()
                        self.baseLayer.commitChanges()
                        self.actionSave.setEnabled(False)
                        self.actiondeleteRows.setEnabled(False)
                        self.model.itemChanged.disconnect(
                            self.attributeChanged)
                        self.toggleEditingTable(False)
                    else:
                        self.initTable()
                        self.baseLayer.commitChanges()
                        self.actionSave.setEnabled(False)
                        self.actiondeleteRows.setEnabled(False)
                        self.model.itemChanged.disconnect(
                            self.attributeChanged)
                        self.toggleEditingTable(False)
#                 self.isEditable = False
            else:
                self.actionSave.setEnabled(True)
                self.actiondeleteRows.setEnabled(True)
                self.baseLayer.startEditing()
                self.toggleEditingTable(True)
                self.model.itemChanged.connect(self.attributeChanged)
#                 self.isEditable = True

    def toggleEditingTable(self, isEditable):
        columnCount = self.model.columnCount()
        rowCount = self.model.rowCount()
        col = 0
        while col < columnCount:
            row = 0
            while row < rowCount:
                self.model.item(row, col).setEditable(isEditable)
                row += 1
            col += 1

    def attributeChanged(self, standardItem):
        self.isSave = False
        #         if not self.isDelete:
        self.changeItemList.append(standardItem)
#         featureId = standardItem.row()
#         self.baseLayer.changeAttributeValue(featureId,
#                                        standardItem.column(), standardItem.text())

    def saveEditing(self):
        self.isSave = True
        if len(self.changeItemList) > 0:
            for standardItem in self.changeItemList:
                featureId = standardItem.row()
                self.baseLayer.changeAttributeValue(featureId,
                                                    standardItem.column(),
                                                    standardItem.text())
            self.changeItemList = []
        if len(self.selectRows) > 0:
            for id in self.selectRows:
                self.baseLayer.deleteFeature(id)
            self.selectRows = []

    def initTable(self):
        self.model.clear()
        #         header = QHeaderView(Qt.Horizontal)
        #         headerModel = QStandardItemModel()

        layer = self.baseLayer
        fields = layer.pendingFields()
        headersList = ["fid"]
        for field in fields:
            headersList.append(field.name())
        self.model.setHorizontalHeaderLabels(headersList)

        #         headerModel.setHorizontalHeaderLabels(headersList)
        #         header.setModel(headerModel)
        #         self.attributeTable.setHorizontalHeader(header)

        if len(layer.selectedFeatures()) > 0:
            features = layer.selectedFeatures()
        else:
            features = layer.getFeatures()
        for feature in features:
            record = [QStandardItem(str(feature.id()))]

            for field in feature.fields():
                name = field.name()
                attribute = feature.attribute(name).toString()

                stdItemValue = QStandardItem(attribute)
                stdItemValue.setEditable(False)
                record.append(stdItemValue)
            self.model.appendRow(record)

    def deleteRows(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.isSave = False
            selectedIndexs = self.attributeTable.selectedIndexes()
            k = -1
            self.selectRows = []
            for index in selectedIndexs:
                if k != index.row():
                    k = index.row()
                    self.selectRows.append(k)
            for row in self.selectRows:
                self.model.takeRow(row)

    def unselectAll(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.attributeTable.clearSelection()

    def selectedToZoom(self):
        if len(self.attributeTable.selectedIndexes()) > 0:
            self.baseLayer.removeSelection()

            selectedIndexs = self.attributeTable.selectedIndexes()
            k = -1
            self.selectRows = []
            for index in selectedIndexs:
                if k != index.row():
                    k = index.row()
                    self.selectRows.append(k)
            self.baseLayer.setSelectedFeatures(self.selectRows)
#             for row in self.selectRows:
#                 self.model.takeRow(row)
        define._canvas.zoomToSelected(self.baseLayer)

    def validate(self, condition):
        if self.baseLayer.dataProvider().capabilities() & condition:
            return True
        else:
            return False
Ejemplo n.º 44
0
 def createuiaction(self):
     action = QAction(QIcon(self.icon), self.icontext, None)
     if not self.valid[0]:
         action.setEnabled(False)
         action.setText(action.text() + " (invalid)")
     return action
Ejemplo n.º 45
0
class ImageView(QWidget, Script):
    def __init__(self):
        Script.__init__(self, "viewerimage")
        self.type = "imageview"
        self.icon = None
        self.vfs = vfs.vfs()
        self.reg_viewer = re.compile(
            ".*(JPEG|JPG|jpg|jpeg|GIF|gif|bmp|png|PNG|pbm|PBM|pgm|PGM|ppm|PPM|xpm|XPM|xbm|XBM|TIFF|tiff).*",
            re.IGNORECASE)
        self.sceneWidth = 0

    def start(self, args):
        try:
            self.preview = args["preview"].value()
        except IndexError:
            self.preview = False
        try:
            self.node = args["file"].value()
            self.curIdx = self.node.at()
        except KeyError:
            pass

    def isImage(self, node):
        if node.size() != 0:
            try:
                type = node.dataType()
            except (IndexError, AttributeError, IOError):
                return False
            if self.reg_viewer.search(str(type)):
                return True
        return False

    def next(self):
        listNodes = self.node.parent().children()
        newIdx = self.curIdx + 1
        if newIdx >= len(listNodes):
            newIdx = 0
        while newIdx != self.curIdx:
            if self.isImage(listNodes[newIdx]):
                break
            newIdx += 1
            if newIdx >= len(listNodes):
                newIdx = 0
        self.curIdx = newIdx
        self.setImage(listNodes[self.curIdx])

    def previous(self):
        listNodes = self.node.parent().children()
        newIdx = self.curIdx - 1
        if newIdx < 0:
            newIdx = len(listNodes) - 1
        while newIdx != self.curIdx:
            if self.isImage(listNodes[newIdx]):
                break
            newIdx -= 1
            if newIdx < 0:
                newIdx = len(listNodes) - 1
        self.curIdx = newIdx
        self.setImage(listNodes[self.curIdx])

    def createActions(self):
        self.actions = QToolBar()
        self.actions.setObjectName("Image viewer actions")
        self.nextButton = QAction(QIcon(":next.png"), "Display next image",
                                  self.actions)
        self.previousButton = QAction(QIcon(":previous.png"),
                                      "Display previous image", self.actions)
        self.rotlButton = QAction(QIcon(":rotate-left.png"),
                                  "Rotate the image 90 degrees to the left",
                                  self.actions)
        self.rotrButton = QAction(QIcon(":rotate-right.png"),
                                  "Rotate the image 90 degrees to the right",
                                  self.actions)
        self.enlargeButton = QAction(QIcon(":viewmag+"), "Enlarge the image",
                                     self.actions)
        self.shrinkButton = QAction(QIcon(":viewmag-"), "Shrink the image",
                                    self.actions)
        self.fitButton = QAction(QIcon(":viewmagfit"),
                                 "Fit the image to the window", self.actions)
        self.normalButton = QAction(QIcon(":viewmag1"),
                                    "Show the image at its normal size",
                                    self.actions)
        self.actions.addAction(self.previousButton)
        self.actions.addAction(self.nextButton)
        self.actions.addAction(self.rotlButton)
        self.actions.addAction(self.rotrButton)
        self.actions.addAction(self.enlargeButton)
        self.actions.addAction(self.shrinkButton)
        self.actions.addAction(self.fitButton)
        self.actions.addAction(self.normalButton)
        self.connect(self.loadedImage, SIGNAL("available(bool)"),
                     self.enableActions)
        self.connect(self.previousButton, SIGNAL("triggered()"), self.previous)
        self.connect(self.nextButton, SIGNAL("triggered()"), self.next)
        self.connect(self.rotlButton, SIGNAL("triggered()"),
                     self.loadedImage.rotateLeft)
        self.connect(self.rotrButton, SIGNAL("triggered()"),
                     self.loadedImage.rotateRight)
        self.connect(self.enlargeButton, SIGNAL("triggered()"),
                     self.loadedImage.enlarge)
        self.connect(self.shrinkButton, SIGNAL("triggered()"),
                     self.loadedImage.shrink)
        self.connect(self.fitButton, SIGNAL("triggered()"),
                     self.loadedImage.fit)
        self.connect(self.normalButton, SIGNAL("triggered()"),
                     self.loadedImage.normal)

    def enableActions(self, cond):
        self.rotlButton.setEnabled(cond)
        self.rotrButton.setEnabled(cond)
        self.enlargeButton.setEnabled(cond)
        self.shrinkButton.setEnabled(cond)
        self.fitButton.setEnabled(cond)
        self.normalButton.setEnabled(cond)

    def setImage(self, node):
        if not self.preview:
            self.imagelabel.clear()
            self.imagelabel.insert(QString.fromUtf8(node.absolute()))
            self.metadata.process(node)
        self.loadedImage.load(node)

    def g_display(self):
        QWidget.__init__(self, None)
        self.factor = 1
        self.box = QHBoxLayout()
        self.setLayout(self.box)

        self.imagebox = QVBoxLayout()
        self.scrollArea = QScrollArea()
        self.loadedImage = LoadedImage(self.scrollArea)
        self.scrollArea.setWidget(self.loadedImage)
        self.scrollArea.setAlignment(Qt.AlignCenter)
        if not self.preview:
            self.createActions()
            self.imagelabelbox = QVBoxLayout()
            self.imagelabelbox.setSpacing(0)
            self.imagelabel = QLineEdit()
            self.imagelabelbox.addWidget(self.imagelabel)
            self.imagelabel.setReadOnly(True)
            self.imagebox.addWidget(self.actions)
        self.imagebox.addWidget(self.scrollArea)
        if not self.preview:
            self.imagebox.setAlignment(self.actions, Qt.AlignCenter)
            self.imagebox.addLayout(self.imagelabelbox)
            self.databox = QVBoxLayout()
            self.metadata = Metadata()
            self.databox.addWidget(self.metadata)

            if len(self.node.parent().children()) < 2:
                self.nextButton.setEnabled(False)
                self.previousButton.setEnabled(False)

        self.box.addLayout(self.imagebox)
        if not self.preview:
            self.box.addLayout(self.databox)

        self.setImage(self.node.parent().children()[self.curIdx])

    def updateWidget(self):
        if not self.preview:
            self.metadata.setMaximumSize(self.width() / 4, self.height())
        self.loadedImage.adjust()

    def resizeEvent(self, e):
        if not self.preview:
            self.metadata.setMaximumSize(self.width() / 4, self.height())
        self.loadedImage.adjust()
Ejemplo n.º 46
0
class ProfileResultsWidget(QWidget, MainWindowTabWidgetBase):
    " Profiling results widget "

    escapePressed = pyqtSignal()

    def __init__(self, scriptName, params, reportTime, dataFile, parent=None):

        MainWindowTabWidgetBase.__init__(self)
        QWidget.__init__(self, parent)

        # The same stats object is needed for both - a table and a graph
        # So, parse profile output once and then pass the object further
        stats = pstats.Stats(dataFile)
        stats.calc_callees()

        self.__profTable = ProfileTableViewer(scriptName, params, reportTime,
                                              dataFile, stats, self)
        self.__profGraph = ProfileGraphViewer(scriptName, params, reportTime,
                                              dataFile, stats, self)
        self.__profTable.hide()

        self.__profTable.escapePressed.connect(self.__onEsc)
        self.__profGraph.escapePressed.connect(self.__onEsc)

        self.__createLayout()
        return

    def __createLayout(self):
        " Creates the toolbar and layout "

        # Buttons
        self.__toggleViewButton = QAction(
            PixmapCache().getIcon('tableview.png'), 'Switch to table view',
            self)
        self.__toggleViewButton.setCheckable(True)
        self.__toggleViewButton.toggled.connect(self.__switchView)

        self.__togglePathButton = QAction(
            PixmapCache().getIcon('longpath.png'),
            'Show full paths for item location', self)
        self.__togglePathButton.setCheckable(True)
        self.__togglePathButton.toggled.connect(self.__togglePath)
        self.__togglePathButton.setEnabled(False)

        self.__printButton = QAction(PixmapCache().getIcon('printer.png'),
                                     'Print', self)
        self.__printButton.triggered.connect(self.__onPrint)
        self.__printButton.setEnabled(False)

        self.__printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        self.__printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.__printPreviewButton.setEnabled(False)

        fixedSpacer = QWidget()
        fixedSpacer.setFixedHeight(16)

        self.__zoomInButton = QAction(PixmapCache().getIcon('zoomin.png'),
                                      'Zoom in (Ctrl+=)', self)
        self.__zoomInButton.setShortcut('Ctrl+=')
        self.__zoomInButton.triggered.connect(self.onZoomIn)

        self.__zoomOutButton = QAction(PixmapCache().getIcon('zoomout.png'),
                                       'Zoom out (Ctrl+-)', self)
        self.__zoomOutButton.setShortcut('Ctrl+-')
        self.__zoomOutButton.triggered.connect(self.onZoomOut)

        self.__zoomResetButton = QAction(
            PixmapCache().getIcon('zoomreset.png'), 'Zoom reset (Ctrl+0)',
            self)
        self.__zoomResetButton.setShortcut('Ctrl+0')
        self.__zoomResetButton.triggered.connect(self.onZoomReset)

        # Toolbar
        toolbar = QToolBar(self)
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.RightToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)

        toolbar.addAction(self.__toggleViewButton)
        toolbar.addAction(self.__togglePathButton)
        toolbar.addAction(self.__printPreviewButton)
        toolbar.addAction(self.__printButton)
        toolbar.addWidget(fixedSpacer)
        toolbar.addAction(self.__zoomInButton)
        toolbar.addAction(self.__zoomOutButton)
        toolbar.addAction(self.__zoomResetButton)

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins(0, 0, 0, 0)
        hLayout.setSpacing(0)
        hLayout.addWidget(self.__profTable)
        hLayout.addWidget(self.__profGraph)
        hLayout.addWidget(toolbar)

        self.setLayout(hLayout)
        return

    def setFocus(self):
        " Overriden setFocus "
        if self.__profTable.isVisible():
            self.__profTable.setFocus()
        else:
            self.__profGraph.setFocus()
        return

    def __onEsc(self):
        " Triggered when Esc is pressed "
        self.escapePressed.emit()
        return

    def __switchView(self, state):
        " Triggered when view is to be switched "
        if state:
            self.__profGraph.hide()
            self.__profTable.show()
            self.__toggleViewButton.setIcon(
                PixmapCache().getIcon('profdgmview.png'))
            self.__toggleViewButton.setToolTip('Switch to diagram view')
            self.__zoomInButton.setEnabled(False)
            self.__zoomOutButton.setEnabled(False)
            self.__zoomResetButton.setEnabled(False)
            self.__togglePathButton.setEnabled(True)
            self.__profTable.setFocus()
        else:
            self.__profTable.hide()
            self.__profGraph.show()
            self.__toggleViewButton.setIcon(
                PixmapCache().getIcon('tableview.png'))
            self.__toggleViewButton.setToolTip('Switch to table view')
            self.__zoomInButton.setEnabled(True)
            self.__zoomOutButton.setEnabled(True)
            self.__zoomResetButton.setEnabled(True)
            self.__togglePathButton.setEnabled(False)
            self.__profGraph.setFocus()
        return

    def __togglePath(self, state):
        " Triggered when full path/file name is switched "
        self.__profTable.togglePath(state)
        if state:
            self.__togglePathButton.setIcon(
                PixmapCache().getIcon('shortpath.png'))
            self.__togglePathButton.setToolTip(
                'Show file names only for item location')
        else:
            self.__togglePathButton.setIcon(
                PixmapCache().getIcon('longpath.png'))
            self.__togglePathButton.setToolTip(
                'Show full paths for item location')
        return

    def __onPrint(self):
        " Triggered on the 'print' button "
        pass

    def __onPrintPreview(self):
        " Triggered on the 'print preview' button "
        pass

    def isZoomApplicable(self):
        " Should the zoom menu items be available "
        return self.__profGraph.isVisible()

    def onZoomIn(self):
        " Triggered on the 'zoom in' button "
        if self.__profGraph.isVisible():
            self.__profGraph.zoomIn()
        return

    def onZoomOut(self):
        " Triggered on the 'zoom out' button "
        if self.__profGraph.isVisible():
            self.__profGraph.zoomOut()
        return

    def onZoomReset(self):
        " Triggered on the 'zoom reset' button "
        if self.__profGraph.isVisible():
            self.__profGraph.resetZoom()
        return

    def isCopyAvailable(self):
        " Tells id the main menu copy item should be switched on "
        return self.__profGraph.isVisible()

    def isDiagramActive(self):
        " Tells if the diagram is active "
        return self.__profGraph.isVisible()

    def onCopy(self):
        " Ctrl+C triggered "
        if self.__profGraph.isVisible():
            self.__profGraph.onCopy()
        return

    def onSaveAs(self, fileName):
        " Saves the diagram into a file "
        if self.__profGraph.isVisible():
            self.__profGraph.onSaveAs(fileName)
        else:
            self.__profTable.onSaveAs(fileName)
        return

    # Mandatory interface part is below

    def isModified(self):
        " Tells if the file is modified "
        return False

    def getRWMode(self):
        " Tells if the file is read only "
        return "RO"

    def getType(self):
        " Tells the widget type "
        return MainWindowTabWidgetBase.ProfileViewer

    def getLanguage(self):
        " Tells the content language "
        return "Profiler"

    def getFileName(self):
        " Tells what file name of the widget content "
        return "N/A"

    def setFileName(self, name):
        " Sets the file name - not applicable"
        raise Exception(
            "Setting a file name for profile results is not applicable")

    def getEol(self):
        " Tells the EOL style "
        return "N/A"

    def getLine(self):
        " Tells the cursor line "
        return "N/A"

    def getPos(self):
        " Tells the cursor column "
        return "N/A"

    def getEncoding(self):
        " Tells the content encoding "
        return "N/A"

    def setEncoding(self, newEncoding):
        " Sets the new encoding - not applicable for the profiler results viewer "
        return

    def getShortName(self):
        " Tells the display name "
        return "Profiling results"

    def setShortName(self, name):
        " Sets the display name - not applicable "
        raise Exception(
            "Setting a file name for profiler results is not applicable")
Ejemplo n.º 47
0
class RunConsoleTabWidget(QWidget, MainWindowTabWidgetBase):
    " IO console tab widget "

    textEditorZoom = pyqtSignal(int)
    settingUpdated = pyqtSignal()

    def __init__(self, threadID, parent=None):

        MainWindowTabWidgetBase.__init__(self)
        QWidget.__init__(self, parent)

        self.__viewer = RedirectedIOConsole(self)
        self.connect(self.__viewer, SIGNAL('UserInput'), self.__onUserInput)

        self.__threadID = threadID
        self.__showstdin = True
        self.__showstdout = True
        self.__showstderr = True

        self.__createLayout()
        return

    def threadID(self):
        " Provides the thread ID the console linked to "
        return self.__threadID

    def __onUserInput(self, userInput):
        " Triggered when the user finished input in the redirected IO console "
        self.emit(SIGNAL('UserInput'), self.__threadID, userInput)
        self.__clearButton.setEnabled(True)
        return

    def __createLayout(self):
        " Creates the toolbar and layout "

        # Buttons
        self.__printButton = QAction(PixmapCache().getIcon('printer.png'),
                                     'Print', self)
        self.__printButton.triggered.connect(self.__onPrint)
        self.__printButton.setEnabled(False)
        self.__printButton.setVisible(False)

        self.__printPreviewButton = QAction(
            PixmapCache().getIcon('printpreview.png'), 'Print preview', self)
        self.__printPreviewButton.triggered.connect(self.__onPrintPreview)
        self.__printPreviewButton.setEnabled(False)
        self.__printPreviewButton.setVisible(False)

        # self.__sendUpButton = QAction( PixmapCache().getIcon('sendioup.png'),
        #                                'Send to Main Editing Area', self )
        # self.__sendUpButton.triggered.connect( self.__sendUp )

        self.__filterMenu = QMenu(self)
        self.__filterMenu.aboutToShow.connect(self.__filterAboutToShow)
        self.__filterGroup = QActionGroup(self)
        self.__filterShowAllAct = self.__filterMenu.addAction("Show all")
        self.__filterShowAllAct.setCheckable(True)
        self.__filterShowAllAct.setActionGroup(self.__filterGroup)
        self.__filterShowAllAct.triggered.connect(self.__onFilterShowAll)
        self.__filterShowStdoutAct = self.__filterMenu.addAction(
            "Show stdin and stdout")
        self.__filterShowStdoutAct.setCheckable(True)
        self.__filterShowStdoutAct.setActionGroup(self.__filterGroup)
        self.__filterShowStdoutAct.triggered.connect(self.__onFilterShowStdout)
        self.__filterShowStderrAct = self.__filterMenu.addAction(
            "Show stdin and stderr")
        self.__filterShowStderrAct.setCheckable(True)
        self.__filterShowStderrAct.setActionGroup(self.__filterGroup)
        self.__filterShowStderrAct.triggered.connect(self.__onFilterShowStderr)
        self.__filterButton = QToolButton(self)
        self.__filterButton.setIcon(PixmapCache().getIcon('iofilter.png'))
        self.__filterButton.setToolTip('Filtering settings')
        self.__filterButton.setPopupMode(QToolButton.InstantPopup)
        self.__filterButton.setMenu(self.__filterMenu)
        self.__filterButton.setFocusPolicy(Qt.NoFocus)

        self.__settingsMenu = QMenu(self)
        self.__settingsMenu.aboutToShow.connect(self.__settingsAboutToShow)
        self.__wrapLongLinesAct = self.__settingsMenu.addAction(
            "Wrap long lines")
        self.__wrapLongLinesAct.setCheckable(True)
        self.__wrapLongLinesAct.triggered.connect(self.__onWrapLongLines)
        self.__showEOLAct = self.__settingsMenu.addAction("Show EOL")
        self.__showEOLAct.setCheckable(True)
        self.__showEOLAct.triggered.connect(self.__onShowEOL)
        self.__showWhitespacesAct = self.__settingsMenu.addAction(
            "Show whitespaces")
        self.__showWhitespacesAct.setCheckable(True)
        self.__showWhitespacesAct.triggered.connect(self.__onShowWhitespaces)
        self.__autoscrollAct = self.__settingsMenu.addAction("Autoscroll")
        self.__autoscrollAct.setCheckable(True)
        self.__autoscrollAct.triggered.connect(self.__onAutoscroll)
        self.__showMarginAct = self.__settingsMenu.addAction(
            "Show timestamp margin")
        self.__showMarginAct.setCheckable(True)
        self.__showMarginAct.triggered.connect(self.__onShowMargin)

        self.__settingsButton = QToolButton(self)
        self.__settingsButton.setIcon(PixmapCache().getIcon('iosettings.png'))
        self.__settingsButton.setToolTip('View settings')
        self.__settingsButton.setPopupMode(QToolButton.InstantPopup)
        self.__settingsButton.setMenu(self.__settingsMenu)
        self.__settingsButton.setFocusPolicy(Qt.NoFocus)

        fixedSpacer = QWidget()
        fixedSpacer.setFixedHeight(8)

        self.__stopButton = QAction(
            PixmapCache().getIcon('runconsolestop.png'), 'Stop process', self)
        self.__stopButton.triggered.connect(self.stop)

        self.__stopAndCloseButton = QAction(
            PixmapCache().getIcon('runconsolestopclose.png'),
            'Stop process and close tab', self)
        self.__stopAndCloseButton.triggered.connect(self.stopAndClose)

        spacer = QWidget()
        spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.__clearButton = QAction(PixmapCache().getIcon('trash.png'),
                                     'Clear', self)
        self.__clearButton.triggered.connect(self.clear)

        # The toolbar
        toolbar = QToolBar(self)
        toolbar.setOrientation(Qt.Vertical)
        toolbar.setMovable(False)
        toolbar.setAllowedAreas(Qt.RightToolBarArea)
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFixedWidth(28)
        toolbar.setContentsMargins(0, 0, 0, 0)

        # toolbar.addAction( self.__sendUpButton )
        toolbar.addAction(self.__printPreviewButton)
        toolbar.addAction(self.__printButton)
        toolbar.addWidget(self.__filterButton)
        toolbar.addWidget(self.__settingsButton)
        toolbar.addWidget(fixedSpacer)
        toolbar.addAction(self.__stopButton)
        toolbar.addAction(self.__stopAndCloseButton)
        toolbar.addWidget(spacer)
        toolbar.addAction(self.__clearButton)

        hLayout = QHBoxLayout()
        hLayout.setContentsMargins(0, 0, 0, 0)
        hLayout.setSpacing(0)
        hLayout.addWidget(toolbar)
        hLayout.addWidget(self.__viewer)

        self.setLayout(hLayout)
        return

    def onZoomReset(self):
        " Triggered when the zoom reset button is pressed "
        if self.__viewer.zoom != 0:
            self.textEditorZoom.emit(0)
        return True

    def onZoomIn(self):
        " Triggered when the zoom in button is pressed "
        if self.__viewer.zoom < 20:
            self.textEditorZoom.emit(self.__viewer.zoom + 1)
        return True

    def onZoomOut(self):
        " Triggered when the zoom out button is pressed "
        if self.__viewer.zoom > -10:
            self.textEditorZoom.emit(self.__viewer.zoom - 1)
        return True

    def __onPrint(self):
        " Triggered when the print button is pressed "
        pass

    def __onPrintPreview(self):
        " triggered when the print preview button is pressed "
        pass

    def setFocus(self):
        " Overridden setFocus "
        self.__viewer.setFocus()
        return

    def onOpenImport(self):
        " Triggered when Ctrl+I is received "
        return True

    def __sendUp(self):
        " Triggered when requested to move the console up "
        return

    def __filterAboutToShow(self):
        " Triggered when filter menu is about to show "
        showAll = self.__showstdin and \
                  self.__showstdout and \
                  self.__showstderr
        onlyStdout = self.__showstdin and \
                     self.__showstdout and \
                     not self.__showstderr
        onlyStderr = self.__showstdin and \
                     not self.__showstdout and \
                     self.__showstderr
        self.__filterShowAllAct.setChecked(showAll)
        self.__filterShowStdoutAct.setChecked(onlyStdout)
        self.__filterShowStderrAct.setChecked(onlyStderr)
        return

    def __onFilterShowAll(self):
        " Triggered when filter show all is clicked "
        if self.__showstdin == True and \
           self.__showstdout == True and \
           self.__showstderr == True:
            return

        self.__showstdin = True
        self.__showstdout = True
        self.__showstderr = True
        self.__viewer.renderContent()
        return

    def __onFilterShowStdout(self):
        " Triggered when filter show stdout only is clicked "
        if self.__showstdin == True and \
           self.__showstdout == True and \
           self.__showstderr == False:
            return

        self.__showstdin = True
        self.__showstdout = True
        self.__showstderr = False
        self.__viewer.renderContent()
        return

    def __onFilterShowStderr(self):
        " Triggered when filter show stderr only is clicked "
        if self.__showstdin == True and \
           self.__showstdout == False and \
           self.__showstderr == True:
            return

        self.__showstdin = True
        self.__showstdout = False
        self.__showstderr = True
        self.__viewer.renderContent()
        return

    def __settingsAboutToShow(self):
        " Settings menu is about to show "
        self.__wrapLongLinesAct.setChecked(Settings().ioconsolelinewrap)
        self.__showEOLAct.setChecked(Settings().ioconsoleshoweol)
        self.__showWhitespacesAct.setChecked(Settings().ioconsoleshowspaces)
        self.__autoscrollAct.setChecked(Settings().ioconsoleautoscroll)
        self.__showMarginAct.setChecked(Settings().ioconsoleshowmargin)
        return

    def __onWrapLongLines(self):
        " Triggered when long lines setting is changed "
        Settings().ioconsolelinewrap = not Settings().ioconsolelinewrap
        self.settingUpdated.emit()
        return

    def __onShowEOL(self):
        " Triggered when show EOL is changed "
        Settings().ioconsoleshoweol = not Settings().ioconsoleshoweol
        self.settingUpdated.emit()
        return

    def __onShowWhitespaces(self):
        " Triggered when show whitespaces is changed "
        Settings().ioconsoleshowspaces = not Settings().ioconsoleshowspaces
        self.settingUpdated.emit()
        return

    def __onAutoscroll(self):
        " Triggered when autoscroll is changed "
        Settings().ioconsoleautoscroll = not Settings().ioconsoleautoscroll
        return

    def __onShowMargin(self):
        " Triggered when show margin is changed "
        Settings().ioconsoleshowmargin = not Settings().ioconsoleshowmargin
        self.settingUpdated.emit()
        return

    def clear(self):
        " Triggered when requested to clear the console "
        self.__viewer.clearAll()
        return

    def consoleSettingsUpdated(self):
        " Triggered when one of the consoles updated a common setting "
        if Settings().ioconsolelinewrap:
            self.__viewer.setWrapMode(QsciScintilla.WrapWord)
        else:
            self.__viewer.setWrapMode(QsciScintilla.WrapNone)
        self.__viewer.setEolVisibility(Settings().ioconsoleshoweol)
        if Settings().ioconsoleshowspaces:
            self.__viewer.setWhitespaceVisibility(QsciScintilla.WsVisible)
        else:
            self.__viewer.setWhitespaceVisibility(QsciScintilla.WsInvisible)
        self.__viewer.setTimestampMarginWidth()
        return

    def resizeEvent(self, event):
        QWidget.resizeEvent(self, event)
        return

    def onPylint(self):
        return True

    def onPymetrics(self):
        return True

    def onRunScript(self, action=False):
        return True

    def onRunScriptSettings(self):
        return True

    def onProfileScript(self, action=False):
        return True

    def onProfileScriptSettings(self):
        return True

    def onImportDgm(self, action=None):
        return True

    def onImportDgmTuned(self):
        return True

    def shouldAcceptFocus(self):
        return True

    def writeFile(self, fileName):
        " Writes the text to a file "
        return self.__viewer.writeFile(fileName)

    def updateModificationTime(self, fileName):
        return

    def appendIDEMessage(self, text):
        " Appends an IDE message "
        self.__viewer.appendIDEMessage(text)
        return

    def appendStdoutMessage(self, text):
        " Appends an stdout message "
        self.__viewer.appendStdoutMessage(text)
        return

    def appendStderrMessage(self, text):
        " Appends an stderr message "
        self.__viewer.appendStderrMessage(text)
        return

    def hiddenMessage(self, msg):
        " Returns True if the message should not be shown "
        if msg.msgType == IOConsoleMsg.STDERR_MESSAGE and \
           not self.__showstderr:
            return True
        if msg.msgType == IOConsoleMsg.STDOUT_MESSAGE and \
           not self.__showstdout:
            return True
        return False

    def zoomTo(self, zoomValue):
        " Sets the new zoom value "
        self.__viewer.zoomTo(zoomValue)
        self.__viewer.setTimestampMarginWidth()
        return

    def rawInput(self, prompt, echo):
        " Triggered when raw input is requested "
        echo = int(echo)
        if echo == 0:
            self.__viewer.inputEcho = False
        else:
            self.__viewer.inputEcho = True

        if prompt:
            self.appendStdoutMessage(prompt)
        self.__clearButton.setEnabled(False)
        self.__viewer.switchMode(self.__viewer.MODE_INPUT)
        return

    def sessionStopped(self):
        " Triggered when redirecting session is stopped "
        self.__viewer.switchMode(self.__viewer.MODE_OUTPUT)
        self.__clearButton.setEnabled(True)
        return

    def stop(self):
        " Triggered when the user requesed to stop the process "
        self.emit(SIGNAL('KillIOConsoleProcess'), self.__threadID)
        return

    def stopAndClose(self):
        " Triggered when the user requested to stop the process and close console "
        self.stop()
        self.close()
        return

    def close(self):
        " Triggered when the console should be closed "
        self.emit(SIGNAL('CloseIOConsole'), self.__threadID)
        return

    def scriptFinished(self):
        " Triggered when the script process finished "
        self.__stopButton.setEnabled(False)
        self.__stopAndCloseButton.setToolTip("Close tab")
        self.__viewer.switchMode(self.__viewer.MODE_OUTPUT)
        self.__clearButton.setEnabled(True)
        return

    # Mandatory interface part is below

    def getEditor(self):
        " Provides the editor widget "
        return self.__viewer

    def isModified(self):
        " Tells if the file is modified "
        return False

    def getRWMode(self):
        " Tells if the file is read only "
        return "IO"

    def getFileType(self):
        " Provides the file type "
        return TexFileType

    def setFileType(self, typeToSet):
        """ Sets the file type explicitly.
            It needs e.g. for .cgi files which can change its type """
        raise Exception("Setting a file type is not supported by the "
                        "IO console widget")

    def getType(self):
        " Tells the widget type "
        return MainWindowTabWidgetBase.IOConsole

    def getLanguage(self):
        " Tells the content language "
        return "IO console"

    def getFileName(self):
        " Tells what file name of the widget content "
        return "n/a"

    def setFileName(self, name):
        " Sets the file name "
        raise Exception("Setting a file name for IO console "
                        "is not applicable")

    def getEol(self):
        " Tells the EOL style "
        return self.__viewer.getEolIndicator()

    def getLine(self):
        " Tells the cursor line "
        line, _ = self.__viewer.getCursorPosition()
        return int(line)

    def getPos(self):
        " Tells the cursor column "
        _, pos = self.__viewer.getCursorPosition()
        return int(pos)

    def getEncoding(self):
        " Tells the content encoding "
        return self.__viewer.encoding

    def setEncoding(self, newEncoding):
        " Sets the new editor encoding "
        raise Exception("Setting encoding is not supported by the "
                        "IO console widget")

    def getShortName(self):
        " Tells the display name "
        return "IO console"

    def setShortName(self, name):
        " Sets the display name "
        raise Exception("Setting short name is not supported by the "
                        "IO console widget")
class EditorRFUGeofoncier:
    def __init__(self, iface):

        # Save reference to the QGIS interface
        self.iface = iface

        self.canvas = self.iface.mapCanvas()
        self.map_layer_registry = QgsMapLayerRegistry.instance()

        # Initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # Initialize locale
        #locale = QSettings().value(r"locale/userLocale")[0:2]
        #locale_path = os.path.join(
        #        self.plugin_dir, r"i18n", r"translate_{}.qm".format(locale))

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

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

        self.conn = None
        self.rfu = None
        self.edge_creator = None

    def unload(self):

        # Remove the plugin menu item and icon..
        self.iface.removePluginMenu(u"&Géofoncier", self.action_connector)
        self.iface.removeToolBarIcon(self.action_connector)

    def initGui(self):

        # Add tool bar..
        self.toolbar = self.iface.addToolBar(u"Géofoncier Éditeur RFU")
        self.toolbar.setObjectName(r"GeofoncierRfuEditorToolBar")

        # Create action(s)..

        self.action_login = QAction(QIcon(r":/resources/btn_log_in"),
                                    u"S'identifer", self.iface.mainWindow())
        self.action_login.setEnabled(True)
        self.action_login.setCheckable(True)

        self.action_connector = QAction(QIcon(r":/resources/btn_conn_rfu"),
                                        u"Connection à l'API Géofoncier",
                                        self.iface.mainWindow())
        self.action_connector.setEnabled(False)
        self.action_connector.setCheckable(True)

        self.action_vtx_creator = QAction(QIcon(r":/resources/btn_add_vtx"),
                                          u"Ajouter un nœud RFU",
                                          self.iface.mainWindow())
        self.action_vtx_creator.setEnabled(False)

        self.action_edge_creator = QAction(QIcon(r":/resources/btn_add_edge"),
                                           u"Ajouter une limite RFU",
                                           self.iface.mainWindow())
        self.action_edge_creator.setEnabled(False)
        self.action_edge_creator.setCheckable(True)

        # Then add action(s) to the tool bar..
        self.toolbar.addActions([
            self.action_login, self.action_connector, self.action_vtx_creator,
            self.action_edge_creator
        ])

        # Manage signals..
        self.iface.currentLayerChanged.connect(self.on_toggled)
        # self.canvas.mapToolSet.connect(self.deactivate_tool)
        self.map_layer_registry.layersRemoved.connect(self.on_layers_removed)

        self.action_login.triggered.connect(self.tool_login_on_triggered)
        self.action_connector.triggered[bool].connect(
            self.tool_rfu_on_triggered)
        self.action_vtx_creator.triggered.connect(
            self.tool_vtx_creator_on_triggered)
        self.action_edge_creator.triggered[bool].connect(
            self.tool_edge_creator_on_triggered)

        # Initialize current layer to None (See switch_editing())..
        self.current_layer = None

    # On iface Signals
    # ================

    def on_toggled(self):

        layer = self.canvas.currentLayer()
        if not layer:
            return

        if layer.isEditable() and layer == self.rfu.l_vertex:
            self.switch_editing(layer)
            self.action_vtx_creator.setEnabled(True)
            self.action_edge_creator.setEnabled(False)
            QObject.connect(layer, SIGNAL(r"editingStopped()"),
                            self.on_toggled)
            QObject.disconnect(layer, SIGNAL(r"editingStarted()"),
                               self.on_toggled)

        elif layer.isEditable() and layer == self.rfu.l_edge:
            self.switch_editing(layer)
            self.action_vtx_creator.setEnabled(False)
            self.action_edge_creator.setEnabled(True)
            QObject.connect(layer, SIGNAL(r"editingStopped()"),
                            self.on_toggled)
            QObject.disconnect(layer, SIGNAL(r"editingStarted()"),
                               self.on_toggled)

        else:
            self.action_vtx_creator.setEnabled(False)
            self.action_edge_creator.setEnabled(False)
            QObject.connect(layer, SIGNAL(r"editingStopped()"),
                            self.on_toggled)
            QObject.disconnect(layer, SIGNAL(r"editingStarted()"),
                               self.on_toggled)

    def switch_editing(self, layer):

        old_layer = None

        if self.current_layer is not None:
            old_layer = self.current_layer
            QObject.disconnect(
                old_layer,
                SIGNAL(r"committedFeaturesAdded(QString, QgsFeatureList)"),
                self.on_committed_features_added)
            QObject.disconnect(
                old_layer,
                SIGNAL(r"committedFeaturesRemoved(QString, QgsFeatureIds)"),
                self.on_committed_features_removed)
            QObject.disconnect(
                old_layer,
                SIGNAL(r"attributeValueChanged(QgsFeatureId, int, QVariant)"),
                self.on_attribute_value_changed)
            QObject.disconnect(
                old_layer,
                SIGNAL(r"geometryChanged(QgsFeatureId, QgsGeometry)"),
                self.on_geometry_changed)

        self.current_layer = layer
        QObject.connect(
            layer, SIGNAL(r"committedFeaturesAdded(QString, QgsFeatureList)"),
            self.on_committed_features_added)
        QObject.connect(
            layer, SIGNAL(r"committedFeaturesRemoved(QString, QgsFeatureIds)"),
            self.on_committed_features_removed)
        QObject.connect(
            layer,
            SIGNAL(r"attributeValueChanged(QgsFeatureId, int, QVariant)"),
            self.on_attribute_value_changed)
        QObject.connect(layer,
                        SIGNAL(r"geometryChanged(QgsFeatureId, QgsGeometry)"),
                        self.on_geometry_changed)

    def on_committed_features_added(self, layer_id, features):
        self.rfu.add_features(layer_id, features)

    def on_committed_features_removed(self, layer_id, ft_id_list):
        self.rfu.remove_features(layer_id, ft_id_list)

    # def on_feature_added(self, fid):
    # feature = tools.get_feature_by_id(self.current_layer, fid)
    # self.rfu.add_feature(self.current_layer.id(), feature)

    def on_geometry_changed(self, fid, geom):
        feature = tools.get_feature_by_id(self.current_layer, fid)
        self.rfu.modify_feature(self.current_layer.id(), feature)

    def on_attribute_value_changed(self, fid, field_idx, value):
        feature = tools.get_feature_by_id(self.current_layer, fid)
        self.rfu.modify_feature(self.current_layer.id(), feature)

    # On map layer registry signals
    # =============================

    def on_layers_removed(self, layers):
        self.current_layer = None

    # Login/logout
    # ============

    def open_connection(self):

        dlg_login = GeoFoncierAPILogin()
        dlg_login.closed.connect(self.dlg_login_on_closed)
        dlg_login.opened.connect(self.dlg_login_on_opened)
        dlg_login.show()

        if not dlg_login.exec_():
            return None

        self.conn = dlg_login.conn
        self.action_connector.setEnabled(True)

        self.iface.messageBar().pushMessage(u"Géofoncier",
                                            u"Bonjour %s %s." %
                                            (self.conn.prenom, self.conn.nom),
                                            level=QgsMessageBar.INFO,
                                            duration=6)

    def close_connection(self):

        msg = (u"Voulez-vous fermer votre session ?\n"
               u"Attention, toute modification sera perdue.")
        resp = QMessageBox.question(self.iface.mainWindow(), r"Question", msg,
                                    QMessageBox.Yes, QMessageBox.No)
        if resp != QMessageBox.Yes:
            return False

        # Close connection
        if self.rfu:
            self.rfu.reset()
            self.rfu.close()
            #if self.rfu.conn:
            #    self.rfu.conn = None
            self.action_connector.setChecked(False)
            self.action_connector.setEnabled(False)

        self.conn = None

        self.iface.messageBar().pushMessage(u"Géofoncier",
                                            u"À bientôt.",
                                            level=QgsMessageBar.INFO,
                                            duration=6)

    # On action signals
    # =================

    def dlg_login_on_closed(self):

        if self.conn == None:
            self.action_login.setChecked(False)

    def dlg_login_on_opened(self):

        self.action_login.setChecked(True)

    def tool_login_on_triggered(self, checked):

        if checked:
            self.open_connection()
        else:
            self.close_connection()

    def tool_rfu_on_triggered(self, checked):

        if checked and not self.rfu:
            self.rfu = RFUDockWidget(self.iface,
                                     self.canvas,
                                     self.map_layer_registry,
                                     conn=self.conn)
            self.rfu.setObjectName(r"RFUDockWidget")
            self.iface.addDockWidget(Qt.TopDockWidgetArea, self.rfu)
            self.rfu.closed.connect(self.rfu_on_closed)
            self.rfu.downloaded.connect(self.on_toggled)
            self.rfu.uploaded.connect(self.rfu_on_uploaded)

        if checked and self.rfu:
            self.rfu.show()

        if not checked:
            self.rfu.hide()

    def rfu_on_closed(self):

        self.action_connector.setChecked(False)

    def rfu_on_uploaded(self):

        if self.edge_creator:
            self.on_edge_creator_destroyed()

    def tool_vtx_creator_on_triggered(self):

        if not self.rfu.dflt_ellips_acronym:
            self.rfu.selected_ellips_acronym = self.rfu.dflt_ellips_acronym

        dlg_vtx_creator = VertexCreator(
            self.canvas,
            self.rfu.layers[0],
            user=self.rfu.conn.user,
            precision_class=self.rfu.precision_class,
            ellips_acronym=self.rfu.ellips_acronym,
            selected_ellips_acronym=self.rfu.selected_ellips_acronym,
            nature=self.rfu.nature,
            auth_creator=self.rfu.auth_creator)

        dlg_vtx_creator.show()

        if not dlg_vtx_creator.exec_():
            return None

    def tool_edge_creator_on_triggered(self, checked=False):

        if not checked:
            self.edge_creator.close()
            self.edge_creator = None

        if checked:
            self.edge_creator = EdgeCreator(self.canvas,
                                            self.rfu.layers[0],
                                            self.rfu.layers[1],
                                            user=self.rfu.conn.user,
                                            auth_creator=self.rfu.auth_creator)

            self.edge_creator.setObjectName(r"EdgeCreatorDockWidget")
            self.edge_creator.destroyed.connect(self.on_edge_creator_destroyed)
            self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.edge_creator)

    def on_edge_creator_destroyed(self):

        self.edge_creator = None
        return self.action_edge_creator.setChecked(False)
class OSMEditorRemoteControlPlugin:

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

    # noinspection PyPep8Naming
    def initGui(self):
        self.action = QAction(
            QIcon(join(dirname(__file__), 'icons', 'josm_icon.svg')),
            'OSM Editor Remote Control',
            self.iface.mainWindow())
        self.action.setEnabled(False)
        help = 'Send remote control command to OSM editor to load data at ' \
               'current map view.'
        self.action.setWhatsThis(help)
        self.action.setStatusTip(help)
        self.action.triggered.connect(self.run)
        self.iface.mapCanvas().layersChanged.connect(self.change_status)
        self.iface.mapCanvas().extentsChanged.connect(self.change_status)
        self.iface.addToolBarIcon(self.action)

    def unload(self):
        self.iface.removeToolBarIcon(self.action)

    def get_lon_lat_extent(self):
        map_canvas = self.iface.mapCanvas()
        extent = map_canvas.mapSettings().extent()
        if map_canvas.hasCrsTransformEnabled():
            crs_map = map_canvas.mapSettings().destinationCrs()
        else:
            crs_map = map_canvas.currentLayer().crs()
        if crs_map.authid() != u'EPSG:4326':
            crs_4326 = QgsCoordinateReferenceSystem()
            crs_4326.createFromSrid(4326)
            return QgsCoordinateTransform(crs_map, crs_4326).transform(extent)
        return extent

    def change_status(self):
        if not self.iface.mapCanvas().currentLayer():
            self.action.setEnabled(False)
        else:
            extent = self.get_lon_lat_extent()
            self.action.setEnabled(
                extent.width() * extent.height() < MAX_DOWNLOAD_AREA_DEG)

    def run(self):
        extent = self.get_lon_lat_extent()
        url = 'http://localhost:8111/load_and_zoom?'
        query_string = 'left=%f&right=%f&top=%f&bottom=%f' % (
            extent.xMinimum(), extent.xMaximum(), extent.yMaximum(),
            extent.yMinimum())
        url += query_string
        try:
            f = urllib.urlopen(url, proxies={})
            result = f.read()
            f.close()
            if result.strip().upper() != 'OK':
                self.report_error('OSM reported: %s' % result)
        except IOError:
            self.report_error(
                'Could not connect to the OSM editor. Is the OSM editor '
                'running?')

    def report_error(self, error_message):
        self.iface.messageBar().pushCritical(
            'OSM Editor Remote Control Plugin', error_message)
Ejemplo n.º 50
0
class PythonConsoleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console"))

        self.settings = QSettings()

        self.shell = ShellScintilla(self)
        self.setFocusProxy(self.shell)
        self.shellOut = ShellOutputScintilla(self)
        self.tabEditorWidget = EditorTabWidget(self)

        ##------------ UI -------------------------------

        self.splitterEditor = QSplitter(self)
        self.splitterEditor.setOrientation(Qt.Horizontal)
        self.splitterEditor.setHandleWidth(6)
        self.splitterEditor.setChildrenCollapsible(True)

        self.shellOutWidget = QWidget(self)
        self.shellOutWidget.setLayout(QVBoxLayout())
        self.shellOutWidget.layout().setContentsMargins(0,0,0,0)
        self.shellOutWidget.layout().addWidget(self.shellOut)

        self.splitter = QSplitter(self.splitterEditor)
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.setHandleWidth(3)
        self.splitter.setChildrenCollapsible(False)
        self.splitter.addWidget(self.shellOutWidget)
        self.splitter.addWidget(self.shell)

        #self.splitterEditor.addWidget(self.tabEditorWidget)

        self.splitterObj = QSplitter(self.splitterEditor)
        self.splitterObj.setHandleWidth(3)
        self.splitterObj.setOrientation(Qt.Horizontal)
        #self.splitterObj.setSizes([0, 0])
        #self.splitterObj.setStretchFactor(0, 1)

        self.widgetEditor = QWidget(self.splitterObj)
        self.widgetFind = QWidget(self)

        self.listClassMethod = QTreeWidget(self.splitterObj)
        self.listClassMethod.setColumnCount(2)
        objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.listClassMethod.setHeaderLabels([objInspLabel, ''])
        self.listClassMethod.setColumnHidden(1, True)
        self.listClassMethod.setAlternatingRowColors(True)


        #self.splitterEditor.addWidget(self.widgetEditor)
        #self.splitterObj.addWidget(self.listClassMethod)
        #self.splitterObj.addWidget(self.widgetEditor)

        # Hide side editor on start up
        self.splitterObj.hide()
        self.listClassMethod.hide()
        # Hide search widget on start up
        self.widgetFind.hide()

        sizes = self.splitter.sizes()
        self.splitter.setSizes(sizes)

        ##----------------Restore Settings------------------------------------

        self.restoreSettingsConsole()

        ##------------------Toolbar Editor-------------------------------------

        ## Action for Open File
        openFileBt = QCoreApplication.translate("PythonConsole", "Open file")
        self.openFileButton = QAction(self)
        self.openFileButton.setCheckable(False)
        self.openFileButton.setEnabled(True)
        self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png"))
        self.openFileButton.setMenuRole(QAction.PreferencesRole)
        self.openFileButton.setIconVisibleInMenu(True)
        self.openFileButton.setToolTip(openFileBt)
        self.openFileButton.setText(openFileBt)

        openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in external editor")
        self.openInEditorButton = QAction(self)
        self.openInEditorButton.setCheckable(False)
        self.openInEditorButton.setEnabled(True)
        self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.openInEditorButton.setMenuRole(QAction.PreferencesRole)
        self.openInEditorButton.setIconVisibleInMenu(True)
        self.openInEditorButton.setToolTip(openExtEditorBt)
        self.openInEditorButton.setText(openExtEditorBt)
        ## Action for Save File
        saveFileBt = QCoreApplication.translate("PythonConsole", "Save")
        self.saveFileButton = QAction(self)
        self.saveFileButton.setCheckable(False)
        self.saveFileButton.setEnabled(False)
        self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png"))
        self.saveFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveFileButton.setIconVisibleInMenu(True)
        self.saveFileButton.setToolTip(saveFileBt)
        self.saveFileButton.setText(saveFileBt)
        ## Action for Save File As
        saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...")
        self.saveAsFileButton = QAction(self)
        self.saveAsFileButton.setCheckable(False)
        self.saveAsFileButton.setEnabled(True)
        self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png"))
        self.saveAsFileButton.setMenuRole(QAction.PreferencesRole)
        self.saveAsFileButton.setIconVisibleInMenu(True)
        self.saveAsFileButton.setToolTip(saveAsFileBt)
        self.saveAsFileButton.setText(saveAsFileBt)
        ## Action Cut
        cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut")
        self.cutEditorButton = QAction(self)
        self.cutEditorButton.setCheckable(False)
        self.cutEditorButton.setEnabled(True)
        self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCutEditorConsole.png"))
        self.cutEditorButton.setMenuRole(QAction.PreferencesRole)
        self.cutEditorButton.setIconVisibleInMenu(True)
        self.cutEditorButton.setToolTip(cutEditorBt)
        self.cutEditorButton.setText(cutEditorBt)
        ## Action Copy
        copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy")
        self.copyEditorButton = QAction(self)
        self.copyEditorButton.setCheckable(False)
        self.copyEditorButton.setEnabled(True)
        self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png"))
        self.copyEditorButton.setMenuRole(QAction.PreferencesRole)
        self.copyEditorButton.setIconVisibleInMenu(True)
        self.copyEditorButton.setToolTip(copyEditorBt)
        self.copyEditorButton.setText(copyEditorBt)
        ## Action Paste
        pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste")
        self.pasteEditorButton = QAction(self)
        self.pasteEditorButton.setCheckable(False)
        self.pasteEditorButton.setEnabled(True)
        self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png"))
        self.pasteEditorButton.setMenuRole(QAction.PreferencesRole)
        self.pasteEditorButton.setIconVisibleInMenu(True)
        self.pasteEditorButton.setToolTip(pasteEditorBt)
        self.pasteEditorButton.setText(pasteEditorBt)
        ## Action Run Script (subprocess)
        runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script")
        self.runScriptEditorButton = QAction(self)
        self.runScriptEditorButton.setCheckable(False)
        self.runScriptEditorButton.setEnabled(True)
        self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png"))
        self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole)
        self.runScriptEditorButton.setIconVisibleInMenu(True)
        self.runScriptEditorButton.setToolTip(runScriptEditorBt)
        self.runScriptEditorButton.setText(runScriptEditorBt)
        ## Action Run Script (subprocess)
        commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment")
        self.commentEditorButton = QAction(self)
        self.commentEditorButton.setCheckable(False)
        self.commentEditorButton.setEnabled(True)
        self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png"))
        self.commentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.commentEditorButton.setIconVisibleInMenu(True)
        self.commentEditorButton.setToolTip(commentEditorBt)
        self.commentEditorButton.setText(commentEditorBt)
        ## Action Run Script (subprocess)
        uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment")
        self.uncommentEditorButton = QAction(self)
        self.uncommentEditorButton.setCheckable(False)
        self.uncommentEditorButton.setEnabled(True)
        self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png"))
        self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole)
        self.uncommentEditorButton.setIconVisibleInMenu(True)
        self.uncommentEditorButton.setToolTip(uncommentEditorBt)
        self.uncommentEditorButton.setText(uncommentEditorBt)
        ## Action for Object browser
        objList = QCoreApplication.translate("PythonConsole", "Object Inspector")
        self.objectListButton = QAction(self)
        self.objectListButton.setCheckable(True)
        self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp",
                                                             False, type=bool))
        self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png"))
        self.objectListButton.setMenuRole(QAction.PreferencesRole)
        self.objectListButton.setIconVisibleInMenu(True)
        self.objectListButton.setToolTip(objList)
        self.objectListButton.setText(objList)
        ## Action for Find text
        findText = QCoreApplication.translate("PythonConsole", "Find Text")
        self.findTextButton = QAction(self)
        self.findTextButton.setCheckable(True)
        self.findTextButton.setEnabled(True)
        self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png"))
        self.findTextButton.setMenuRole(QAction.PreferencesRole)
        self.findTextButton.setIconVisibleInMenu(True)
        self.findTextButton.setToolTip(findText)
        self.findTextButton.setText(findText)

        ##----------------Toolbar Console-------------------------------------

        ## Action Show Editor
        showEditor = QCoreApplication.translate("PythonConsole", "Show editor")
        self.showEditorButton = QAction(self)
        self.showEditorButton.setEnabled(True)
        self.showEditorButton.setCheckable(True)
        self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png"))
        self.showEditorButton.setMenuRole(QAction.PreferencesRole)
        self.showEditorButton.setIconVisibleInMenu(True)
        self.showEditorButton.setToolTip(showEditor)
        self.showEditorButton.setText(showEditor)
        ## Action for Clear button
        clearBt = QCoreApplication.translate("PythonConsole", "Clear console")
        self.clearButton = QAction(self)
        self.clearButton.setCheckable(False)
        self.clearButton.setEnabled(True)
        self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png"))
        self.clearButton.setMenuRole(QAction.PreferencesRole)
        self.clearButton.setIconVisibleInMenu(True)
        self.clearButton.setToolTip(clearBt)
        self.clearButton.setText(clearBt)
        ## Action for settings
        optionsBt = QCoreApplication.translate("PythonConsole", "Settings")
        self.optionsButton = QAction(self)
        self.optionsButton.setCheckable(False)
        self.optionsButton.setEnabled(True)
        self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png"))
        self.optionsButton.setMenuRole(QAction.PreferencesRole)
        self.optionsButton.setIconVisibleInMenu(True)
        self.optionsButton.setToolTip(optionsBt)
        self.optionsButton.setText(optionsBt)
        ## Action menu for class
        actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class")
        self.actionClass = QAction(self)
        self.actionClass.setCheckable(False)
        self.actionClass.setEnabled(True)
        self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png"))
        self.actionClass.setMenuRole(QAction.PreferencesRole)
        self.actionClass.setIconVisibleInMenu(True)
        self.actionClass.setToolTip(actionClassBt)
        self.actionClass.setText(actionClassBt)
        ## Import Processing class
        loadProcessingBt = QCoreApplication.translate("PythonConsole", "Import Processing class")
        self.loadProcessingButton = QAction(self)
        self.loadProcessingButton.setCheckable(False)
        self.loadProcessingButton.setEnabled(True)
        self.loadProcessingButton.setIcon(QgsApplication.getThemeIcon("console/iconProcessingConsole.png"))
        self.loadProcessingButton.setMenuRole(QAction.PreferencesRole)
        self.loadProcessingButton.setIconVisibleInMenu(True)
        self.loadProcessingButton.setToolTip(loadProcessingBt)
        self.loadProcessingButton.setText(loadProcessingBt)
        ## Import QtCore class
        loadQtCoreBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore class")
        self.loadQtCoreButton = QAction(self)
        self.loadQtCoreButton.setCheckable(False)
        self.loadQtCoreButton.setEnabled(True)
        self.loadQtCoreButton.setIcon(QgsApplication.getThemeIcon("console/iconQtCoreConsole.png"))
        self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtCoreButton.setIconVisibleInMenu(True)
        self.loadQtCoreButton.setToolTip(loadQtCoreBt)
        self.loadQtCoreButton.setText(loadQtCoreBt)
        ## Import QtGui class
        loadQtGuiBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui class")
        self.loadQtGuiButton = QAction(self)
        self.loadQtGuiButton.setCheckable(False)
        self.loadQtGuiButton.setEnabled(True)
        self.loadQtGuiButton.setIcon(QgsApplication.getThemeIcon("console/iconQtGuiConsole.png"))
        self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole)
        self.loadQtGuiButton.setIconVisibleInMenu(True)
        self.loadQtGuiButton.setToolTip(loadQtGuiBt)
        self.loadQtGuiButton.setText(loadQtGuiBt)
        ## Action for Run script
        runBt = QCoreApplication.translate("PythonConsole", "Run command")
        self.runButton = QAction(self)
        self.runButton.setCheckable(False)
        self.runButton.setEnabled(True)
        self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png"))
        self.runButton.setMenuRole(QAction.PreferencesRole)
        self.runButton.setIconVisibleInMenu(True)
        self.runButton.setToolTip(runBt)
        self.runButton.setText(runBt)
        ## Help action
        helpBt = QCoreApplication.translate("PythonConsole", "Help")
        self.helpButton = QAction(self)
        self.helpButton.setCheckable(False)
        self.helpButton.setEnabled(True)
        self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png"))
        self.helpButton.setMenuRole(QAction.PreferencesRole)
        self.helpButton.setIconVisibleInMenu(True)
        self.helpButton.setToolTip(helpBt)
        self.helpButton.setText(helpBt)

        self.toolBar = QToolBar()
        self.toolBar.setEnabled(True)
        self.toolBar.setFocusPolicy(Qt.NoFocus)
        self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBar.setLayoutDirection(Qt.LeftToRight)
        self.toolBar.setIconSize(QSize(16, 16))
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.addAction(self.clearButton)
        self.toolBar.addAction(self.actionClass)
        self.toolBar.addAction(self.runButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.showEditorButton)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.optionsButton)
        self.toolBar.addAction(self.helpButton)

        self.toolBarEditor = QToolBar()
        self.toolBarEditor.setEnabled(False)
        self.toolBarEditor.setFocusPolicy(Qt.NoFocus)
        self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu)
        self.toolBarEditor.setLayoutDirection(Qt.LeftToRight)
        self.toolBarEditor.setIconSize(QSize(16, 16))
        self.toolBarEditor.setMovable(False)
        self.toolBarEditor.setFloatable(False)
        self.toolBarEditor.addAction(self.openFileButton)
        self.toolBarEditor.addAction(self.openInEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.saveFileButton)
        self.toolBarEditor.addAction(self.saveAsFileButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.findTextButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.cutEditorButton)
        self.toolBarEditor.addAction(self.copyEditorButton)
        self.toolBarEditor.addAction(self.pasteEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.commentEditorButton)
        self.toolBarEditor.addAction(self.uncommentEditorButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.objectListButton)
        self.toolBarEditor.addSeparator()
        self.toolBarEditor.addAction(self.runScriptEditorButton)

        ## Menu Import Class
        self.classMenu = QMenu()
        self.classMenu.addAction(self.loadProcessingButton)
        self.classMenu.addAction(self.loadQtCoreButton)
        self.classMenu.addAction(self.loadQtGuiButton)
        cM = self.toolBar.widgetForAction(self.actionClass)
        cM.setMenu(self.classMenu)
        cM.setPopupMode(QToolButton.InstantPopup)

        self.widgetButton = QWidget()
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth())
        self.widgetButton.setSizePolicy(sizePolicy)

        self.widgetButtonEditor = QWidget(self.widgetEditor)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth())
        self.widgetButtonEditor.setSizePolicy(sizePolicy)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth())
        self.shellOut.setSizePolicy(sizePolicy)

        self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        ##------------ Layout -------------------------------

        self.mainLayout = QGridLayout(self)
        self.mainLayout.setMargin(0)
        self.mainLayout.setSpacing(0)
        self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1)
        self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1)

        self.shellOutWidget.layout().insertWidget(0, self.toolBar)

        self.layoutEditor = QGridLayout(self.widgetEditor)
        self.layoutEditor.setMargin(0)
        self.layoutEditor.setSpacing(0)
        self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1)
        self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1)
        self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1)

        ## Layout for the find widget
        self.layoutFind = QGridLayout(self.widgetFind)
        self.layoutFind.setContentsMargins(0, 0, 0, 0)
        self.lineEditFind = QgsFilterLineEdit()
        placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...")

        if pyqtconfig.Configuration().qt_version >= 0x40700:
          self.lineEditFind.setPlaceholderText(placeHolderTxt)
        else:
          self.lineEditFind.setToolTip(placeHolderTxt)
        self.findNextButton = QToolButton()
        self.findNextButton.setEnabled(False)
        toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next")
        self.findNextButton.setToolTip(toolTipfindNext)
        self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png"))
        self.findNextButton.setIconSize(QSize(24, 24))
        self.findNextButton.setAutoRaise(True)
        self.findPrevButton = QToolButton()
        self.findPrevButton.setEnabled(False)
        toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous")
        self.findPrevButton.setToolTip(toolTipfindPrev)
        self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png"))
        self.findPrevButton.setIconSize(QSize(24, 24))
        self.findPrevButton.setAutoRaise(True)
        self.caseSensitive = QCheckBox()
        caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive")
        self.caseSensitive.setText(caseSensTr)
        self.wholeWord = QCheckBox()
        wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word")
        self.wholeWord.setText(wholeWordTr)
        self.wrapAround = QCheckBox()
        self.wrapAround.setChecked(True)
        wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around")
        self.wrapAround.setText(wrapAroundTr)
        self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1)
        self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1)
        self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1)
        self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1)
        self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1)
        self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1)

        ##------------ Add first Tab in Editor -------------------------------

        #self.tabEditorWidget.newTabEditor(tabName='first', filename=None)

        ##------------ Signal -------------------------------

        self.findTextButton.toggled.connect(self.findTextEditor)
        self.objectListButton.toggled.connect(self.toggleObjectListWidget)
        self.commentEditorButton.triggered.connect(self.commentCode)
        self.uncommentEditorButton.triggered.connect(self.uncommentCode)
        self.runScriptEditorButton.triggered.connect(self.runScriptEditor)
        self.cutEditorButton.triggered.connect(self.cutEditor)
        self.copyEditorButton.triggered.connect(self.copyEditor)
        self.pasteEditorButton.triggered.connect(self.pasteEditor)
        self.showEditorButton.toggled.connect(self.toggleEditor)
        self.clearButton.triggered.connect(self.shellOut.clearConsole)
        self.optionsButton.triggered.connect(self.openSettings)
        self.loadProcessingButton.triggered.connect(self.processing)
        self.loadQtCoreButton.triggered.connect(self.qtCore)
        self.loadQtGuiButton.triggered.connect(self.qtGui)
        self.runButton.triggered.connect(self.shell.entered)
        self.openFileButton.triggered.connect(self.openScriptFile)
        self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor)
        self.saveFileButton.triggered.connect(self.saveScriptFile)
        self.saveAsFileButton.triggered.connect(self.saveAsScriptFile)
        self.helpButton.triggered.connect(self.openHelp)
        self.connect(self.listClassMethod, SIGNAL('itemClicked(QTreeWidgetItem*, int)'),
                     self.onClickGoToLine)
        self.lineEditFind.returnPressed.connect(self._findText)
        self.findNextButton.clicked.connect(self._findNext)
        self.findPrevButton.clicked.connect(self._findPrev)
        self.lineEditFind.textChanged.connect(self._textFindChanged)

    def _findText(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findNext(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(True)

    def _findPrev(self):
        self.tabEditorWidget.currentWidget().newEditor.findText(False)

    def _textFindChanged(self):
        if self.lineEditFind.text():
            self.findNextButton.setEnabled(True)
            self.findPrevButton.setEnabled(True)
        else:
            self.lineEditFind.setStyleSheet('')
            self.findNextButton.setEnabled(False)
            self.findPrevButton.setEnabled(False)

    def onClickGoToLine(self, item, column):
        tabEditor = self.tabEditorWidget.currentWidget().newEditor
        if item.text(1) == 'syntaxError':
            check = tabEditor.syntaxCheck(fromContextMenu=False)
            if check and not tabEditor.isReadOnly():
                self.tabEditorWidget.currentWidget().save()
            return
        linenr = int(item.text(1))
        itemName = str(item.text(0))
        charPos = itemName.find(' ')
        if charPos != -1:
            objName = itemName[0:charPos]
        else:
            objName = itemName
        tabEditor.goToLine(objName, linenr)

    def processing(self):
       self.shell.commandConsole('processing')

    def qtCore(self):
       self.shell.commandConsole('qtCore')

    def qtGui(self):
       self.shell.commandConsole('qtGui')

    def toggleEditor(self, checked):
        self.splitterObj.show() if checked else self.splitterObj.hide()
        if not self.tabEditorWidget:
            self.tabEditorWidget.enableToolBarEditor(checked)
            self.tabEditorWidget.restoreTabsOrAddNew()

    def toggleObjectListWidget(self, checked):
        self.listClassMethod.show() if checked else self.listClassMethod.hide()

    def findTextEditor(self, checked):
        self.widgetFind.show() if checked else self.widgetFind.hide()

    def pasteEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.paste()

    def cutEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.cut()

    def copyEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.copy()

    def runScriptEditor(self):
        self.tabEditorWidget.currentWidget().newEditor.runScriptCode()

    def commentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True)

    def uncommentCode(self):
        self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False)

    def openScriptFileExtEditor(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        path = tabWidget.path
        import subprocess
        try:
            subprocess.Popen([os.environ['EDITOR'], path])
        except KeyError:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def openScriptFile(self):
        lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.home())
        openFileTr = QCoreApplication.translate("PythonConsole", "Open File")
        fileList = QFileDialog.getOpenFileNames(
            self, openFileTr, lastDirPath, "Script file (*.py)")
        if fileList:
            for pyFile in fileList:
                for i in range(self.tabEditorWidget.count()):
                    tabWidget = self.tabEditorWidget.widget(i)
                    if tabWidget.path == pyFile:
                        self.tabEditorWidget.setCurrentWidget(tabWidget)
                        break
                else:
                    tabName = QFileInfo(pyFile).fileName()
                    self.tabEditorWidget.newTabEditor(tabName, pyFile)

                    lastDirPath = QFileInfo(pyFile).path()
                    self.settings.setValue("pythonConsole/lastDirPath", pyFile)
                    self.updateTabListScript(pyFile, action='append')

    def saveScriptFile(self):
        tabWidget = self.tabEditorWidget.currentWidget()
        try:
            tabWidget.save()
        except (IOError, OSError), error:
            msgText = QCoreApplication.translate('PythonConsole',
                                                 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path,
                                                                                                              error.strerror)
            self.callWidgetMessageBarEditor(msgText, 2, False)
Ejemplo n.º 51
0
    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

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

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

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

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

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

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

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

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

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

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

        # Create the dialog (after translation) and keep reference
        self.dlg = GisGrimeFocusDialog()

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

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

        self.actions.append(action)
        ###########aca las conexiones a los botones############################
        # set the default crs system
        dest_crs = self.dlg.mpsw_crs.setCrs(QgsCoordinateReferenceSystem(3116))
        # funcion que guarda la ruta del archivo de salida en el text
        # correspondiente
        self.dlg.pBSearchFile.clicked.connect(self.readInputData)

        #funcionque conecta al boton con la funcion de convertir el scv en shape
        #  y cargarlo
        self.dlg.pBImport.clicked.connect(self.validations)

        self.dlg.mcb_lista_csv.layerChanged.connect(self.load_fields)
        self.dlg.pb_clean.clicked.connect(self.clean)

        # funcion que habilita el radio buton de numero de features al seleccionar
        # el cuadro de cifras
        self.dlg.dsb_bandwith.valueChanged.connect(self.radio_custom_click)

        return action
Ejemplo n.º 52
0
class CatalogOTFPlugin:
    def __init__(self, iface):
        def translate():
            #
            # For create file 'qm'
            # 1) Define that files need for translation: catalogotf.pro
            # 2) Create 'ts': pylupdate4 -verbose catalogotf.pro
            # 3) Edit your translation: QtLinquist
            # 4) Create 'qm': lrelease catalogotf_pt_BR.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.projOTF = ProjectDockWidgetCatalogOTF(iface)
        self.name = u"&Catalog OTF"
        self.dock = None
        name_src = "catalogotf"
        translate()

    def _connect(self, isConnect=True):
        signal_slot = ({
            'signal': QgsProject.instance().readProject,
            'slot': self.projOTF.onReadProject
        }, {
            'signal': QgsProject.instance().writeProject,
            'slot': self.projOTF.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):
        msgtrans = QCoreApplication.translate("CatalogOTF",
                                              "Catalog on the fly")
        icon = QIcon(os.path.join(os.path.dirname(__file__), 'catalogotf.svg'))
        self.action = QAction(icon, msgtrans, self.iface.mainWindow())
        self.action.setObjectName("CatalogOTF")
        self.action.setWhatsThis(msgtrans)
        self.action.setStatusTip(msgtrans)
        self.action.triggered.connect(self.run)

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

        self._connect()

    def unload(self):
        self.iface.removePluginMenu(self.name, self.action)
        self.iface.removeToolBarIcon(self.action)
        del self.action
        del self.dock
        self._connect(False)

    @pyqtSlot()
    def run(self):
        self.dock = DockWidgetCatalogOTF(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
        self.action.setEnabled(False)
Ejemplo n.º 53
0
class TunnelDialog(WindowBaseClass, Ui_TunnelDialog):
    def __init__(self):
        WindowBaseClass.__init__(self)
        self.setupUi(self)
        self._explicitQuit = False

        # Tunnels
        self._tunnels = []

        # Setup tray
        self.tray = Tray(self, "IOSSHy", QIcon(":/icons/network-server.png"))
        self.tray.activated.connect(self.activated)

        action = QAction("&Configure", self.tray.menu)
        action.setIcon(QIcon(":/icons/configure.png"))
        action.triggered.connect(self.show)
        self.tray.menu.addAction(action)
        self.tray.menu.setDefaultAction(action)

        self.tray.menu.addSeparator()
        self.actionNoTun = QAction("No tunnels configured", self.tray.menu)
        self.actionNoTun.setEnabled(False)
        self.tray.menu.addAction(self.actionNoTun)
        self.actionLastSep = self.tray.menu.addSeparator()

        if kde:
            action = QAction("&About", self.tray.menu)
            action.triggered.connect(self.about)
            self.tray.menu.addAction(action)

        action = QAction("&Quit", self.tray.menu)
        action.setIcon(QIcon(":/icons/application-exit.png"))
        action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q))
        action.triggered.connect(self.quit)
        self.tray.menu.addAction(action)

        # Load settings
        self.readSettings()
        self.hide()

    def show(self):
        self.visible = True
        WindowBaseClass.show(self)
        desktop = QDesktopWidget()
        rect = desktop.availableGeometry(desktop.primaryScreen()) 
        center = rect.center();
        center.setX(center.x() - (self.width()/2));
        center.setY(center.y() - (self.height()/2));
        self.move(center);

    def hide(self):
        self.visible = False
        self.writeSettings()
        WindowBaseClass.hide(self)

    def closeEvent(self, event):
        if not self._explicitQuit:
            self.hide()
            event.ignore()

    def on_listTunnels_currentItemChanged(self, current, previous):
        self.grpTunnelProperties.setEnabled(current is not None)
        self.grpSshProperties.setEnabled(current is not None)
        if current is not None:
            tunnel = self._tunnels[self.listTunnels.row(current)]

            self.txtName.setText( tunnel.name )
            self.txtHost.setText( "localhost" if tunnel.host == "" else tunnel.host )
            self.txtLocalPort.setText( "0" if tunnel.localPort is None else str(tunnel.localPort) )
            self.txtPort.setText( str(tunnel.port) )
            self.txtSshPort.setText( str(tunnel.sshPort) )
            self.txtUsername.setText( "root" if tunnel.username == "" else tunnel.username )
            self.txtCommand.setText( "" if tunnel.command is None else tunnel.command )
            self.chkCloseOnTerm.setChecked( Qt.Checked if tunnel.autoClose else Qt.Unchecked )

            self.txtName.setFocus()
            self.txtName.selectAll()
        else:
            self.txtName.setText("")
            self.txtHost.setText("localhost")
            self.txtLocalPort.setText("0")
            self.txtPort.setText("")
            self.txtSshPort.setText("22")
            self.txtUsername.setText("root")
            self.txtCommand.setText("")
            self.chkCloseOnTerm.setChecked(Qt.Unchecked)

    def currentTunnel(self):
        try:
            ti = self.listTunnels.currentRow()
            return None if ti < 0 else self._tunnels[ti]
        except IndexError:
            return None

    def on_txtName_textEdited(self, text):
        self.currentTunnel().name = text

    def on_txtHost_textEdited(self, text):
        self.currentTunnel().host = text

    def on_txtLocalPort_textEdited(self, text):
        self.currentTunnel().localPort = text

    def on_txtPort_textEdited(self, text):
        self.currentTunnel().port = text

    def on_txtSshPort_textEdited(self, text):
        self.currentTunnel().sshPort = text

    def on_txtUsername_textEdited(self, text):
        self.currentTunnel().username = text

    def on_txtCommand_textEdited(self, text):
        self.currentTunnel().command = text

    def on_chkCloseOnTerm_stateChanged(self, state):
        if self.currentTunnel() is not None:
            self.currentTunnel().autoClose = state == Qt.Checked

    @pyqtSignature("")
    def on_btnAddTunnel_clicked(self):
        tunnel = Tunnel(self)
        self._tunnels.append(tunnel)
        self.listTunnels.setCurrentItem(tunnel.item)
        self.tray.menu.insertAction(self.actionLastSep, tunnel.action)
        self.tray.menu.removeAction(self.actionNoTun)

    @pyqtSignature("")
    def on_btnDuplicateTunnel_clicked(self):
        cur = self.currentTunnel()
        if cur is not None:
            tunnel = Tunnel(self)
            tunnel.name = cur.name+" (copy)"
            tunnel.host = cur.host
            tunnel.localPort = cur.localPort
            tunnel.port = cur.port
            tunnel.username = cur.username
            tunnel.command = cur.command
            tunnel.autoClose = cur.autoClose
            self._tunnels.append(tunnel)
            self.listTunnels.setCurrentItem(tunnel.item)
            self.tray.menu.insertAction(self.actionLastSep, tunnel.action)

    @pyqtSignature("")
    def on_btnRemoveTunnel_clicked(self):
        tunnel = self.currentTunnel()
        if tunnel is not None:
            ti = self.listTunnels.currentRow()
            del self._tunnels[ti]
            self.listTunnels.setCurrentRow(0 if ti != 0 else 1)
            self.listTunnels.takeItem(ti)
            self.listTunnels.setCurrentItem(None, QItemSelectionModel.Clear)
            self.tray.menu.removeAction(tunnel.action)
            del tunnel

            if len(self._tunnels) == 0:
                self.tray.menu.insertAction(self.actionLastSep, self.actionNoTun)

    def updateTooltip(self):
        tuninfo = []
        for tunnel in self._tunnels:
            if tunnel.isOpen():
                tuninfo.append( "<div>{name}: {host}:{port} => {local}</div>".format(name=tunnel.name, host=tunnel.host, port=tunnel.port, local=tunnel.tunnelPort) )
        if tuninfo:
            tuninfo.insert(0, "<b>Active tunnels:</b>")
            self.tray.setActive()
        else:
            self.tray.setActive(False)
        self.tray.setToolTipSubTitle( "\n".join(tuninfo) )

    def activated(self):
        if self.visible:
            self.hide()
        else:
            self.show()

    def readSettings(self):
        if os.name == 'nt':
            settings = QSettings()
        else:
            settings = QSettings(os.path.expanduser("~/.iosshy.ini"), QSettings.IniFormat)
        for name in settings.childGroups():
            tunnel = Tunnel(self)
            tunnel.name = name
            tunnel.readSettings(settings)
            self._tunnels.append(tunnel)
            self.tray.menu.insertAction(self.actionLastSep, tunnel.action)
            self.tray.menu.removeAction(self.actionNoTun)

    def writeSettings(self):
        if os.name == 'nt':
            settings = QSettings()
        else:
            settings = QSettings(os.path.expanduser("~/.iosshy.ini"), QSettings.IniFormat)
        settings.clear()
        for tunnel in self._tunnels:
            tunnel.writeSettings(settings)

    def about(self):
        KAboutApplicationDialog(application.aboutData, self).exec_()
        if self.isHidden():
            self.show()
            self.hide()

    def quit(self):
        self.writeSettings()
        self._explicitQuit = True
        self.close()
Ejemplo n.º 54
0
class MainWindow(QMainWindow):
    groups = dict()
    typeQListWidgetHeader = 1000
    showHostsInGroups = False
    currentGroupName = None  # used to simple detect currently selected group to show menu

    def __init__(self):
        super(MainWindow, self).__init__()
        self.config = Config()
        self.db = Database(self.config.getConnectionString())

        cryptoKey = self.getCryptoKey()
        self.hosts = Hosts(self.db, cryptoKey)

        # menu used for each host
        self.hostMenu = QMenu()
        self.editAction = QAction(QIcon(':/ico/edit.svg'), "Edit", self.hostMenu)
        self.editAction.triggered.connect(self.editHost)
        self.hostMenu.addAction(self.editAction)

        # menu used for headers of groups
        self.groupsHeaderMenu = QMenu()
        self.editGroupAction = QAction(QIcon(':/ico/edit.svg'), "Edit group", self.groupsHeaderMenu)
        self.editGroupAction.triggered.connect(self.editGroup)
        self.deleteGroupAction = QAction(QIcon(':/ico/remove.svg'), "Delete group", self.groupsHeaderMenu)
        self.deleteGroupAction.triggered.connect(self.deleteGroup)
        self.groupsHeaderMenu.addAction(self.editGroupAction)
        self.groupsHeaderMenu.addAction(self.deleteGroupAction)

        self.duplicateAction = QAction(QIcon(':/ico/copy.svg'), "Duplicate", self.hostMenu)
        self.duplicateAction.triggered.connect(self.duplicateHost)
        self.hostMenu.addAction(self.duplicateAction)

        # todo: confirm for delete action
        self.deleteAction = QAction(QIcon(':/ico/remove.svg'), "Delete", self.hostMenu)
        self.deleteAction.triggered.connect(self.deleteHost)
        self.hostMenu.addAction(self.deleteAction)

        self.connectFramelessMenu = actions.generateScreenChoseMenu(self.hostMenu, self.connectFrameless,
                                                                    ':/ico/frameless.svg', "Connect frameless")
        self.hostMenu.addMenu(self.connectFramelessMenu)

        self.assignGroupAction = QAction("Assign group", self.hostMenu)
        self.assignGroupAction.triggered.connect(self.assignGroup)
        self.hostMenu.addAction(self.assignGroupAction)

        # setup main window
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # when top level changed, we changing dock title bar
        self.dockWidgetTileBar = DockWidgetTitleBar()
        self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)
        self.ui.hostsDock.topLevelChanged.connect(self.dockLevelChanged)

        # set global menu
        self.globalMenu = QMenu()
        self.globalMenu.addAction(QIcon(':/ico/add.svg'), 'Add host', self.addHost)

        # groups menu
        self.groupsMenu = QMenu("Groups")
        self.groupsMenu.aboutToShow.connect(self.setGroupsMenu)
        self.globalMenu.addMenu(self.groupsMenu)

        # disable menu indicator
        self.ui.menu.setStyleSheet("QPushButton::menu-indicator {image: none;}")
        self.positionMenu = QMenu("Dock position")
        self.positionMenu.addAction("Left", lambda: self.setDockPosition(Qt.LeftDockWidgetArea))
        self.positionMenu.addAction("Right", lambda: self.setDockPosition(Qt.RightDockWidgetArea))
        self.positionMenu.addAction("Float", self.setDockFloat)
        self.globalMenu.addMenu(self.positionMenu)
        self.globalMenu.addAction('Change tray icon visibility', self.changeTrayIconVisibility)
        self.globalMenu.addAction('Settings', self.showSettings)
        self.globalMenu.addAction('Quit', self.close)
        self.ui.menu.setMenu(self.globalMenu)

        # set events on hosts list
        self.ui.hostsList.itemDoubleClicked.connect(self.slotConnectHost)
        self.ui.hostsList.itemClicked.connect(self.slotShowHost)
        self.ui.hostsList.customContextMenuRequested.connect(self.slotShowHostContextMenu)

        # set tab widget
        self.tabWidget = MyTabWidget()
        self.setCentralWidget(self.tabWidget)
        self.tabWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tabWidget.customContextMenuRequested.connect(self.showCentralWidgetContextMenu)

        # set tray icon
        self.tray = QSystemTrayIcon(QIcon(":/ico/myrdp.svg"))
        self.tray.activated.connect(self.trayActivated)

        self.trayMenu = QMenu()
        self.trayMenu.addAction("Hide tray icon", self.changeTrayIconVisibility)
        self.connectHostMenuTray = ConnectHostMenu(self.hosts)
        self.connectHostMenuTray.triggered.connect(self.connectHostFromTrayMenu)
        self.trayMenu.addMenu(self.connectHostMenuTray)
        self.trayMenu.addAction("Quit", self.close)

        self.tray.setContextMenu(self.trayMenu)
        self.restoreSettings()
        # host list
        self.ui.filter.textChanged.connect(self.setHostList)
        self.setHostList()

    def getCryptoKey(self, passphrase=None):
        try:
            return self.config.getPrivateKey(passphrase)
        except ValueError:
            passwordDialog = PasswordDialog()
            retCode = passwordDialog.exec_()
            if retCode == QtGui.QDialog.Accepted:
                return self.getCryptoKey(passwordDialog.getPassword())
            else:
                raise SystemError("Password required")

    def showSettings(self):
        settingsWidget = self.findChild(QWidget, "settings")
        if settingsWidget is None:
            self.settingsWidget = SettingsPage()
            self.settingsWidget.setObjectName("settings")
            self.tabWidget.insertTab(0, self.settingsWidget, QIcon(":/ico/settings.svg"), 'Settings')

        index = self.tabWidget.indexOf(self.settingsWidget)
        self.tabWidget.setCurrentIndex(index)

    def connectHostFromMenu(self, action):
        self.connectHost(str(action.text()))

    def connectHostFromTrayMenu(self, action):
        tabPage = self.connectHost(str(action.text()))
        if not self.isVisible():
            self.tabWidget.setDetached(True, tabPage)

    def trayActivated(self, reason):
        if reason != QSystemTrayIcon.Trigger:
            return
        if self.isVisible():
            self.hide()
        else:
            self.show()
            self.activateWindow()

    def changeTrayIconVisibility(self):
        if self.tray.isVisible():
            self.tray.hide()
            if not self.isVisible():
                self.show()
        else:
            self.tray.show()

    def refreshGroups(self):
        groupList = self.hosts.getGroupsList()
        for group in groupList:
            if group not in self.groups:
                # add new groups as visible
                self.groups[group] = True

        # remove not existing groups
        keysToDelete = set(self.groups.keys()) - set(groupList)
        for key in keysToDelete:
            self.groups.pop(key)

    def assignGroup(self):
        groups = self.hosts.getGroupsList()
        assignGroupDialog = AssignGroupDialog(groups)
        groupToAssign = assignGroupDialog.assign()
        if groupToAssign is not False:  # None could be used to unassign the group
            groupToAssign = groupToAssign if groupToAssign else None
            for hostName in self.getSelectedHosts():
                self.hosts.assignGroup(hostName, groupToAssign)
            self.db.tryCommit()
            self.setHostList()

    def setGroupsMenu(self):
        self.groupsMenu.clear()
        addGroupAction = self.groupsMenu.addAction('Add group')
        addGroupAction.triggered.connect(self.addGroup)

        deleteGroupAction = self.groupsMenu.addAction('Delete group')
        deleteGroupAction.triggered.connect(self.showDeleteGroupDialog)

        showHostsInGroupsAction = self.groupsMenu.addAction('Show host list in groups')
        showHostsInGroupsAction.triggered.connect(self.changeHostListView)
        showHostsInGroupsAction.setCheckable(True)
        showHostsInGroupsAction.setChecked(self.showHostsInGroups)

        self.groupsMenu.addSeparator()
        for group, checked in self.groups.items():
            action = QAction(group, self.groupsMenu)
            action.setCheckable(True)
            action.setChecked(checked)
            action.triggered.connect(self.groupsVisibilityChanged)
            self.groupsMenu.addAction(action)

    def addGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.add()
        self._processHostSubmit(resp)

    def groupsVisibilityChanged(self, checked):
        currentGroup = str(self.sender().text())
        self.groups[currentGroup] = checked
        self.setHostList()

    def setDockPosition(self, dockWidgetArea):
        if self.ui.hostsDock.isFloating():
            self.ui.hostsDock.setFloating(False)
        self.addDockWidget(dockWidgetArea, self.ui.hostsDock)

    def setDockFloat(self):
        if self.ui.hostsDock.isFloating():
            return
        # default title bar must be set before is float because sometimes window make strange crash
        self.ui.hostsDock.setTitleBarWidget(None)
        self.ui.hostsDock.setFloating(True)

    def dockLevelChanged(self, isFloating):
        if isFloating:
            # changing title bar widget if is not none, probably true will be only once on start with saved float state
            if self.ui.hostsDock.titleBarWidget():
                self.ui.hostsDock.setTitleBarWidget(None)
        else:
            self.ui.hostsDock.setTitleBarWidget(self.dockWidgetTileBar)

    def showFramelessWidget(self):
        self.t.show()
        self.t.setGeometry(self.frameGeometry())

    def getCurrentHostListItemName(self):
        return self.ui.hostsList.currentItem().text()

    def getSelectedHosts(self):
        return [host.text() for host in self.ui.hostsList.selectedItems()]

    def findHostItemByName(self, name):
        result = self.ui.hostsList.findItems(name, Qt.MatchExactly)
        resultLen = len(result)
        if resultLen != 1:  # should be only one host
            logger.error("Host not found. Got %d results" % resultLen)
        return result[0]

    def showCentralWidgetContextMenu(self, pos):
        menu = QMenu()
        title = self.ui.hostsDock.windowTitle()

        hostsDockAction = menu.addAction(title)
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.ui.hostsDock.isVisible())
        hostsDockAction.triggered.connect(self.changeHostsDockWidgetVisibility)

        hostsDockAction = menu.addAction("Tray icon")
        hostsDockAction.setCheckable(True)
        hostsDockAction.setChecked(self.tray.isVisible())
        hostsDockAction.triggered.connect(self.changeTrayIconVisibility)

        connectHostMenuTray = ConnectHostMenu(self.hosts, "Connect")
        connectHostMenuTray.triggered.connect(self.connectHostFromMenu)
        menu.addMenu(connectHostMenuTray)

        menu.exec_(self.tabWidget.mapToGlobal(pos))

    def changeHostListView(self, checked):
        self.showHostsInGroups = checked
        self.setHostList()

    def changeHostsDockWidgetVisibility(self):
        isVisible = self.ui.hostsDock.isVisible()
        self.ui.hostsDock.setVisible(not isVisible)

    def isHostListHeader(self, item):
        if not item or item.type() == self.typeQListWidgetHeader:
            return True
        return False

    def slotShowHostContextMenu(self, pos):
        def changeMenusVisibility(isEnabled):
            self.connectFramelessMenu.setEnabled(isEnabled)
            self.editAction.setEnabled(isEnabled)
            self.duplicateAction.setEnabled(isEnabled)

        # ignore context menu for group headers
        item = self.ui.hostsList.itemAt(pos)

        if self.isHostListHeader(item):
            item = self.ui.hostsList.itemAt(pos)
            widgetItem = self.ui.hostsList.itemWidget(item)
            if widgetItem:
                self.currentGroupName = widgetItem.text()  # yea I'm so dirty
                if self.currentGroupName != unassignedGroupName:
                    self.groupsHeaderMenu.exec_(self.ui.hostsList.mapToGlobal(pos))
            return

        if len(self.ui.hostsList.selectedItems()) == 1:  # single menu
            changeMenusVisibility(True)
        else:
            changeMenusVisibility(False)

        self.hostMenu.exec_(self.ui.hostsList.mapToGlobal(pos))

    def _processHostSubmit(self, resp):
        if resp["code"]:
            self.setHostList()
        hostName = resp.get("name")
        if hostName:
            hostItem = self.findHostItemByName(hostName)
            self.slotConnectHost(hostItem)

    def addHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        self._processHostSubmit(hostDialog.add())

    def editHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.edit(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def editGroup(self):
        groupConfigDialog = GroupConfigDialog(self.hosts.groups)
        resp = groupConfigDialog.edit(self.currentGroupName)
        self._processHostSubmit(resp)

    def deleteGroup(self):
        retCode = self.showOkCancelMessageBox("Do you want to remove selected group? All assigned hosts "
                                              "to this group will be unassigned.",
                                              "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        self.hosts.deleteGroup(self.currentGroupName)
        self.setHostList()

    def showDeleteGroupDialog(self):
        deleteGroupDialog = DeleteGroupDialog(self.hosts)
        deleteGroupDialog.deleteGroup()
        self.setHostList()

    def duplicateHost(self):
        hostDialog = HostConfigDialog(self.hosts)
        resp = hostDialog.duplicate(self.getCurrentHostListItemName())
        self._processHostSubmit(resp)

    def deleteHost(self):
        retCode = self.showOkCancelMessageBox("Do you want to remove selected hosts?",
                                              "Confirmation")
        if retCode == QMessageBox.Cancel:
            return

        for host in self.getSelectedHosts():
            self.hosts.delete(host)
        self.setHostList()

    def connectFrameless(self, screenIndex=None):
        self.connectHost(self.getCurrentHostListItemName(), frameless=True, screenIndex=screenIndex)

    # Fix to release keyboard from QX11EmbedContainer, when we leave widget through wm border
    def leaveEvent(self, event):
        keyG = QWidget.keyboardGrabber()
        if keyG is not None:
            keyG.releaseKeyboard()
        event.accept()  # needed?

    def setHostList(self):
        """ set hosts list in list view """
        self.ui.hostsList.clear()
        self.refreshGroups()
        hostFilter = self.ui.filter.text()
        if self.showHostsInGroups:
            self.showHostListInGroups(hostFilter)
        else:
            self.showHostList(hostFilter)

    def showHostList(self, hostFilter):
        groupFilter = [group for group, visibility in self.groups.items() if visibility]
        hosts = self.hosts.getHostsListByHostNameAndGroup(hostFilter, groupFilter)
        self.ui.hostsList.addItems(hosts)

    def showHostListInGroups(self, hostFilter):
        hosts = self.hosts.getGroupedHostNames(hostFilter)
        for group, hostsList in hosts.items():
            if self.groups.get(group, True):
                if group is None:
                    group = unassignedGroupName
                groupHeader = QtGui.QListWidgetItem(type=self.typeQListWidgetHeader)
                groupLabel = QtGui.QLabel(str(group))
                groupLabel.setProperty('class', 'group-title')
                self.ui.hostsList.addItem(groupHeader)
                self.ui.hostsList.setItemWidget(groupHeader, groupLabel)
                self.ui.hostsList.addItems(hostsList)

    def slotShowHost(self, item):
        # on one click we activating tab and showing options
        self.tabWidget.activateTab(item)

    def slotConnectHost(self, item):
        if self.isHostListHeader(item):
            return
        self.connectHost(str(item.text()))

    def connectHost(self, hostId, frameless=False, screenIndex=None):
        hostId = str(hostId)  # sometimes hostId comes as QString
        tabPage = self.tabWidget.createTab(hostId)
        tabPage.reconnectionNeeded.connect(self.connectHost)

        if frameless:
            self.tabWidget.detachFrameless(tabPage, screenIndex)

        try:
            execCmd, opts = self.getCmd(tabPage, hostId)
        except LookupError:
            logger.error("Host {} not found.".format(hostId))
            return

        ProcessManager.start(hostId, tabPage, execCmd, opts)
        return tabPage

    def getCmd(self, tabPage, hostName):
        host = self.hosts.get(hostName)

        # set tabPage widget
        width, height = tabPage.setSizeAndGetCurrent()
        # 1et widget winId to embed rdesktop
        winId = tabPage.x11.winId()

        # set remote desktop client, at this time works only with freerdp
        remoteClientType, remoteClientOptions = self.config.getRdpClient()
        remoteClient = ClientFactory(remoteClientType, **remoteClientOptions)
        remoteClient.setWindowParameters(winId, width, height)
        remoteClient.setUserAndPassword(host.user, host.password)
        remoteClient.setAddress(host.address)
        return remoteClient.getComposedCommand()

    def saveSettings(self):
        self.config.setValue("geometry", self.saveGeometry())
        self.config.setValue("windowState", self.saveState())
        self.config.setValue('trayIconVisibility', self.tray.isVisible())
        self.config.setValue('mainWindowVisibility', self.isVisible())
        self.config.setValue('groups', self.groups)
        self.config.setValue('showHostsInGroups', self.showHostsInGroups)

    def restoreSettings(self):
        try:
            self.restoreGeometry(self.config.getValue("geometry"))
            self.restoreState(self.config.getValue("windowState"))
        except Exception:
            logger.info("No settings to restore")

        # restore tray icon state
        trayIconVisibility = self.config.getBooleanValue('trayIconVisibility', True)
        self.tray.setVisible(trayIconVisibility)
        self.showHostsInGroups = self.config.getBooleanValue('showHostsInGroups', False)
        if self.tray.isVisible():
            mainWindowVisibility = self.config.getBooleanValue('mainWindowVisibility', True)
            self.setVisible(mainWindowVisibility)
        else:  # it tray icon is not visible, always show main window
            self.show()

        self.groups = {str(k): v for k, v in self.config.getValue('groups', {}).items()}

    def closeEvent(self, event):
        if not ProcessManager.hasActiveProcess:
            self.saveSettings()
            QCoreApplication.exit()
            return

        ret = self.showOkCancelMessageBox("Are you sure do you want to quit?",
                                          "Exit confirmation")
        if ret == QMessageBox.Cancel:
            event.ignore()
            return

        self.saveSettings()
        ProcessManager.killemall()
        event.accept()
        QCoreApplication.exit()

    def showOkCancelMessageBox(self, messageBoxText, windowTitle):
        msgBox = QMessageBox(self, text=messageBoxText)
        msgBox.setWindowTitle(windowTitle)
        msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        msgBox.setIcon(QMessageBox.Question)
        return msgBox.exec_()
Ejemplo n.º 55
0
class OWPaintData(widget.OWWidget):
    TOOLS = [
        ("Brush", "Create multiple instances", AirBrushTool, _i("brush.svg")),
        ("Put", "Put individual instances", PutInstanceTool, _i("put.svg")),
        ("Select", "Select and move instances", SelectTool,
         _i("select-transparent_42px.png")),
        ("Jitter", "Jitter instances", JitterTool, _i("jitter.svg")),
        ("Magnet", "Attract multiple instances", MagnetTool, _i("magnet.svg")),
        ("Clear", "Clear the plot", ClearTool,
         _i("../../../icons/Dlg_clear.png"))
    ]

    name = "Paint Data"
    description = "Create data by painting data points in the plane."
    long_description = ""
    icon = "icons/PaintData.svg"
    priority = 10
    keywords = ["data", "paint", "create"]

    outputs = [("Data", Orange.data.Table)]
    inputs = [("Data", Orange.data.Table, "set_data")]

    autocommit = Setting(False)
    table_name = Setting("Painted data")
    attr1 = Setting("x")
    attr2 = Setting("y")
    hasAttr2 = Setting(True)

    brushRadius = Setting(75)
    density = Setting(7)

    want_graph = True

    def __init__(self):
        super().__init__()

        self.data = None
        self.current_tool = None
        self._selected_indices = None
        self._scatter_item = None

        self.labels = ["C1", "C2"]

        self.undo_stack = QtGui.QUndoStack(self)

        self.class_model = ColoredListModel(self.labels,
                                            self,
                                            flags=QtCore.Qt.ItemIsSelectable
                                            | QtCore.Qt.ItemIsEnabled
                                            | QtCore.Qt.ItemIsEditable)

        self.class_model.dataChanged.connect(self._class_value_changed)
        self.class_model.rowsInserted.connect(self._class_count_changed)
        self.class_model.rowsRemoved.connect(self._class_count_changed)

        self.data = np.zeros((0, 3))
        self.colors = colorpalette.ColorPaletteGenerator(
            len(colorpalette.DefaultRGBColors))
        self.tools_cache = {}

        self._init_ui()

    def _init_ui(self):
        namesBox = gui.widgetBox(self.controlArea, "Names")

        hbox = gui.widgetBox(namesBox,
                             orientation='horizontal',
                             margin=0,
                             spacing=0)
        gui.lineEdit(hbox,
                     self,
                     "attr1",
                     "Variable X ",
                     controlWidth=80,
                     orientation="horizontal",
                     enterPlaceholder=True,
                     callback=self._attr_name_changed)
        gui.separator(hbox, 18)
        hbox = gui.widgetBox(namesBox,
                             orientation='horizontal',
                             margin=0,
                             spacing=0)
        attr2 = gui.lineEdit(hbox,
                             self,
                             "attr2",
                             "Variable Y ",
                             controlWidth=80,
                             orientation="horizontal",
                             enterPlaceholder=True,
                             callback=self._attr_name_changed)
        gui.checkBox(hbox,
                     self,
                     "hasAttr2",
                     '',
                     disables=attr2,
                     labelWidth=0,
                     callback=self.set_dimensions)
        gui.separator(namesBox)

        gui.widgetLabel(namesBox, "Labels")
        self.classValuesView = listView = QListView(
            selectionMode=QListView.SingleSelection,
            sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Maximum))
        listView.setModel(self.class_model)
        itemmodels.select_row(listView, 0)
        namesBox.layout().addWidget(listView)

        self.addClassLabel = QAction("+",
                                     self,
                                     toolTip="Add new class label",
                                     triggered=self.add_new_class_label)

        self.removeClassLabel = QAction(
            unicodedata.lookup("MINUS SIGN"),
            self,
            toolTip="Remove selected class label",
            triggered=self.remove_selected_class_label)

        actionsWidget = itemmodels.ModelActionsWidget(
            [self.addClassLabel, self.removeClassLabel], self)
        actionsWidget.layout().addStretch(10)
        actionsWidget.layout().setSpacing(1)
        namesBox.layout().addWidget(actionsWidget)

        tBox = gui.widgetBox(self.controlArea, "Tools", addSpace=True)
        buttonBox = gui.widgetBox(tBox, orientation="horizontal")
        toolsBox = gui.widgetBox(buttonBox, orientation=QtGui.QGridLayout())

        self.toolActions = QtGui.QActionGroup(self)
        self.toolActions.setExclusive(True)
        self.toolButtons = []

        for i, (name, tooltip, tool, icon) in enumerate(self.TOOLS):
            action = QAction(
                name,
                self,
                toolTip=tooltip,
                checkable=tool.checkable,
                icon=QIcon(icon),
            )
            action.triggered.connect(partial(self.set_current_tool, tool))

            button = QtGui.QToolButton(
                iconSize=QSize(24, 24),
                toolButtonStyle=Qt.ToolButtonTextUnderIcon,
                sizePolicy=QSizePolicy(QSizePolicy.MinimumExpanding,
                                       QSizePolicy.Fixed))
            button.setDefaultAction(action)
            self.toolButtons.append((button, tool))

            toolsBox.layout().addWidget(button, i / 3, i % 3)
            self.toolActions.addAction(action)

        for column in range(3):
            toolsBox.layout().setColumnMinimumWidth(column, 10)
            toolsBox.layout().setColumnStretch(column, 1)

        undo = self.undo_stack.createUndoAction(self)
        redo = self.undo_stack.createRedoAction(self)

        undo.setShortcut(QtGui.QKeySequence.Undo)
        redo.setShortcut(QtGui.QKeySequence.Redo)

        self.addActions([undo, redo])

        gui.separator(tBox)
        indBox = gui.indentedBox(tBox, sep=8)
        form = QtGui.QFormLayout(
            formAlignment=Qt.AlignLeft,
            labelAlignment=Qt.AlignLeft,
            fieldGrowthPolicy=QtGui.QFormLayout.AllNonFixedFieldsGrow)
        indBox.layout().addLayout(form)
        slider = gui.hSlider(indBox,
                             self,
                             "brushRadius",
                             minValue=1,
                             maxValue=100,
                             createLabel=False)
        form.addRow("Radius", slider)

        slider = gui.hSlider(indBox,
                             self,
                             "density",
                             None,
                             minValue=1,
                             maxValue=100,
                             createLabel=False)

        form.addRow("Intensity", slider)

        gui.rubber(self.controlArea)
        gui.auto_commit(self.controlArea, self, "autocommit", "Send",
                        "Send on change")

        # main area GUI
        viewbox = PaintViewBox(enableMouse=False)
        self.plotview = pg.PlotWidget(background="w", viewBox=viewbox)
        self.plotview.sizeHint = lambda: QSize(
            200, 100)  # Minimum size for 1-d painting
        self.plot = self.plotview.getPlotItem()

        axis_color = self.palette().color(QtGui.QPalette.Text)
        axis_pen = QtGui.QPen(axis_color)

        tickfont = QtGui.QFont(self.font())
        tickfont.setPixelSize(max(int(tickfont.pixelSize() * 2 // 3), 11))

        axis = self.plot.getAxis("bottom")
        axis.setLabel(self.attr1)
        axis.setPen(axis_pen)
        axis.setTickFont(tickfont)

        axis = self.plot.getAxis("left")
        axis.setLabel(self.attr2)
        axis.setPen(axis_pen)
        axis.setTickFont(tickfont)
        if not self.hasAttr2:
            self.plot.hideAxis('left')

        self.plot.hideButtons()
        self.plot.setXRange(0, 1, padding=0.01)

        self.mainArea.layout().addWidget(self.plotview)

        # enable brush tool
        self.toolActions.actions()[0].setChecked(True)
        self.set_current_tool(self.TOOLS[0][2])
        self.graphButton.clicked.connect(self.save_graph)

        self.set_dimensions()

    def set_dimensions(self):
        if self.hasAttr2:
            self.plot.setYRange(0, 1, padding=0.01)
            self.plot.showAxis('left')
            self.plotview.setSizePolicy(QSizePolicy.Ignored,
                                        QSizePolicy.Minimum)
        else:
            self.plot.setYRange(-.5, .5, padding=0.01)
            self.plot.hideAxis('left')
            self.plotview.setSizePolicy(QSizePolicy.Ignored,
                                        QSizePolicy.Maximum)
        self._replot()
        for button, tool in self.toolButtons:
            if tool.only2d:
                button.setDisabled(not self.hasAttr2)

    def set_data(self, data):
        if data:
            try:
                y = next(cls for cls in data.domain.class_vars
                         if cls.is_discrete)
            except StopIteration:
                y = np.ones(X.shape[0])
            else:
                y = data[:, y].Y
            while len(self.class_model) < np.unique(y).size:
                self.add_new_class_label(undoable=False)

            X = np.array([scale(vals) for vals in data.X[:, :2].T]).T
            self.data = np.column_stack((X, y))
            self._replot()

    def add_new_class_label(self, undoable=True):

        newlabel = next(label for label in namegen('C', 1)
                        if label not in self.class_model)

        command = SimpleUndoCommand(lambda: self.class_model.append(newlabel),
                                    lambda: self.class_model.__delitem__(-1))
        if undoable:
            self.undo_stack.push(command)
        else:
            command.redo()

    def remove_selected_class_label(self):
        index = self.selected_class_label()

        if index is None:
            return

        label = self.class_model[index]
        mask = self.data[:, 2] == index
        move_mask = self.data[~mask][:, 2] > index

        self.undo_stack.beginMacro("Delete class label")
        self.undo_stack.push(UndoCommand(DeleteIndices(mask), self))
        self.undo_stack.push(UndoCommand(Move((move_mask, 2), -1), self))
        self.undo_stack.push(
            SimpleUndoCommand(lambda: self.class_model.__delitem__(index),
                              lambda: self.class_model.insert(index, label)))
        self.undo_stack.endMacro()

        newindex = min(max(index - 1, 0), len(self.class_model) - 1)
        itemmodels.select_row(self.classValuesView, newindex)

    def _class_count_changed(self):
        self.labels = list(self.class_model)
        self.removeClassLabel.setEnabled(len(self.class_model) > 1)
        self.addClassLabel.setEnabled(
            len(self.class_model) < self.colors.number_of_colors)
        if self.selected_class_label() is None:
            itemmodels.select_row(self.classValuesView, 0)

    def _class_value_changed(self, index, _):
        index = index.row()
        newvalue = self.class_model[index]
        oldvalue = self.labels[index]
        if newvalue != oldvalue:
            self.labels[index] = newvalue


#             command = Command(
#                 lambda: self.class_model.__setitem__(index, newvalue),
#                 lambda: self.class_model.__setitem__(index, oldvalue),
#             )
#             self.undo_stack.push(command)

    def selected_class_label(self):
        rows = self.classValuesView.selectedIndexes()
        if rows:
            return rows[0].row()
        else:
            return None

    def set_current_tool(self, tool):
        prev_tool = self.current_tool.__class__

        if self.current_tool is not None:
            self.current_tool.deactivate()
            self.current_tool.editingStarted.disconnect(
                self._on_editing_started)
            self.current_tool.editingFinished.disconnect(
                self._on_editing_finished)
            self.current_tool = None
            self.plot.getViewBox().tool = None

        if tool not in self.tools_cache:
            newtool = tool(self, self.plot)
            newtool.editingFinished.connect(self.invalidate)
            self.tools_cache[tool] = newtool
            newtool.issueCommand.connect(self._add_command)

        self._selected_region = QRectF()
        self.current_tool = tool = self.tools_cache[tool]
        self.plot.getViewBox().tool = tool
        tool.editingStarted.connect(self._on_editing_started)
        tool.editingFinished.connect(self._on_editing_finished)
        tool.activate()

        if not tool.checkable:
            self.set_current_tool(prev_tool)

    def _on_editing_started(self):
        self.undo_stack.beginMacro("macro")

    def _on_editing_finished(self):
        self.undo_stack.endMacro()

    def execute(self, command):
        if isinstance(command, (Append, DeleteIndices, Insert, Move)):
            if isinstance(command, (DeleteIndices, Insert)):
                self._selected_indices = None

                if isinstance(self.current_tool, SelectTool):
                    self.current_tool._reset()

            self.data, undo = transform(command, self.data)
            self._replot()
            return undo
        else:
            assert False, "Non normalized command"

    def _add_command(self, cmd):
        name = "Name"

        if (not self.hasAttr2
                and isinstance(cmd, (Move, MoveSelection, Jitter, Magnet))):
            # tool only supported if both x and y are enabled
            return

        if isinstance(cmd, Append):
            cls = self.selected_class_label()
            points = np.array([(p.x(), p.y() if self.hasAttr2 else 0, cls)
                               for p in cmd.points])
            self.undo_stack.push(UndoCommand(Append(points), self, text=name))
        elif isinstance(cmd, Move):
            self.undo_stack.push(UndoCommand(cmd, self, text=name))
        elif isinstance(cmd, SelectRegion):
            indices = [
                i for i, (x, y) in enumerate(self.data[:, :2])
                if cmd.region.contains(QPointF(x, y))
            ]
            indices = np.array(indices, dtype=int)
            self._selected_indices = indices
        elif isinstance(cmd, DeleteSelection):
            indices = self._selected_indices
            if indices is not None and indices.size:
                self.undo_stack.push(
                    UndoCommand(DeleteIndices(indices), self, text="Delete"))
        elif isinstance(cmd, MoveSelection):
            indices = self._selected_indices
            if indices is not None and indices.size:
                self.undo_stack.push(
                    UndoCommand(Move((self._selected_indices, slice(0, 2)),
                                     np.array([cmd.delta.x(),
                                               cmd.delta.y()])),
                                self,
                                text="Move"))
        elif isinstance(cmd, DeleteIndices):
            self.undo_stack.push(UndoCommand(cmd, self, text="Delete"))
        elif isinstance(cmd, Insert):
            self.undo_stack.push(UndoCommand(cmd, self))
        elif isinstance(cmd, AirBrush):
            data = create_data(cmd.pos.x(), cmd.pos.y(),
                               self.brushRadius / 1000, 1 + self.density / 20,
                               cmd.rstate)
            self._add_command(Append([QPointF(*p) for p in zip(*data.T)]))
        elif isinstance(cmd, Jitter):
            point = np.array([cmd.pos.x(), cmd.pos.y()])
            delta = -apply_jitter(self.data[:, :2], point,
                                  self.density / 100.0, 0, cmd.rstate)
            self._add_command(Move((..., slice(0, 2)), delta))
        elif isinstance(cmd, Magnet):
            point = np.array([cmd.pos.x(), cmd.pos.y()])
            delta = -apply_attractor(self.data[:, :2], point,
                                     self.density / 100.0, 0)
            self._add_command(Move((..., slice(0, 2)), delta))
        else:
            assert False, "unreachable"

    def _replot(self):
        def pen(color):
            pen = QPen(color, 1)
            pen.setCosmetic(True)
            return pen

        if self._scatter_item is not None:
            self.plot.removeItem(self._scatter_item)
            self._scatter_item = None

        nclasses = len(self.class_model)
        pens = [pen(self.colors[i]) for i in range(nclasses)]

        self._scatter_item = pg.ScatterPlotItem(
            self.data[:, 0],
            self.data[:, 1] if self.hasAttr2 else np.zeros(self.data.shape[0]),
            symbol="+",
            pen=[pens[int(ci)] for ci in self.data[:, 2]])

        self.plot.addItem(self._scatter_item)

    def _attr_name_changed(self):
        self.plot.getAxis("bottom").setLabel(self.attr1)
        self.plot.getAxis("left").setLabel(self.attr2)
        self.invalidate()

    def invalidate(self):
        self.commit()

    def commit(self):
        if self.hasAttr2:
            X, Y = self.data[:, :2], self.data[:, 2]
            attrs = (Orange.data.ContinuousVariable(self.attr1),
                     Orange.data.ContinuousVariable(self.attr2))
        else:
            X, Y = self.data[:, np.newaxis, 0], self.data[:, 2]
            attrs = (Orange.data.ContinuousVariable(self.attr1), )
        if len(np.unique(Y)) >= 2:
            domain = Orange.data.Domain(
                attrs,
                Orange.data.DiscreteVariable("Class",
                                             values=list(self.class_model)))
            data = Orange.data.Table.from_numpy(domain, X, Y)
        else:
            domain = Orange.data.Domain(attrs)
            data = Orange.data.Table.from_numpy(domain, X)
        data.name = self.table_name
        self.send("Data", data)

    def sizeHint(self):
        sh = super().sizeHint()
        return sh.expandedTo(QSize(1200, 800))

    def onDeleteWidget(self):
        self.plot.clear()

    def save_graph(self):
        from Orange.widgets.data.owsave import OWSave

        save_img = OWSave(data=self.plotview.plotItem,
                          file_formats=FileFormat.img_writers)
        save_img.exec_()

    def send_report(self):
        if self.data is None:
            return
        settings = []
        if self.attr1 != "x" or self.attr2 != "y":
            settings += [("Axis x", self.attr1), ("Axis y", self.attr2)]
        settings += [("Number of points", len(self.data))]
        self.report_items("Painted data", settings)
        self.report_plot(self.plot)
Ejemplo n.º 56
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

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

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

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

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

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

        We implement this ourselves since we do not inherit QObject.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.add_action(self.action_add_layers)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if test_package == '':
            test_package = default_package

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

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

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

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

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

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

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

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

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

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

        # Do not show by default
        show_message = False

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # 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 show_definitions(self):
        """Show InaSAFE Definitions (a report showing all key metadata)."""
        from safe.gui.tools.help_dialog import HelpDialog
        from safe.gui.tools.help import definitions_help
        dialog = HelpDialog(self.iface.mainWindow(),
                            definitions_help.definitions_help())
        dialog.show()  # non modal

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def shortcut_f7(self):
        """Executed when user press F7 - will show the shakemap importer."""
        self.show_shakemap_importer()
Ejemplo n.º 57
0
    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        """Add a toolbar icon to the toolbar.

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

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

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

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

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

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

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

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

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

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

        # Create the dialog (after translation) and keep reference
        self.dlg = BeyondTheBorderDialog()

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToVectorMenu(
                self.menu,
                action)
            if ProcessingConfig.getSetting('ACTIVATE_R'):
                # RscriptFolder = processing.algs.r.RUtils.RUtils.RScriptsFolder()
                RscriptFolder = ProcessingConfig.getSetting('R_SCRIPTS_FOLDER')
                shutil.copyfile(self.plugin_dir+"/rscript/btb_LissageGrille.rsx", RscriptFolder+"/btb_LissageGrille.rsx")
                shutil.copyfile(self.plugin_dir+"/rscript/btb_Schematisation_de_carreaux.rsx", RscriptFolder+"/btb_Schematisation_de_carreaux.rsx")
                shutil.copyfile(self.plugin_dir+"/rscript/btb_Schematisation_de_carreaux.rsx.help", RscriptFolder+"/btb_Schematisation_de_carreaux.rsx.help")

        self.actions.append(action)

        return action
Ejemplo n.º 58
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_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_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()
Ejemplo n.º 59
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()

    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:
           no exceptions explicitly raised.
        """
        myOverrideFlag = QSettings().value('locale/overrideFlag',
                                           QVariant(False)).toBool()
        myLocaleName = None
        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 TranslationLoadException(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)

    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.png'),
                                  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/keywords.png'),
            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/reload.png'),
                                       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/options.png'),
                                     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/functions-table.png'),
            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 dockwidget and tabify it with the legend
        #--------------------------------------
        self.dockWidget = Dock(self.iface)
        self.iface.addDockWidget(Qt.LeftDockWidgetArea, 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.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 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 keywords editor.

        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 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.showImpactFunctionsDoc()
Ejemplo n.º 60
0
class BaseSTRNode(object):
    """
    Base class for all STR nodes.
    """
    def __init__(self,
                 data,
                 parent=None,
                 view=None,
                 parentWidget=None,
                 isChild=False,
                 styleIfChild=True,
                 rootDepthForHash=1,
                 model=None):
        self._data = data
        self._children = []
        self._parent = parent
        self._rootNodeHash = ""
        self._view = view
        self._parentWidget = parentWidget
        self._model = model

        if parent is not None:
            parent.addChild(self)
            #Inherit view from parent
            self._view = parent.treeView()
            self._parentWidget = parent.parentWidget()
        '''
        Set the hash of the node that will be taken as the root parent node.
        In this case it will be level one.
        Level zero will not have any hash specified (just be an empty string).
        '''
        if self.depth() == rootDepthForHash:
            self._rootNodeHash = gen_random_string()
        elif self.depth() > rootDepthForHash:
            self._rootNodeHash = self._parent.rootHash()

        #Separator for child text
        self.separator = ": "

        if isChild:
            if styleIfChild:
                self._styleIfChild = True
        else:
            self._styleIfChild = False

        #Default actions that will be most commonly used by the nodes with data management capabilities
        self.editAction = QAction(
            EDIT_ICON, QApplication.translate("BaseSTRNode", "Edit..."), None)
        self.deleteAction = QAction(
            DELETE_ICON, QApplication.translate("BaseSTRNode", "Delete"), None)

        self._expand_action = QAction(
            QApplication.translate("BaseSTRNode", "Expand"),
            self._parentWidget)
        self._collapse_action = QAction(
            QApplication.translate("BaseSTRNode", "Collapse"),
            self._parentWidget)

    def addChild(self, child):
        '''
        Add child to the parent node.
        '''
        self._children.append(child)

    def insertChild(self, position, child):
        '''
        Append child at the specified position in the list
        '''
        if position < 0 or position > len(self._children):
            return False

        self._children.insert(position, child)
        child._parent = self

        return True

    def removeChild(self, position):
        '''
        Remove child at the specified position.
        '''
        if position < 0 or position >= len(self._children):
            return False

        child = self._children.pop(position)
        child._parent = None

        return True

    def clear(self):
        '''
        Removes all children in the node.
        '''
        try:
            del self._children[:]
            return True
        except:
            return False

    def child(self, row):
        '''
        Get the child node at the specified row.
        '''
        if row < 0 or row >= len(self._children):
            return None

        return self._children[row]

    def childCount(self):
        '''
        Number of children node with the current node as the parent.
        '''
        return len(self._children)

    def children(self):
        '''
        Returns all the node's children as a list.
        '''
        return self._children

    def hasParent(self):
        '''
        True if the node has a parent. Otherwise returns False.
        '''
        return True if self._parent else False

    def parent(self):
        '''
        The parent of this node.
        '''
        return self._parent

    def treeView(self):
        '''
        Returns the tree view that contains this node.
        '''
        return self._view

    def parentWidget(self):
        '''
        Returns the main widget that displays the social tenure relationship information.
        '''
        return self._parentWidget

    def row(self):
        '''
        Return the position of this node in the parent container.
        '''
        if self._parent:
            return self.parent()._children.index(self)

        return 0

    def icon(self):
        '''
        Return a QIcon for decorating the node.
        To be implemented by subclasses.
        '''
        return None

    def id(self):
        '''
        Returns the ID of the model it represents.
        '''
        return -1

    def depth(self):
        '''
        Returns the depth/hierarchy of this node.
        '''
        depth = 0
        item = self.parent()

        while item is not None:
            item = item.parent()
            depth += 1

        return depth

    def rootHash(self):
        '''
        Returns a hash key that is used to identify
        the lineage of the child nodes i.e.
        which node exactly is the 'forefather'.
        '''
        return self._rootNodeHash

    def styleIfChild(self):
        '''
        Style the parent _title if set to 'True'.
        This is a read only property.
        '''
        return self._styleIfChild

    def data(self, column):
        '''
        Returns the data item in the specified specified column index within the list.
        '''
        if column < 0 or column >= len(self._data):
            raise IndexError

        return self._data[column]

    def setData(self, column, value):
        '''
        Set the value of the node data at the given column index.
        '''
        if column < 0 or column >= len(self._data):
            return False

        self._data[column] = value

        return True

    def model(self):
        """
        :return: Returns the data model associated with this node. Returns
        'None' if not defined.
        :rtype: object
        """
        return self._model

    def columnCount(self):
        '''
        Return the number of columns.
        '''
        return len(self._data)

    def column(self, position):
        '''
        Get the data in the specified column.
        '''
        if position < 0 and position >= len(self._data):
            return None

        return self._data[position]

    def removeColumns(self, position, columns):
        '''
        Removes columns in the STR node.
        '''
        if position < 0 or position >= len(self._data):
            return False

        for c in range(columns):
            self._data.pop(position)

        return True

    def clearColumns(self):
        '''
        Removes all columns in the node.
        '''
        del self._data[:]

    def typeInfo(self):
        return "BASE_NODE"

    def __repr__(self):
        return self.typeInfo()

    def manageActions(self, modelindex, menu):
        """
        Returns the list of actions to be loaded into the context menu
        of this node when a user right clicks in the tree view.
        Default actions are for expanding/collapsing child nodes.
        To be inherited by subclasses for additional custom actions.
        """
        nullAction = QAction(
            NO_ACTION_ICON,
            QApplication.translate("BaseSTRNode", "No User Action"),
            self.parentWidget())
        nullAction.setEnabled(False)

        if not self._view is None:
            if self._view.isExpanded(modelindex):
                self._expand_action.setEnabled(False)
                self._collapse_action.setEnabled(True)

            else:
                self._expand_action.setEnabled(True)
                self._collapse_action.setEnabled(False)

        #Disconnect then reconnect signals
        if self.signalReceivers(self._expand_action) > 0:
            self._expand_action.triggered.disconnect()

        if self.signalReceivers(self._collapse_action) > 0:
            self._collapse_action.triggered.disconnect()

        #Connect expand/collapse signals to the respective actions
        self._expand_action.triggered.connect(
            lambda: self._on_expand(modelindex))
        self._collapse_action.triggered.connect(
            lambda: self._on_collapse(modelindex))

        menu.addAction(self._expand_action)
        menu.addAction(self._collapse_action)

    def _on_expand(self, index):
        """
        Slot raised to expand all children under this node at the specified
        index.
        :param index: Location in the data model.
        :type index: QModelIndex
        """
        if index.isValid():
            self._view.expand(index)

    def _on_collapse(self, index):
        """
        Slot raised to collapse all children under this node at the specified
        index.
        :param index: Location in the data model.
        :type index: QModelIndex
        """
        if index.isValid():
            self._view.collapse(index)

    def onEdit(self, index):
        '''
        Slot triggered when the Edit action of the node is triggered by the user.
        Subclasses to implement.
        '''
        pass

    def onDelete(self, index):
        '''
        Slot triggered when the Delete action of the node is triggered by the user.
        Subclasses to implement.
        '''
        pass

    def signalReceivers(self, action, signal="triggered()"):
        '''
        Convenience method that returns the number of receivers connected to the signal of the action object.
        '''
        return action.receivers(SIGNAL(signal))

    def _concat_names_values(self, display_mapping, formatter):
        """
        Extract model values based on the properties defined by display mapping
        and concatenates the display-friendly property name with its corresponding
        value.
        :param display_mapping: Collection containing a tuple of column name
        and display name as key and column value.
        :type display_mapping: dict
        :param formatter: Collections of functions mapped to the property names
        that format the corresponding attribute values.
        :type formatter: dict
        :return: list of display name-value pairs.
        :rtype: list
        """
        name_values = []

        for col_name_prop, attr_val in display_mapping.iteritems():
            prop, prop_display = col_name_prop[0], col_name_prop[1]
            if prop in formatter:
                attr_val = formatter[prop](attr_val)

            name_val = "%s%s %s" % (prop_display, self.separator, attr_val)
            name_values.append(name_val)

        return name_values

    def _property_values(self, model, display_mapping, formatter):
        """
        Extract model values based on the properties defined by display_mapping.
        :param model: Instance of database model.
        :param display_mapping: property names and corresponding display-friendly
        names.
        :type display_mapping: dict
        :param formatter: Collections of functions mapped to the property names
        that format the corresponding attribute values.
        :type formatter: dict
        :return: Attribute values as specified in the display_mapping.
        :rtype: list
        """
        attr_values = []

        for prop, disp in display_mapping.iteritems():
            attr_val = getattr(model, prop)

            if prop in formatter:
                attr_val = formatter[prop](attr_val)

            attr_values.append(attr_val)

        return attr_values

    def _display_mapping(self):
        """
        :return: Property names and their corresponding display names.
        :rtype: dict
        """
        raise NotImplementedError