def add_submenu(self, submenu, menu):

        submenu = QMenu(submenu, menu)
        submenu.setIcon(QIcon(":/plugins/ProjectLauncher/icon_folder.png"))
        menu.addMenu(submenu)

        return submenu
    def process_custom_menu(self, point):
        ''' See XmlController for documentation '''
        item = self.select_item_at(point)
        if not item:
            return
        menu = QMenu()
        node = item.node

        if node.get('executable') == 'True':
            menu.addAction(self.actRunScenario)
        elif node.get('type') in ['selectable', 'model_choice']:
            menu.addAction(self.actMoveNodeUp)
            menu.addAction(self.actMoveNodeDown)
        elif node.tag == 'models_to_run': # special case of a selectable list
            models_menu = QMenu(menu)
            models_menu.setTitle('Add model to run')
            models_menu.setIcon(IconLibrary.icon('add'))
            available_model_names = get_model_names(self.project)
            for model_name in available_model_names:
                cb = lambda x = model_name, y = self.selected_index(): self.addModel(y, x)
                action = self.create_action('model', model_name, cb)
                models_menu.addAction(action)
            menu.addMenu(models_menu)

        self.add_default_menu_items_for_node(node, menu)

        if not menu.isEmpty():
            menu.exec_(QCursor.pos())
Example #3
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))
Example #4
0
    def add_custom_menu_items_for_node(self, node, menu):
        if node.get('type') == 'scenario':
            node_executable = (node.get('executable') == 'True')
            menu.addAction(self.actExecutable)

            # Workaround: disabled items do not show check marks
            if node.get('inherited') is None:
                self.actExecutable.setEnabled(True)
                self.actExecutable.setText('Executable')
                self.actExecutable.setChecked(node_executable)
            else:
                self.actExecutable.setDisabled(True)
                self.actExecutable.setText(
                    'Executable: %s' % ('Yes' if node_executable else 'No'))

            if node_executable:
                menu.addAction(self.actRunScenario)
            if node.find('models_to_run') is None:
                #if there isn't a child node models_to_run
                menu.addAction(self.actModelsToRun)
        elif node.get('type') in ['selectable', 'model_choice']:
            menu.addAction(self.actMoveNodeUp)
            menu.addAction(self.actMoveNodeDown)
        elif node.tag == 'models_to_run':  # special case of a selectable list
            models_menu = QMenu(menu)
            models_menu.setTitle('Add model to run')
            models_menu.setIcon(IconLibrary.icon('add'))
            available_model_names = get_model_names(self.project)
            for model_name in available_model_names:
                cb = lambda x=model_name, y=self.selected_index(
                ): self.addModel(y, x)
                action = self.create_action('model', model_name, cb)
                models_menu.addAction(action)
            menu.addMenu(models_menu)
Example #5
0
    def process_custom_menu(self, point):
        ''' See XmlController for documentation '''
        item = self.select_item_at(point)
        if not item:
            return
        menu = QMenu()
        node = item.node

        if node.get('executable') == 'True':
            menu.addAction(self.actRunScenario)
        elif node.get('type') in ['selectable', 'model_choice']:
            menu.addAction(self.actMoveNodeUp)
            menu.addAction(self.actMoveNodeDown)
        elif node.tag == 'models_to_run':  # special case of a selectable list
            models_menu = QMenu(menu)
            models_menu.setTitle('Add model to run')
            models_menu.setIcon(IconLibrary.icon('add'))
            available_model_names = get_model_names(self.project)
            for model_name in available_model_names:
                cb = lambda x=model_name, y=self.selected_index(
                ): self.addModel(y, x)
                action = self.create_action('model', model_name, cb)
                models_menu.addAction(action)
            menu.addMenu(models_menu)

        self.add_default_menu_items_for_node(node, menu)

        if not menu.isEmpty():
            menu.exec_(QCursor.pos())
Example #6
0
 def _read_ini_file(self, root, ini_file_path, category):
     try:
         ini_full_path = os.path.join(root, ini_file_path)
         parser = ConfigParser()
         ini_file = codecs.open(ini_full_path, 'r', 'utf-8')
         parser.readfp(ini_file)
         #read config
         group_id = parser.get('general', 'id')
         group_alias = parser.get('ui', 'alias')
         icon_file = ConfigReaderHelper.try_read_config(parser, 'ui', 'icon')
         group_icon_path = os.path.join(root, icon_file) if icon_file else None
         #try read translations
         posible_trans = parser.items('ui')
         for key, val in posible_trans:
             if type(key) is unicode and key == 'alias[%s]' % self.locale:
                 self.translator.append(group_alias, val)
                 break
         #create menu
         group_menu = QMenu(self.tr(group_alias))
         group_menu.setIcon(QIcon(group_icon_path))
         #append to all groups
         # set contrib&user
         self.groups[group_id] = GroupInfo(group_id, group_alias, group_icon_path, ini_full_path, group_menu, category)
     except Exception, e:
         error_message = self.tr('Group INI file can\'t be parsed: ') + e.message
         QgsMessageLog.logMessage(error_message, level=QgsMessageLog.CRITICAL)
 def _read_ini_file(self, root, ini_file_path, category):
     try:
         ini_full_path = os.path.join(root, ini_file_path)
         parser = ConfigParser()
         ini_file = codecs.open(ini_full_path, 'r', 'utf-8')
         parser.readfp(ini_file)
         #read config
         group_id = parser.get('general', 'id')
         group_alias = parser.get('ui', 'alias')
         icon_file = ConfigReaderHelper.try_read_config(parser, 'ui', 'icon')
         group_icon_path = os.path.join(root, icon_file) if icon_file else None
         #try read translations
         posible_trans = parser.items('ui')
         for key, val in posible_trans:
             if type(key) is unicode and key == 'alias[%s]' % self.locale:
                 self.translator.append(group_alias, val)
                 break
         #create menu
         group_menu = QMenu(self.tr(group_alias))
         group_menu.setIcon(QIcon(group_icon_path))
         #append to all groups
         # set contrib&user
         self.groups[group_id] = GroupInfo(group_id, group_alias, group_icon_path, ini_full_path, group_menu, category)
     except Exception, e:
         error_message = self.tr('Group INI file can\'t be parsed: ') + e.message
         QgsMessageLog.logMessage(error_message, level=QgsMessageLog.CRITICAL)
 def add_custom_menu_items_for_node(self, node, menu):
     if node.get('type') == 'scenario':
         node_executable = (node.get('executable') == 'True')
         menu.addAction(self.actExecutable)
         
         # Workaround: disabled items do not show check marks
         if node.get('inherited') is None:
             self.actExecutable.setEnabled(True)
             self.actExecutable.setText('Executable')
             self.actExecutable.setChecked(node_executable)
         else:
             self.actExecutable.setDisabled(True)
             self.actExecutable.setText('Executable: %s' % ('Yes' if node_executable else 'No'))
             
         if node_executable:
             menu.addAction(self.actRunScenario)
         if node.find('models_to_run') is None:  
             #if there isn't a child node models_to_run
             menu.addAction(self.actModelsToRun)                
     elif node.get('type') in ['selectable', 'model_choice']:
         menu.addAction(self.actMoveNodeUp)
         menu.addAction(self.actMoveNodeDown)
     elif node.tag == 'models_to_run': # special case of a selectable list
         models_menu = QMenu(menu)
         models_menu.setTitle('Add model to run')
         models_menu.setIcon(IconLibrary.icon('add'))
         available_model_names = get_model_names(self.project)
         for model_name in available_model_names:
             cb = lambda x = model_name, y = self.selected_index(): self.addModel(y, x)
             action = self.create_action('model', model_name, cb)
             models_menu.addAction(action)
         menu.addMenu(models_menu)
Example #9
0
class WebLayerGroup:
    """Group in menu"""
    def __init__(self, name, icon):
        self._menu = QMenu(name)
        self._menu.setIcon(QIcon(os.path.join("icons", icon)))

    def menu(self):
        return self._menu
class WebLayerGroup:
    """Group in menu"""

    def __init__(self, name, icon):
        self._menu = QMenu(name)
        self._menu.setIcon(QIcon(os.path.join(":/plugins/openlayers/weblayers/icons", icon)))

    def menu(self):
        return self._menu
Example #11
0
class WebLayerGroup:
    """Group in menu"""
    def __init__(self, name, icon):
        self._menu = QMenu(name)
        self._menu.setIcon(
            QIcon(os.path.join(":/plugins/tmsforkorea/weblayers/icons", icon)))

    def menu(self):
        return self._menu
Example #12
0
 def addMenu(self, parent, name, title, icon_path):
     """
     Adds a QMenu
     """
     child = QMenu(parent)
     child.setObjectName(name)
     child.setTitle(self.tr(title))
     child.setIcon(QIcon(icon_path))
     parent.addMenu(child)
     return child
Example #13
0
def install_shortcuts(obj, actions, ide):
    short = resources.get_shortcut
    for action in actions:
        short_key = action.get("shortcut", None)
        action_data = action.get("action", None)
        connect = action.get("connect", None)

        shortcut = None
        item_ui = None
        func = None
        if connect:
            func = getattr(obj, connect, None)

        if short_key and not action_data:
            if isinstance(short_key, QKeySequence):
                shortcut = QShortcut(short_key, ide)
            else:
                shortcut = QShortcut(short(short_key), ide)
            shortcut.setContext(Qt.ApplicationShortcut)
            if isinstance(func, collections.Callable):
                ide.connect(shortcut, SIGNAL("activated()"), func)
        if action_data:
            is_menu = action_data.get('is_menu', False)
            if is_menu:
                item_ui = QMenu(action_data['text'], ide)
            else:
                item_ui = QAction(action_data['text'], ide)
                object_name = "%s.%s" % (obj.__class__.__name__, connect)
                item_ui.setObjectName(object_name)
            image_name = action_data.get('image', None)
            section = action_data.get('section', None)
            weight = action_data.get('weight', None)
            keysequence = action_data.get('keysequence', None)
            if image_name:
                if isinstance(image_name, int):
                    icon = ide.style().standardIcon(image_name)
                    item_ui.setIcon(icon)
                elif isinstance(image_name, str):
                    icon = QIcon(":img/" + image_name)
                    item_ui.setIcon(icon)
            if short_key and not is_menu:
                item_ui.setShortcut(short(short_key))
                item_ui.setShortcutContext(Qt.ApplicationShortcut)
            elif keysequence and not is_menu:
                item_ui.setShortcut(short(keysequence))
                item_ui.setShortcutContext(Qt.ApplicationShortcut)
            if isinstance(func, collections.Callable) and not is_menu:
                ide.connect(item_ui, SIGNAL("triggered()"), func)
            if section and section[0] is not None and weight:
                ide.register_menuitem(item_ui, section, weight)
                if image_name and not is_menu:
                    ide.register_toolbar(item_ui, section, weight)

        if short_key and shortcut:
            ide.register_shortcut(short_key, shortcut, item_ui)
Example #14
0
def install_shortcuts(obj, actions, ide):
    short = resources.get_shortcut
    for action in actions:
        short_key = action.get("shortcut", None)
        action_data = action.get("action", None)
        connect = action.get("connect", None)

        shortcut = None
        item_ui = None
        func = None
        if connect:
            func = getattr(obj, connect, None)

        if short_key and not action_data:
            if isinstance(short_key, QKeySequence):
                shortcut = QShortcut(short_key, ide)
            else:
                shortcut = QShortcut(short(short_key), ide)
            shortcut.setContext(Qt.ApplicationShortcut)
            if isinstance(func, collections.Callable):
                ide.connect(shortcut, SIGNAL("activated()"), func)
        if action_data:
            is_menu = action_data.get('is_menu', False)
            if is_menu:
                item_ui = QMenu(action_data['text'], ide)
            else:
                item_ui = QAction(action_data['text'], ide)
                object_name = "%s.%s" % (obj.__class__.__name__, connect)
                item_ui.setObjectName(object_name)
            image_name = action_data.get('image', None)
            section = action_data.get('section', None)
            weight = action_data.get('weight', None)
            keysequence = action_data.get('keysequence', None)
            if image_name:
                if isinstance(image_name, int):
                    icon = ide.style().standardIcon(image_name)
                    item_ui.setIcon(icon)
                elif isinstance(image_name, str):
                    icon = QIcon(":img/" + image_name)
                    item_ui.setIcon(icon)
            if short_key and not is_menu:
                item_ui.setShortcut(short(short_key))
                item_ui.setShortcutContext(Qt.ApplicationShortcut)
            elif keysequence and not is_menu:
                item_ui.setShortcut(short(keysequence))
                item_ui.setShortcutContext(Qt.ApplicationShortcut)
            if isinstance(func, collections.Callable) and not is_menu:
                ide.connect(item_ui, SIGNAL("triggered()"), func)
            if section and section[0] is not None and weight:
                ide.register_menuitem(item_ui, section, weight)
                if image_name and not is_menu:
                    ide.register_toolbar(item_ui, section, weight)

        if short_key and shortcut:
            ide.register_shortcut(short_key, shortcut, item_ui)
Example #15
0
 def _setupUi(self):
     self.setupUi(self)
     self.browserView.setModel(self.boardModel)
     h = self.browserView.header()
     h.setResizeMode(QHeaderView.Fixed)
     h.resizeSection(1, 120)
     h.setResizeMode(0, QHeaderView.Stretch)
     
     # Action menu
     actionMenu = QMenu('Actions', self.toolBar)
     actionMenu.setIcon(QIcon(QPixmap(":/actions")))
     actionMenu.addAction(self.actionNewFolder)
     actionMenu.addAction(self.actionRemoveEmptyFolders)
     actionMenu.addAction(self.actionRenameSelected)
     actionMenu.addAction(self.actionMoveSelectedToIgnoreBox)
     actionMenu.addAction(self.actionSwitchConflictAndOriginal)
     actionMenu.addSeparator()
     actionMenu.addAction(self.actionMassRename)
     actionMenu.addAction(self.actionSplit)
     actionMenu.addAction(self.actionUndoSplit)
     actionMenu.addAction(self.actionMoveConflicts)
     actionMenu.addAction(self.actionMoveConflictsAndOriginals)
     self.actionActions.setMenu(actionMenu)
     button = QToolButton(self.toolBar)
     button.setDefaultAction(actionMenu.menuAction())
     button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
     self.actionsButton = button
     self.toolBar.insertWidget(self.actionActions, button) # the action is a placeholder
     self.toolBar.removeAction(self.actionActions)
     
     # Materialize menu
     materializeMenu = QMenu('Materialize', self.toolBar)
     materializeMenu.setIcon(QIcon(QPixmap(":/materialize")))
     materializeMenu.addAction(self.actionRenameInRespectiveLocations)
     materializeMenu.addAction(self.actionCopyToOtherLocation)
     materializeMenu.addAction(self.actionMoveToOtherLocation)
     self.actionMaterialize.setMenu(materializeMenu)
     button = QToolButton(self.toolBar)
     button.setDefaultAction(materializeMenu.menuAction())
     button.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
     self.materializeButton = button
     self.toolBar.insertWidget(self.actionMaterialize, button) # the action is a placeholder
     self.toolBar.removeAction(self.actionMaterialize)
Example #16
0
 def get_plugin_actions(self):
     """Setup actions"""
     quit_action = create_action(self, self.tr("&Quit"), self.tr("Ctrl+Q"),
                         'exit.png', self.tr("Quit"),
                         triggered=self.quit)
     run_action = create_action(self, self.tr("&Run..."), None,
                         'run_small.png', self.tr("Run a Python script"),
                         triggered=self.run_script)
     environ_action = create_action(self,
                         self.tr("Environment variables..."),
                         icon = 'environ.png',
                         tip=self.tr("Show and edit environment variables"
                                     " (for current session)"),
                         triggered=self.show_env)
     syspath_action = create_action(self,
                         self.tr("Show sys.path contents..."),
                         icon = 'syspath.png',
                         tip=self.tr("Show (read-only) sys.path"),
                         triggered=show_syspath)
     buffer_action = create_action(self,
                         self.tr("Buffer..."), None,
                         tip=self.tr("Set maximum line count"),
                         triggered=self.change_max_line_count)
     font_action = create_action(self,
                         self.tr("&Font..."), None,
                         'font.png', self.tr("Set shell font style"),
                         triggered=self.change_font)
     exteditor_action = create_action(self,
                         self.tr("External editor path..."), None, None,
                         self.tr("Set external editor executable path"),
                         triggered=self.change_exteditor)
     wrap_action = create_action(self,
                         self.tr("Wrap lines"),
                         toggled=self.toggle_wrap_mode)
     wrap_action.setChecked( CONF.get(self.ID, 'wrap') )
     calltips_action = create_action(self, self.tr("Balloon tips"),
         toggled=self.toggle_calltips)
     calltips_action.setChecked( CONF.get(self.ID, 'calltips') )
     codecompletion_action = create_action(self,
                                       self.tr("Automatic code completion"),
                                       toggled=self.toggle_codecompletion)
     codecompletion_action.setChecked( CONF.get(self.ID,
                                                'codecompletion/auto') )
     codecompenter_action = create_action(self,
                                 self.tr("Enter key selects completion"),
                                 toggled=self.toggle_codecompletion_enter)
     codecompenter_action.setChecked( CONF.get(self.ID,
                                                'codecompletion/enter-key') )
     
     option_menu = QMenu(self.tr("Internal console settings"), self)
     option_menu.setIcon(get_icon('tooloptions.png'))
     add_actions(option_menu, (buffer_action, font_action, wrap_action,
                               calltips_action, codecompletion_action,
                               codecompenter_action, exteditor_action))
                 
     menu_actions = [None, run_action, environ_action, syspath_action,
                     option_menu, None, quit_action]
     toolbar_actions = []
     
     # Add actions to context menu
     add_actions(self.shell.menu, menu_actions)
     
     return menu_actions, toolbar_actions
Example #17
0
class CartoDBPlugin(QObject):
    # initialize plugin directory
    PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__))

    def __init__(self, iface):
        QObject.__init__(self)
        QgsMessageLog.logMessage('GDAL Version: ' + str(gdal.VersionInfo('VERSION_NUM')), 'CartoDB Plugin', QgsMessageLog.INFO)

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

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

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

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

        # SQLite available?
        driverName = "SQLite"
        self.sqLiteDrv = ogr.GetDriverByName(driverName)
        if self.sqLiteDrv is None:
            QgsMessageLog.logMessage('SQLite driver not found', 'CartoDB Plugin', QgsMessageLog.CRITICAL)
        else:
            QgsMessageLog.logMessage('SQLite driver is found', 'CartoDB Plugin', QgsMessageLog.INFO)
            self.databasePath = CartoDBPlugin.PLUGIN_DIR + '/db/database.sqlite'
            shutil.copyfile(CartoDBPlugin.PLUGIN_DIR + '/db/init_database.sqlite', self.databasePath)
        self.layers = []
        self.countLoadingLayers = 0
        self.countLoadedLayers = 0

        self._cdbMenu = None
        self._mainAction = None
        self._loadDataAction = None
        self._createVizAction = None
        self._addSQLAction = None
        self.toolbar = CartoDBToolbar()
        self._toolbarAction = None
        self._menu = None

    def initGui(self):
        self._cdbMenu = QMenu("CartoDB plugin", self.iface.mainWindow())
        self._cdbMenu.setIcon(QIcon(":/plugins/qgis-cartodb/images/icon.png"))
        self._mainAction = QAction(self.tr('Add CartoDB Layer'), self.iface.mainWindow())
        self._mainAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/add.png"))
        self._loadDataAction = QAction(self.tr('Upload layers to CartoDB'), self.iface.mainWindow())
        self._loadDataAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/upload.png"))
        self._createVizAction = QAction(self.tr('Create New Map'), self.iface.mainWindow())
        self._createVizAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/map.png"))
        self._addSQLAction = QAction(self.tr('Add SQL CartoDB Layer'), self.iface.mainWindow())
        self._addSQLAction.setIcon(QIcon(":/plugins/qgis-cartodb/images/icons/sql.png"))

        self.toolbar.setClick(self.connectionManager)
        self.toolbar.error.connect(self.toolbarError)
        self._toolbarAction = self.iface.addWebToolBarWidget(self.toolbar)
        worker = CartoDBPluginWorker(self.toolbar, 'connectCartoDB')
        worker.start()

        if not self.toolbar.isCurrentUserValid():
            self._mainAction.setEnabled(False)
            self._loadDataAction.setEnabled(False)
            self._createVizAction.setEnabled(False)
            self._addSQLAction.setEnabled(False)

        self._mainAction.triggered.connect(self.run)
        self._loadDataAction.triggered.connect(self.upload)
        self._createVizAction.triggered.connect(self.createNewMap)
        self._addSQLAction.triggered.connect(self.addSQL)

        self._cdbMenu.addAction(self._mainAction)
        self._cdbMenu.addAction(self._loadDataAction)
        self._cdbMenu.addAction(self._createVizAction)
        self._cdbMenu.addAction(self._addSQLAction)
        try:
            self.iface.layerToolBar().addAction(self._mainAction)
        except:
            self.iface.addWebToolBarIcon(self._mainAction)
        self.iface.addWebToolBarIcon(self._loadDataAction)
        self.iface.addWebToolBarIcon(self._createVizAction)
        try:
            self.iface.layerToolBar().addAction(self._addSQLAction)
        except:
            self.iface.addWebToolBarIcon(self._addSQLAction)

        # Create Web menu, if it doesn't exist yet
        tmpAction = QAction("Temporal", self.iface.mainWindow())
        self.iface.addPluginToWebMenu("_tmp", tmpAction)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._cdbMenu)
        self.iface.removePluginWebMenu("_tmp", tmpAction)

        # Register plugin layer type
        self.pluginLayerType = CartoDBPluginLayerType(self.iface, self.createLayerCB)
        QgsPluginLayerRegistry.instance().addPluginLayerType(self.pluginLayerType)

    def unload(self):
        self.iface.removeWebToolBarIcon(self._mainAction)
        self.iface.removeWebToolBarIcon(self._loadDataAction)
        self.iface.removeWebToolBarIcon(self._createVizAction)
        self.iface.removeWebToolBarIcon(self._addSQLAction)
        self.iface.webMenu().removeAction(self._cdbMenu.menuAction())
        self.iface.removeWebToolBarIcon(self._toolbarAction)

        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(CartoDBPluginLayer.LAYER_TYPE)

    def connectionManager(self):
        dlg = CartoDBConnectionsManager()
        dlg.notfoundconnections.connect(self.connectionsNotFound)
        dlg.deleteconnetion.connect(self.onDeleteUser)
        dlg.show()

        result = dlg.exec_()
        if result == 1 and dlg.currentUser is not None and dlg.currentApiKey is not None:
            self.toolbar.setUserCredentials(dlg.currentUser, dlg.currentApiKey, dlg.currentMultiuser)
            self._mainAction.setEnabled(True)
            self._loadDataAction.setEnabled(True)
            self._createVizAction.setEnabled(True)
            self._addSQLAction.setEnabled(True)

    def connectionsNotFound(self):
        self.toolbarError("")
        self.toolbar.reset()

    def onDeleteUser(self, user):
        if self.toolbar.currentUser == user:
            self.toolbar.setConnectText()

    def toolbarError(self, error):
        self._mainAction.setEnabled(False)
        self._loadDataAction.setEnabled(False)
        self._createVizAction.setEnabled(False)
        self._addSQLAction.setEnabled(False)

    def run(self):
        # Create and show the dialog
        dlg = CartoDBPluginDialog(self.toolbar)
        dlg.show()

        result = dlg.exec_()
        # See if OK was pressed
        if result == 1 and dlg.currentUser is not None and dlg.currentApiKey is not None:
            selectedItems = dlg.getTablesListSelectedItems()
            countLayers = len(selectedItems)
            self.countLoadingLayers = self.countLoadingLayers + countLayers
            if countLayers > 0:
                self.progressMessageBar, self.progress = self.addLoadingMsg(self.countLoadingLayers)
                self.iface.messageBar().pushWidget(self.progressMessageBar, self.iface.messageBar().INFO)
                self.iface.mainWindow().statusBar().showMessage(self.tr('Processed {} %').format(0))
                for i, table in enumerate(selectedItems):
                    widget = dlg.getItemWidget(table)
                    worker = CartoDBLayerWorker(self.iface, widget.tableName, widget.tableOwner, dlg,
                                                filterByExtent=dlg.filterByExtent(), readonly=widget.readonly,
                                                multiuser=widget.multiuser)
                    worker.finished.connect(self.addLayer)
                    self.worker = worker
                    worker.load()
        elif dlg.loadSQL:
            self.addSQL()


    def addLayer(self, layer):
        try:
            self.worker.deleteLater()
        except Exception, e:
            pass

        self.countLoadedLayers = self.countLoadedLayers + 1

        if layer.readonly:
            self.iface.messageBar().pushMessage(self.tr('Warning'),
                                                self.tr('Layer {}  is loaded in readonly mode').format(layer.layerName),
                                                level=self.iface.messageBar().WARNING, duration=5)
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        self.layers.append(layer)
        self.progressMessageBar.setText(str(self.countLoadedLayers) + '/' + str(self.countLoadingLayers))
        percent = self.countLoadedLayers / float(self.countLoadingLayers) * 100
        self.iface.mainWindow().statusBar().showMessage(self.tr('Processed {}% - Loaded: {}').format(int(percent), layer.cartoTable))
        self.progress.setValue(self.countLoadedLayers)
        if self.countLoadedLayers == self.countLoadingLayers:
            self.iface.mainWindow().statusBar().clearMessage()
            self.iface.messageBar().popWidget(self.progressMessageBar)
            self.countLoadedLayers = 0
            self.countLoadingLayers = 0
Example #18
0
class SOSClient:
    """QGIS Plugin Implementation."""

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

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

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

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

        # Declare instance attributes
        self.actions = []
        self.menu = QMenu(self.tr(u'&SOS Client'))
        self.toolbar = self.iface.addToolBar(u'SOSClient')
        self.toolbar.setObjectName(u'SOSClient')

    # 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('SOSClient', message)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.menu.addAction (action)

        self.actions.append(action)

        return action

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

        self.add_action(
            ':/plugins/SOSClient/icon_add.png',
            text=self.tr(u'SOS Client'),
            callback=self.run,
            parent=self.iface.mainWindow())

        self.add_action(
            ':/plugins/SOSClient/icon_xml.png',
            text=self.tr(u'Show XML'),
            callback=self.showLayerXml,
            parent=self.iface.mainWindow(),
            add_to_toolbar=True)
        
        self.add_action(
            ':/plugins/SOSClient/icon_plot.png',
            text=self.tr(u'Plot'),
            callback=self.showPlotDialog,
            parent=self.iface.mainWindow(),
            add_to_toolbar=True)

        self.add_action(
            ':/plugins/SOSClient/icon.png',
            text=self.tr(u'About'),
            callback=self.about,
            parent=self.iface.mainWindow(),
            add_to_toolbar=False)
        
        self.menu.setIcon(QIcon(':/plugins/SOSClient/icon.png'))
        self.iface.webMenu().addMenu (self.menu)

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removeToolBarIcon(action)
        self.iface.webMenu().removeAction(self.menu.menuAction())

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass
        
    def showLayerXml (self):
        layer = self.iface.activeLayer()
        if layer == None:
            self.iface.messageBar().pushMessage (self.tr(u'SOS Client'),self.tr("You must select a layer"), QgsMessageBar.WARNING, 10)
            return
        
        xml = layer.customProperty("xml")
        if len (xml):
            dlg = XmlViewerDialog (self.iface.mainWindow(), QFile(xml), XmlHighlighter)
            dlg.show()
            dlg.exec_()
        else:
            self.iface.messageBar().pushMessage (self.tr(u'SOS Client'),self.tr("Layer have not a xml property"), QgsMessageBar.WARNING, 10)
            
    def showPlotDialog (self):
        try:
            dlg = SOSPlotDialog (self.iface.activeLayer(), parent=self.iface.mainWindow())
            dlg.show()
            dlg.exec_()
        except Exception as error:
            self.iface.messageBar().pushMessage (self.tr(u'SOS Client'),unicode(error), QgsMessageBar.CRITICAL, 10)
    
    def about(self):
        #TODO
        QMessageBox.information(self.iface.mainWindow(), self.tr(u"About SOS Client"), 
                                self.tr(u"SOS Client Plugin<br />This plugin request observations data from OGC SOS server to create a vector layer.<br />Also provides tools to plot observations data<br /><br />Author: Rubén Mosquera Varela<br />E-mail: <a href=\"mailto:[email protected]\">[email protected]</a>"))
Example #19
0
 def set_actions(self):
     """Setup actions"""
     quit_action = create_action(self, self.tr("&Quit"), self.tr("Ctrl+Q"),
                         'exit.png', self.tr("Quit"),
                         triggered=self.quit)
     run_action = create_action(self, self.tr("&Run..."), None,
                         'run_small.png', self.tr("Run a Python script"),
                         triggered=self.run_script)
     environ_action = create_action(self,
                         self.tr("Environment variables..."),
                         icon = 'environ.png',
                         tip=self.tr("Show and edit environment variables"
                                     " (for current session)"),
                         triggered=self.show_env)
     syspath_action = create_action(self,
                         self.tr("Show sys.path contents..."),
                         icon = 'syspath.png',
                         tip=self.tr("Show (read-only) sys.path"),
                         triggered=show_syspath)
     font_action = create_action(self,
                         self.tr("&Font..."), None,
                         'font.png', self.tr("Set shell font style"),
                         triggered=self.change_font)
     exteditor_action = create_action(self,
                         self.tr("External editor path..."), None, None,
                         self.tr("Set external editor executable path"),
                         triggered=self.change_exteditor)
     wrap_action = create_action(self,
                         self.tr("Wrap lines"),
                         toggled=self.toggle_wrap_mode)
     wrap_action.setChecked( CONF.get(self.ID, 'wrap') )
     calltips_action = create_action(self, self.tr("Balloon tips"),
         toggled=self.toggle_calltips)
     calltips_action.setChecked( CONF.get(self.ID, 'calltips') )
     codecompletion_action = create_action(self, self.tr("Code completion"),
         toggled=self.toggle_codecompletion)
     codecompletion_action.setChecked( CONF.get(self.ID,
                                                'autocompletion/enabled') )
     codecompenter_action = create_action(self,
                                 self.tr("Enter key selects completion"),
                                 toggled=self.toggle_codecompletion_enter)
     codecompenter_action.setChecked( CONF.get(self.ID,
                                                'autocompletion/enter-key') )
     rollbackimporter_action = create_action(self,
             self.tr("Force modules to be completely reloaded"),
             tip=self.tr("Force Python to reload modules imported when "
                         "executing a script in the interactive console"),
             toggled=self.toggle_rollbackimporter)
     rollbackimporter_action.setChecked( CONF.get(self.ID,
                                                  'rollback_importer') )
     try:
         imp.find_module('matplotlib')
         dockablefigures_action = create_action(self,
                         self.tr("Dockable figures"),
                         tip=self.tr("If enabled, matplotlib figures may "
                                     "be docked to Spyder's main window "
                                     "(will apply only for new figures)"),
                         toggled=self.toggle_dockablefigures_mode)
         dockablefigures_action.setChecked( CONF.get('figure', 'dockable') )
     except ImportError:
         dockablefigures_action = None
         
     option_menu = QMenu(self.tr("Interactive console settings"), self)
     option_menu.setIcon(get_icon('tooloptions.png'))
     add_actions(option_menu, (font_action, wrap_action, calltips_action,
                               codecompletion_action, codecompenter_action,
                               rollbackimporter_action, exteditor_action,
                               dockablefigures_action))
     
     menu_actions = [None, run_action, environ_action, syspath_action,
                     option_menu, None, quit_action]
     toolbar_actions = []
     
     # Add actions to context menu
     add_actions(self.shell.menu, menu_actions)
     
     return menu_actions, toolbar_actions
class FileController_OpusData(FileController):
    def __init__(self, manager, data_path, parent_widget, tools_model):

        FileController.__init__(self, manager, data_path, parent_widget)

        self.actRefresh = QAction(IconLibrary.icon('reload'), "Refresh Tree",
                                  self.treeview)
        QObject.connect(self.actRefresh, SIGNAL("triggered()"),
                        self.refreshAction)

        self.actViewDataset = QAction(IconLibrary.icon('inspect'),
                                      "View Dataset", self.treeview)
        QObject.connect(self.actViewDataset, SIGNAL("triggered()"),
                        self.viewDatasetAction)

        self.actOpenTextFile = QAction(IconLibrary.icon('text'),
                                       "Open Text File", self.treeview)
        QObject.connect(self.actOpenTextFile, SIGNAL("triggered()"),
                        self.openTextFile)

        self.tool_library_node = self.manager.project.find(
            'data_manager/tool_library')

        self.tools_model = tools_model

    def viewDatasetAction(self):
        #print "viewDatasetAction"
        model = self.model
        table_name = str(model.fileName(self.currentIndex))
        table_name_full = str(model.filePath(self.currentIndex))
        parentIndex = model.parent(self.currentIndex)
        parent_name = str(model.fileName(parentIndex))
        parent_name_full = str(model.filePath(parentIndex))
        storage = StorageFactory().get_storage(
            'flt_storage', storage_location=parent_name_full)
        columns = storage.get_column_names(table_name)
        # temporarily use the table name for the dataset name
        # dataset_name = DatasetFactory().dataset_name_for_table(table_name)
        # Aaron - please check this way of getting the XMLConfiguration -- is this the best way?

        #        general = self.mainwindow.toolboxBase.opus_core_xml_configuration.get_section('general')
        #        # problem: this gets the package order for the current project, but the viewer shows all the data
        #        package_order = general['dataset_pool_configuration'].package_order

        # PREVIOUS HACK:
        # package_order = ['seattle_parcel','urbansim_parcel', 'eugene', 'urbansim', 'opus_core']
        # temporary code: just use a generic dataset for now
        data = Dataset(in_storage=storage,
                       dataset_name=table_name,
                       in_table_name=table_name,
                       id_name=[])
        # code to get a more specialized dataset if possible (doesn't work with table names not ending in 's'
        # unless they are in the exceptions list in DatasetFactory)
        # data = DatasetFactory().search_for_dataset_with_hidden_id(dataset_name, package_order,
        #    arguments={'in_storage': storage, 'in_table_name': table_name})
        # Need to add a new tab to the main tabs for display of the data
        container = QWidget()
        widgetLayout = QVBoxLayout(container)
        summaryGroupBox = QGroupBox(container)
        summaryGroupBox.setTitle(
            QString("Year: %s  Run name: %s" %
                    (parent_name, table_name_full.split('/')[-3])))
        summaryGroupBox.setFlat(True)
        summaryGroupBoxLayout = QVBoxLayout(summaryGroupBox)
        # Grab the summary data
        buffer = StringIO()
        data.summary(output=buffer, unload_after_each_attribute=True)
        strng = buffer.getvalue()
        buffer.close()
        textBrowser = QTextBrowser()
        #        textBrowser.insertPlainText(strng)
        textBrowser.insertHtml(self.parse_dataset_summary(strng))
        summaryGroupBoxLayout.addWidget(textBrowser)

        widgetLayout.addWidget(summaryGroupBox)

        tableGroupBox = QGroupBox(container)
        tableGroupBox.setTitle(QString("Table View"))
        tableGroupBox.setFlat(True)
        tableGroupBoxLayout = QVBoxLayout(tableGroupBox)
        tv = QTableView()
        header = columns
        tabledata_tmp = []
        for column in columns:
            tabledata_tmp.append(data.get_attribute(column))

        # Transpose the lists
        tabledata = map(None, *tabledata_tmp)

        # If the table data is not empty then we display it
        if tabledata:
            #tv.resizeColumnsToContents()
            tm = TableModel(tabledata, header, container)
            tv.setModel(tm)
            tv.setSortingEnabled(True)
            tableGroupBoxLayout.addWidget(tv)

        widgetLayout.addWidget(tableGroupBox)

        container.tabIcon = IconLibrary.icon('inspect')
        container.tabLabel = QString(table_name)
        self.manager._attach_tab(container)

    def parse_dataset_summary(self, summary):
        html = [
            '''<style type="text/css">

            table.prettytable {
              background: white;
            }
            table.prettytable th {
              border: 1px black solid;
              padding: 0.2em;
              background: gainsboro;
              text-align: left;
                border-width: thin thin thin thin;
                padding: 2px 2px 2px 2px;
                border-style: inset inset inset inset;
                border-color: gray gray gray gray;
            }
            table.prettytable td {
              border: 1px black solid;
              padding: 0.2em;
            }

            table.prettytable caption {
              margin-left: inherit;
              margin-right: inherit;
            }
            #text a {
                color: #000000;
                position: relative;
                text-decoration: underline;
            }
            </style>''', '<body>', '<div id="text">',
            '<table class="prettytable">'
        ]

        summary_lines = summary.split('\n')
        for i, line in enumerate(summary_lines):
            if i == 1: continue
            html.append('<tr>')
            if i == 0:
                header = line.split()[1:]
                html.append(''.join(['<th>%s</th>' % col for col in header]))
            else:

                row = line.split()
                if len(row) == 0: continue
                if row[0] == 'Size:':
                    start_end = i
                    break
                html.append(''.join(['<td>%s</td>' % col for col in row]))

            html.append('</tr>')
        html.append('</table>')
        try:
            html.append('<br><br>' + '<br>'.join(summary_lines[start_end:]))
        except:
            pass
        html.append('</div></body>')
        return QString('\n'.join(html))

    def refreshAction(self):
        #print "refreshAction"
        self.model.refresh(self.treeview.rootIndex())

# Disabling editor support for now

    def openTextFile(self):
        print 'openTextFile %s' % self.model.filePath(self.currentIndex)
        pass
#        print "openTextFile pressed with column = %s and item = %s" % \
#              (self.currentColumn, self.model.filePath(self.currentIndex))
#        if self.mainwindow.editorStuff:
#            print "Loading into qscintilla..."
#            filename = self.model.filePath(self.currentIndex)
#            self.mainwindow.editorStuff.clear()
#            try:
#                f = open(filename,'r')
#            except:
#                return
#            for l in f.readlines():
#                self.mainwindow.editorStuff.append(l)
#            f.close()
#            self.mainwindow.editorStatusLabel.setText(QString(filename))
#            self.mainwindow.openEditorTab()

    def fillInAvailableTools(self):

        # Operations on the selected item
        export_choices = {}
        import_choices = {}

        # Classification for the selected item
        classification = ""

        regex = QRegExp("\\d{4}")  # match directory names with four digits

        def isYear(filename):
            return regex.exactMatch(filename)

        if self.model.isDir(self.currentIndex):

            def hasYearChild(index):
                return any([
                    isYear(self.model.fileName(index.child(i, 0)))
                    for i in range(self.model.rowCount(index))
                ])

            name = self.model.fileName(self.currentIndex)
            parentname = self.model.fileName(
                self.model.parent(self.currentIndex))
            isdir = self.model.isDir(self.currentIndex)
            if self.model.parent(self.currentIndex).isValid():
                parentisdir = self.model.isDir(
                    self.model.parent(self.currentIndex))
            else:
                parentisdir = False
            # print "%s %s %s %s" % (name, parentname,isdir,parentisdir)
            if isdir and isYear(name):
                # We have a database dir
                # print "Database Dir"
                classification = "database"
            elif parentisdir and isYear(parentname):
                # We have a dataset
                # print "Dataset Dir"
                classification = "dataset"
            elif isdir and hasYearChild(self.currentIndex):
                classification = "database_collection"

        else:
            model = self.model
            parentIndex = model.parent(self.currentIndex)
            parentparentIndex = model.parent(parentIndex)
            parentparentname = model.fileName(parentparentIndex)
            parentparentisdir = model.isDir(parentparentIndex)
            if parentparentisdir and isYear(parentparentname):
                # We have a file with a parentparent which is a database classification
                classification = "array"

        # Build up a list of available operations based on the classification

        tool_set_nodes = [
            tool_set_node for tool_set_node in self.tool_library_node
            if tool_set_node.tag == 'tool_group'
        ]
        tool_file_nodes = []
        for tool_set_node in tool_set_nodes:
            tool_file_nodes.extend(
                [node for node in tool_set_node if node.tag == 'tool'])

        # Find all tool_nodes that acts on the resolved classification
        # (by looking at the XML node 'acts_on')
        for tool_node in tool_file_nodes:
            acts_on_node = tool_node.find('acts_on')
            exports_to_node = tool_node.find('exports_to')
            imports_from_node = tool_node.find('imports_from')

            if acts_on_node is None:
                # This tool doesn't export or import anything
                continue

            tool_classifications = acts_on_node.text.split(',')

            if not imports_from_node is None:
                imports_from_value = imports_from_node.text
                if classification in tool_classifications:
                    import_choices[imports_from_value] = tool_node

            if not exports_to_node is None:
                exports_to_value = exports_to_node.text
                if classification in tool_classifications:
                    export_choices[exports_to_value] = tool_node

        self.classification = classification
        return (export_choices, import_choices)

#         print "Classification = " + classification
#        dbxml = self.treeview.model().index(0,0,QModelIndex()).parent()
#         First loop through all tool_sets
#        setsindexlist = self.treeview.findElementIndexByType("tool_library",dbxml,True)
#        for setsindex in setsindexlist:
#            if setsindex.isValid():
#                print "Found valid tool_sets"
#                 Now loop through all tool_set and find the ones with a matching classification
#                tsindexlist = self.xml_model.findElementIndexByType("tool_file",setsindex,True)
#                for tsindex in tsindexlist:
#                    if tsindex.isValid():
#                        print "Found valid tool_set"
#                        classificationtext = ""
#                        tsitem = tsindex.internalPointer()
#                         We use the dom tree to find the classification because it is a hidden node
#                         in the XML tree and will not show up via a search on the model indexes (i.e. it
#                         is not actually in the model/view since it is hidden.
#                        if tsitem.node().hasChildNodes():
#                            tschildren = tsitem.node().childNodes()
#                            for x in xrange(0,tschildren.count(),1):
#                                if tschildren.item(x).isElement():
#                                    tselement = tschildren.item(x).toElement()
#                                    if tselement.hasAttribute(QString("type")) and \
#                                           (tselement.attribute(QString("type")) == QString("acts_on")):
#                                        if tselement.hasChildNodes():
#                                            classchildren = tselement.childNodes()
#                                            for x in xrange(0,classchildren.count(),1):
#                                                if classchildren.item(x).isText():
#                                                    print "Found some text in the classification element"
#                                                    classificationtext = classchildren.item(x).nodeValue()
#                                                    classificationtext = str(classchildren.item(x).nodeValue()).split(',')
#                                    if tselement.hasAttribute(QString("type")) and \
#                                           (tselement.attribute(QString("type")) == QString("exports_to")):
#                                        print tselement.text()
#                                        export_to_text = tselement.text()
#                        tagName = tsitem.domNode.toElement().tagName()
#                        for i in classificationtext:
#                            if i != "" and i == classification:
#                                choices[tagName] = export_to_text
#        self.classification = classification
#        return choices

    def dataActionMenuFunctionImport(self, action):
        return self.dataActionMenuFunction(self.import_dynactions, action)

    def dataActionMenuFunctionExport(self, action):
        return self.dataActionMenuFunction(self.export_dynactions, action)

    def dataActionMenuFunction(self, dynactions, action):
        QObject.disconnect(self.menu, SIGNAL("triggered(QAction*)"),
                           self.dataActionMenuFunction)
        if action != self.actRefresh:
            actiontext = str(action.text())
            tool_node = dynactions[actiontext]
            filename = self.model.fileName(self.currentIndex)
            filepath = self.model.filePath(self.currentIndex)
            parentfilepath = self.model.filePath(self.currentIndex.parent())

            params = self.getOptionalParams(actiontext)
            window = ExecuteToolGui(parent_widget=self.treeview,
                                    tool_node=tool_node,
                                    tool_config=None,
                                    tool_library_node=self.tool_library_node,
                                    params=params,
                                    model=self.tools_model)
            window.show()
        return

    def getOptionalParams(self, actiontext):
        params = {'tool_path': get_path_to_tool_modules(self.manager.project)}
        if self.classification == 'database':
            params['opus_data_directory'] = str(
                self.model.filePath(self.currentIndex.parent()))
            params['opus_data_year'] = str(
                self.model.fileName(self.currentIndex))
            params['opus_table_name'] = 'ALL'
            if actiontext == 'CSV':
                params['csv_table_name'] = 'ALL'
        elif self.classification == 'dataset':
            params['opus_data_directory'] = str(
                self.model.filePath(self.currentIndex.parent().parent()))
            params['opus_data_year'] = str(
                self.model.fileName(self.currentIndex.parent()))
            params['opus_table_name'] = str(
                self.model.fileName(self.currentIndex))
            if actiontext == 'CSV':
                params['csv_table_name'] = str(
                    self.model.fileName(self.currentIndex))
        elif self.classification == 'database_collection':
            params['opus_data_directory'] = str(
                self.model.filePath(self.currentIndex))
            params['opus_data_year'] = 'ALL'
            params['opus_table_name'] = 'ALL'
            if actiontext == 'CSV':
                params['csv_table_name'] = str(
                    self.model.fileName(self.currentIndex))
        return params

    def process_custom_menu(self, position):
        self.currentColumn = self.treeview.indexAt(position).column()
        self.currentIndex = self.treeview.indexAt(position)

        self.menu = QMenu(self.treeview)

        if self.currentIndex.isValid():
            if self.model.fileInfo(self.currentIndex).suffix() == "txt":
                self.menu.addAction(self.actOpenTextFile)
            else:
                # Do stuff for directories
                export_choices, import_choices = self.fillInAvailableTools()

                if self.classification == "dataset" or self.classification == "database" or self.classification == "database_collection":
                    self.export_menu = QMenu(
                        QString('Export Opus %s to' % self.classification),
                        self.treeview)
                    self.export_menu.setIcon(IconLibrary.icon('export'))
                    self.import_menu = QMenu(
                        QString('Import Opus %s from' % self.classification),
                        self.treeview)
                    self.import_menu.setIcon(IconLibrary.icon('import'))

                    if len(export_choices) > 0:
                        self.export_dynactions = {}
                        for export_type, tool_node in export_choices.iteritems(
                        ):
                            dynaction = QAction(
                                IconLibrary.icon('spreadsheet'), export_type,
                                self.treeview)
                            self.export_menu.addAction(dynaction)
                            self.export_dynactions[export_type] = tool_node
                        QObject.connect(self.export_menu,
                                        SIGNAL("triggered(QAction*)"),
                                        self.dataActionMenuFunctionExport)
                        self.menu.addMenu(self.export_menu)

                    if len(import_choices) > 0:
                        self.import_dynactions = {}
                        for import_type, tool_node in import_choices.iteritems(
                        ):
                            dynaction = QAction(
                                IconLibrary.icon('spreadsheet'), import_type,
                                self.treeview)
                            self.import_menu.addAction(dynaction)
                            self.import_dynactions[import_type] = tool_node
                        QObject.connect(self.import_menu,
                                        SIGNAL("triggered(QAction*)"),
                                        self.dataActionMenuFunctionImport)
                        self.menu.addMenu(self.import_menu)

                    self.menu.addSeparator()

                    # We need to provide the option to open the dataset
                    self.menu.addAction(self.actViewDataset)

        # Now tack on a refresh for all right clicks
        #print "Setting model refresh"
        self.menu.addAction(self.actRefresh)
        self.menu.exec_(QCursor.pos())
Example #21
0
class MSMainWindow(QMainWindow):
    """Gui of the main window"""
    
    #MAX_RECENT_FILES = 10
    #start putting links spyder numpy scipy et tutti quanti
    links=('http://numpy.scipy.org/',
           'http://packages.python.org/spyder/',
           'http://www.riverbankcomputing.co.uk/software/pyqt/intro')
    
    pluginPath=path.normcase('pluginmanager/plugins/')    
    
    def __init__(self, availablePlugins):
        """
        Constructor with all the models needed setup menus
        
        """
        QMainWindow.__init__(self)
        self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks)
        self.plugins = availablePlugins
        self.pluginsInst=[]   
        settings=QSettings('INRA/INSA', '-'.join([QApplication.instance().APPLICATION_NAME_STR, 
                                                  QApplication.instance().VERSION_STR]))  
        self.recentFiles = list(settings.value("RecentFiles").toStringList())
        self.setStyleSheet(stylesheet)
        self.pipeline = MSPipelineToolBar("Pipeline toolbar", parent=self)
        self.addToolBar(0x1,self.pipeline)
        
        self._setupModels()
        self._setupUi()        
        self._setupMenus()

    def _setupModels(self):
        """
        Warning:Causes segfault when horizontal labels set to True
        
        on aura peu etre a la fin un model par sampleList c'est ce qui parait
        le plus logique
        
        """        
        #drag and drop table sample
        self.sampleModel = QStandardItemModel(self)      
        self.sampleModel.setHorizontalHeaderLabels(["Sample", "Class"])
        #treeView1
        self.spectraModel = QStandardItemModel(self)
        #treeview2
        self.peakModel = QStandardItemModel(self)
        #treeview3
        self.clusterModel = QStandardItemModel(self)
 
    def _setupMenus(self):
        #file
        self.fileMenu = QMenu('&File')
        self.fileMenu.setTearOffEnabled(True)
        self.op=QMenu("&Open...",self.fileMenu)
        self.op.setIcon(QIcon(path.normcase("gui/icons/fileopen.png")))
        
        open_=QAction("&Open rawfiles", self)
        open_.setToolTip("Open an mzXML or netCDF file")
        open_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O))
        open_icon=QIcon(path.normcase("gui/icons/fileopen.png"))
        open_.setIcon(open_icon)
        self.op.addAction(open_)
        
        load_=QAction("&Open projects...", self)
        load_.setToolTip("load binary file containing saved objects")
        load_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
        load_icon=QIcon(QPixmap(path.normcase("gui/icons/project_open.png")))
        load_.setIcon(load_icon)
        self.op.addAction(load_)
        
        self.fileMenu.addMenu(self.op)
        
        save_=QAction("&Save...", self)
        save_.setToolTip("save the actual application model")
        save_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
        save_icon=QIcon(path.normcase("gui/icons/save_all.png"))
        save_.setIcon(save_icon)
        self.fileMenu.addAction(save_)
        
        pkl = QAction("&load a peaklist", self) #TODO:load peaklist
        pkl.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_P))
        pkl.setToolTip("load a peaklist and process it")
        pkl.setIcon(QIcon(path.normcase("gui/icons/featuredetect.png")))
        self.fileMenu.addAction(pkl)
        
        convert_=QAction("&Convert...", self)
        convert_.setEnabled(False)
        convert_.setToolTip("Convert a .wiff file if Analyst(c) is installed")        
        convert_icon=QIcon(path.normcase("gui/icons/goto.png"))
        convert_.setIcon(convert_icon)
        self.fileMenu.addAction(convert_)
        
        a = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Launch a batch")
        a.setEnabled(False)
        
        b = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Merge")
        b.setToolTip("Merge MRM file")
        #b.setEnabled(False)
        
        self.fileMenu.addSeparator()
#        
#        for i in xrange(self.MAX_RECENT_FILES):
#            a = QAction('', self)
#            a.setVisible(False)
#            self.fileMenu.addAction(a)
#        
#        for i in xrange(min(self.MAX_RECENT_FILES, len(self.recentFiles))):
#            self.fileMenu.actions()[5+i].setVisible(True)
#            self.fileMenu.actions()[5+i].setText(self.recentFiles[i].split('/')[-1])
            
        
        exit_action =QAction("&Exit", self)
        exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q))
        exit_action.setIcon(QIcon(QPixmap(path.normcase('gui/icons/exit.png'))))
        self.fileMenu.addAction(exit_action)
        
        self.menuBar().addMenu(self.fileMenu)
        
        self.editMenu=QMenu("&Edit")
        self.editMenu.setTearOffEnabled(True)
        self.editMenu.addAction(QIcon(path.normcase('gui/icons/edit_undo.png')), '&Undo...')
        self.editMenu.addAction(QIcon(path.normcase('gui/icons/edit_redo.png')), '&Redo...')
        self.editMenu.actions()[0].setEnabled(False)
        self.editMenu.actions()[1].setEnabled(False)
        self.editMenu.addSeparator()
        self.editMenu.addAction(QIcon(path.normcase('gui/icons/run.png')), '&Preferences')
        self.exportMenu = QMenu("&Export...")
        self.exportMenu.setIcon(QIcon(path.normcase('gui/icons/file_export.png')))
        self.exportMenu.addAction("&Peaklist")        
        self.exportMenu.addAction("&Clusters intensity matrix")
        self.editMenu.addMenu(self.exportMenu)        
        self.menuBar().addMenu(self.editMenu)
        
        
        #view
        self.viewMenu =QMenu("&View")
        self.viewMenu.setTearOffEnabled(True)
        self.viewMenu.addAction(QIcon(path.normcase('gui/icons/window_duplicate')),
                                "&Cascade View", 
                                self.mdiArea.cascadeSubWindows, 
                                QKeySequence(Qt.CTRL + Qt.Key_K))
        self.viewMenu.addAction(QIcon(path.normcase('gui/icons/view_icon')),
                                "&Title View", 
                                self.mdiArea.tileSubWindows, 
                                QKeySequence(Qt.CTRL + Qt.Key_N))
        self.viewMenu.addAction(QIcon(path.normcase("gui/icons/stop_process.png")),
                                "&Close all subWindows",
                                self.mdiArea.closeAllSubWindows,
                                QKeySequence(Qt.CTRL+Qt.Key_W))
        
        self.plotting =QMenu("&Plotting...")
        self.plotting.setIcon(QIcon(QPixmap(path.normcase("gui/icons/plot.png"))))
        self.plotting.addAction("&3D Plot")
        #self.plotting.addAction("&Cytoscape web")
        self.plotting.addAction("&Spectrogram Plot")
        
        #self.multiplePlot = QAction("&Visualize Raw/Treated Data", self)
        #self.multiplePlot.setCheckable(True)
        #self.multiplePlot.setEnabled(False)
        #self.sub_plot_.addAction(self.multiplePlot)
       
        self.viewMenu.addMenu(self.plotting)
        self.viewMenu.addSeparator()
        self.show_hide=QMenu("&Show/Hide")
        m=self.createPopupMenu()
        m.setTitle("&Show/Hide")
        self.viewMenu.addMenu(m)
        #self.pref = QMenu("&Preferences")
       
        #self.pref.addAction(self.multiplePlot)
        #self.viewMenu.addMenu(self.pref)
        self.menuBar().addMenu(self.viewMenu)

        #algorithm
        self.algoMenu= QMenu("&Algorithm")
        self.algoMenu.setTearOffEnabled(True)
        self.preProcessing=QMenu("&PreProcessing(experimental)")
        self.preProcessing.addAction("&Smoothing raw data...")
        self.preProcessing.addAction("&Cut off raw data...")
        self.preProcessing.addAction('&Calibration (mz dimension)')
        self.preProcessing.addAction("&Resize sample...")
        
        self.algoMenu.addMenu(self.preProcessing)
        
        self.peakPickingMenu = QMenu("&Peack Picking & Alignement(XCMS)", self)
        self.peakPickingMenu.setIcon(QIcon(path.normcase("gui/icons/pickedpeakicon.png")))
        
        matched = QAction("&MatchedFiltered", self)
        matched.setIcon(QIcon(path.normcase('gui/icons/RLogo')))
        matched.setToolTip("Peak Detection and Integration using MatchedFiltered algorithm")
        self.peakPickingMenu.addAction(matched)        
        
        centwave=QAction("&CentWave", self)
        centwave.setIcon(QIcon(path.normcase('gui/icons/RLogo')))
        centwave.setToolTip("Peak Detection and Integration using CentWave algorithm")
        self.peakPickingMenu.addAction(centwave)
        #peak_.setShortcut(.QKeySequence(CTRL + Key_P))
       # peak_icon=.QIcon(.QPixmap(path.normcase("gui/icons/pickedpeakicon.png")))
        #peak_.setIcon(peak_icon)
        self.algoMenu.addMenu(self.peakPickingMenu)
        
        self.alignment = QMenu("&Alignment")
        self.alignment.setIcon(QIcon(path.normcase('gui/icons/format_indent_more.png')))
        self.alignment.addAction("&Polynomial fitting(exp)")
        self.alignment.addAction("&DynamicTimeWarping")
        self.alignment.addAction("&ObiWarp")
        self.alignment.actions()[2].setEnabled(False)
        self.algoMenu.addMenu(self.alignment)
        
        self.algoMenu.addAction("Normalization")
        
        clust_ =  QAction("&Clustering", self)
        clust_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L))
        clust_icon=QIcon(QPixmap(path.normcase("gui/icons/cluster.png")))
        clust_.setIcon(clust_icon)
        self.algoMenu.addAction(clust_)
        
        id_ =  QAction("&Identification", self)
        id_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_I))
        id_.setToolTip("Try to identify peaks with several methods")
        id_.setIcon(QIcon(QPixmap(path.normcase("gui/icons/findcompound.png"))))
        self.algoMenu.addAction(id_)
        self.menuBar().addMenu(self.algoMenu)        
        
     
        
        #tools
        self.toolsMenu =QMenu("&Tools")
        self.toolsMenu.setTearOffEnabled(True)
        web =  QAction("&Web Browser", self)
        web.setIcon(QIcon(QPixmap(path.normcase("gui/icons/applications_internet.png"))))
        self.toolsMenu.addAction(web)
        #cyto = QAction("&cytoscape", self)
        #cyto_icon =QIcon(QPixmap(path.normcase("gui/icons/cytoscape.jpeg")))
        #cyto.setIcon(cyto_icon)
        #self.toolsMenu.addAction(cyto)
        editor = QAction("&Editor", self)
        editor.setIcon(QIcon(QPixmap(path.normcase("gui/icons/document_sign.png"))))
        self.toolsMenu.addAction(editor)
        pet=QAction("&Short Periodic Table", self)  
        pet.setIcon(QIcon(QPixmap(path.normcase("gui/icons/pet.jpg"))))
        self.toolsMenu.addAction(pet)
        self.menuBar().addMenu(self.toolsMenu)
        
        #plugins
        self.pluginMenu = QMenu('&Plugins')
        self.pluginMenu.setTearOffEnabled(True)
        instPl=  QAction("&Install a plugin", self)
        instPl.setIcon(QIcon(path.normcase('gui/icons/pluginInstall.png')))
        self.pluginMenu.addAction(instPl)
        self.launchingMenu = QMenu("&Launch PLugins", self)
        self.launchingMenu.setIcon(QIcon(path.normcase('gui/icons/plugin')))
        
        for plug in self.plugins:
            #fullname="".join([self.pluginPath, str(plug)])
            mod=imp.load_source(self.__module__, plug)
            if mod.autoActivation:
                qApp=QApplication.instance()
                name=getattr(mod, 'className')
                cls=getattr(mod, name)
                p=cls(qApp.model, self, parent=self)                
                #p=qApp.pluginManager.loadPlugin(qApp.model, self, plug.split('/')[-1])
                self.pluginsInst.append(p)
            else:
                self.launchingMenu.addAction(plug.split('/')[-1])
        self.pluginMenu.addMenu(self.launchingMenu)
        self.pluginMenu.addAction(QIcon(path.normcase("gui/icons/process_stop.png")),
                                        "&Remove loaded Plugin")
        self.menuBar().addMenu(self.pluginMenu)
        
        #about
        self.aboutMenu= QMenu("&About")
        self.aboutMenu.setTearOffEnabled(True)
        metms = QAction(QIcon(path.normcase('gui/icons/deluge.png')), "&about metMS...", self)
        self.aboutMenu.addAction(metms)
        
        pyqt =  QAction("&about PyQt4...", self)
        pyqt_icon =QIcon(QPixmap(path.normcase("gui/icons/logo_QT4.png")))
        pyqt.setIcon(pyqt_icon)
        self.aboutMenu.addAction(pyqt)
        metms =  QAction("&metMS Documentation", self)
        metms_icon =QIcon(QPixmap(path.normcase("gui/icons/deluge.png")))
        metms.setIcon(metms_icon)
        self.aboutMenu.addAction(metms)
        self.menuBar().addMenu(self.aboutMenu)
        

    def _setupUi(self, background=None):
        """        
        Make the GUI
        
        """
        #mdi
        self.mdiArea = MSMdiArea(self)
        self.mdiArea.setBackground(QBrush(QPixmap(path.normcase('gui/icons/blac2.png'))))#QColor(Qt.blue).darker()))
        self.setCentralWidget(self.mdiArea)
        
        
        #sample dock widget
        self.sampleDockWidget = QDockWidget("Samples", self)
        #sampleWidget = QWidget()
        self.sampleTableView = MSDragFromTableView()
        self.sampleTableView.setModel(self.sampleModel)
        self.sampleTableView.setSelectionBehavior(1)
        self.sampleTableView.verticalHeader().hide()
        self.sampleTableView.verticalHeader().setDefaultSectionSize(15)        
        self.sampleTableView.horizontalHeader().setDefaultSectionSize(150)
        

        self.sampleDockWidget.setWidget(self.sampleTableView)#sampleWidget)
        self.sampleDockWidget.visible=True
        
        
        #workflow dock
        self.workflowDockWidget = QDockWidget("Visualizer", self)
        self.workflowDockWidget.visible = True

        a=QWidget(self)
        v=QVBoxLayout(a)
        q=QToolBar()
        #self.workingSample = QLabel("Working Sample:None")
        #q.addWidget(self.workingSample)
        q.addWidget(QLabel("ppm :"))
        self.ppmEditer=QDoubleSpinBox()
        self.usePpm=QCheckBox("use ?")  
        q.addWidget(self.ppmEditer)
        q.addWidget(self.usePpm)
        
        q.addSeparator()
        
        self.removeButton=QToolButton(self)
        self.removeButton.setIcon(QIcon(path.normcase("gui/icons/delete.png")))           
        q.addWidget(self.removeButton)
        
        self.markAsGood=QAction(QIcon(path.normcase("gui/icons/button_ok.png")),"mark peak as good", self)
        self.markAsBad=QAction(QIcon(path.normcase("gui/icons/stop.png")), "mark peak as bad", self)
        self.hideItem = QAction(QIcon(path.normcase("gui/icons/list_remove.png")), "Hide Item", self)
        
        q.addAction(self.markAsGood)
        q.addAction(self.markAsBad)
        q.addAction(self.hideItem)
        v.addWidget(q)        
        
        
        self.tabWidget = QTabWidget()
        self.tab = QWidget()
        verticalLayout = QVBoxLayout(self.tab)
        self.treeView = MSToDropTableView()
        self.treeView.verticalHeader().setDefaultSectionSize(20)
        
        self.treeView.setModel(self.spectraModel)
        self.spectraLabel = QLabel("Sample: None")
        verticalLayout.addWidget(self.treeView)
        verticalLayout.addWidget(self.spectraLabel)
        self.tabWidget.addTab(self.tab, QIcon(path.normcase("gui/icons/spectrumicon.png")),"Spectra")
        
        self.tab_2 = QWidget()
        verticalLayout_4 = QVBoxLayout(self.tab_2)
        self.treeView_2 = MSToDropTableView()#MSTreeView(self.tab_2)# QTableView(self)#
        self.treeView_2.verticalHeader().setDefaultSectionSize(20)
        self.treeView_2.setModel(self.peakModel)
        self.peakLabel = QLabel("Sample: None")
        verticalLayout_4.addWidget(self.treeView_2)
        verticalLayout_4.addWidget(self.peakLabel)
        self.tabWidget.addTab(self.tab_2,QIcon(path.normcase("gui/icons/peakicon.png")), "Peaks List")
        
        self.tab_3 = QWidget()
        verticalLayout_5 = QVBoxLayout(self.tab_3)
        self.treeView_3 = MSToDropTreeView()
        self.treeView_3.setAnimated(True)
        self.treeView_3.setModel(self.clusterModel)
        self.clusterLabel = QLabel("Sample: None")
        verticalLayout_5.addWidget(self.treeView_3)
        verticalLayout_5.addWidget(self.clusterLabel)
        self.tabWidget.addTab(self.tab_3, QIcon(path.normcase("gui/icons/clustering.png")), "Clusters")
        
        self.tabWidget.setCurrentIndex(0)
        
        for l in (self.spectraLabel, self.peakLabel, self.clusterLabel):
            l.setAutoFillBackground(True)
            
        v.addWidget(self.tabWidget)
        self.workflowDockWidget.setWidget(a)
        self.addDockWidget(Qt.DockWidgetArea(0x2),self.workflowDockWidget)        
        
                
        from gui.MetBaseGui import MSIsoCalculator
        self.isoCalc = MSIsoCalculator(self)
        self.isoCalcDockWidget=QDockWidget('isotopes calculation', self)
        self.isoCalcDockWidget.setWidget(self.isoCalc)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.isoCalcDockWidget)
        self.isoCalcDockWidget.setVisible(False)
        self.isoCalcDockWidget.visible=False
        
        from gui.MetBaseGui import FormulaGenerator
        self.generator=FormulaGenerator(self)
        self.generatorDockWidget=QDockWidget('formula generator', self)
        self.generatorDockWidget.setWidget(self.generator)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.generatorDockWidget)
        self.generatorDockWidget.setVisible(False)
        self.generatorDockWidget.visible=False
        
        self.compoundTreeView = MSCompoundTreeView(self)
        self.compoundDockWidget = QDockWidget("Compounds", self)
        self.compoundDockWidget.setWidget(self.compoundTreeView)
        self.addDockWidget(Qt.DockWidgetArea(0x2),self.compoundDockWidget)
        self.compoundDockWidget.setVisible(False)
        self.compoundDockWidget.visible=False
        
        self.comparativeTableView = QTableView(self)
        self.comparativeTableView.horizontalHeader().setStretchLastSection(True)
        self.comparativeTableView.verticalHeader().setDefaultSectionSize(20)
        self.comparativeDock = QDockWidget("Comparative View", self)
        self.comparativeDock.setWidget(self.comparativeTableView)
        self.addDockWidget(Qt.DockWidgetArea(0x8), self.comparativeDock)
        self.comparativeDock.setVisible(False)
        self.comparativeDock.visible = False
        
        self.tabifyDockWidget(self.compoundDockWidget, self.isoCalcDockWidget)
        self.tabifyDockWidget(self.isoCalcDockWidget, self.workflowDockWidget )
        self.tabifyDockWidget(self.workflowDockWidget, self.generatorDockWidget)
        #set the end
        
        #WARNING: possible that the internal shell widget cause random segfault
        #with the error of QObject::killTimers...? not sure !
        self.shell = QWidget()#InternalShell(namespace={'metms': QApplication.instance()}, 
                     #              parent=self, 
                     #              multithreaded=False)
        self.shellDock = QDockWidget("Python Shell", self)
        self.shellDock.setWindowIcon(QIcon(path.normcase('gui/icons/stop.png')))
        self.shellDock.setWidget(self.shell)
        self.shellDock.setMinimumWidth(255)
        self.shellDock.visible=True
        self.addDockWidget(0x2, self.shellDock)

        self.addDockWidget(0x2, self.sampleDockWidget)
        self.tabifyDockWidget(self.shellDock, self.sampleDockWidget)
        
        self.pb = QProgressBar(self)
        self.pb.setMaximumWidth(245)
        
        self.stopProcess = QToolButton(self)
        self.stopProcess.setIcon(QIcon(path.normcase("gui/icons/process_stop.png")))        
        m = QMenu()
        #self.connect(m, SIGNAL('triggered(QAction*'), QApplication.instance().taskManager.abortByName)
        self.stopProcess.setMenu(m)
        self.stopProcess.setPopupMode(1) #Menu Button
        #self.connect(self.stopProcess, SIGNAL("clicked()"), self.stopThread)
        
        self.statusBar().addPermanentWidget(self.stopProcess)
        self.statusBar().addPermanentWidget(self.pb)
    
    def updateStopProcessMenu(self):
        """
        update the menu of the stop process
        button, based directly on the processes
        stored by the task manager
        
        """
        self.stopProcess.menu().clear()
        for c in QApplication.instance().taskManager:
            self.stopProcess.menu().addAction(c.title)
        
        #QApplication.instance().taskManager.abort(QApplication.instance().taskManager[-1])
        
    def addMdiSubWindow(self, plot, title="", showMaximized=False):
        """ 
        Allow addition of new window in the mdiarea
        
        """        
        win=self.mdiArea.addSubWindow(plot)
        #print "widget parent", plot.parent()
        win.setAttribute(Qt.WA_DeleteOnClose)
        #win.connect(win, SIGNAL('destroyed(QObject *)'), self.testdestroy)
        #plot.setParent(win)
        win.setWindowTitle(title)
        if showMaximized:
            win.showMaximized()
        else:
            win.resize(400, 300)
        win.show()
        return win
   

           
    def updateTreeView(self):
        """
        Tree View update switch spectre/chromato
        
        """
        if self.treeView.model() == self.spectraModel:
            self.treeView.setModel(self.chromaModel)
            self.tabWidget.setTabText(0, "Chroma")
        else:
            self.treeView.setModel(self.spectraModel)
            #self.treeView.setSelectionMode(1)
            self.tabWidget.setTabText(0, "Spectra")
    
    def addTreeViewModel (self,model1, model2):
        """Add a model """
        self.chromaModel.appendRow(model1)
        self.spectraModel.appendRow(model2)
    
    
    def _actionHovered(self, action):
        """emulate tooltip cause they do not work that much"""
        tip = action.toolTip()
        QToolTip.showText(QCursor.pos(), tip)
    

    def showErrorMessage(self, title, string):
        QMessageBox.critical(self, title, string, 0, 0)
    
    
    def showWarningMessage(self, title, string):
        return QMessageBox.warning(self, title, string, QMessageBox.Ok|QMessageBox.Cancel)
    
    
    def showInformationMessage(self, title, string):
        QMessageBox.information(self, title, string, 0)
        
    
    def updateProgressBar(self, i):
        """update the value of the progress bar for all the treatment"""
        
        self.pb.setValue(min(i, 100))

    def to_indetermined_mode(self):
        self.pb.setMaximum(0)
        
    
    def to_determined_mode(self):
        self.pb.setMaximum(100)
        
    
    def showInStatusBar(self, string, time=5000):
        self.statusBar().showMessage(string, time)
    
    
    
    def addInterpreterDock(self, shell):
        self.shellDock = QDockWidget(self)
        self.shellDock.setWidget(shell)
        self.shellDock.setWindowTitle("shell")
        self.addDockWidget(0x2, self.shellDock)
        
    
    
    def showMetMSInformation(self):
        
        QMessageBox.about(self,
            self.tr("About %1").arg("metMS"),
            self.tr("""<b>%1 %2</b>
            <br>metabolite Mass Spectrometry
            <p>Copyright &copy; 2010 Marco INSA, INRA
            <br>Licensed under the terms of the CeciLL License
            <p>Developed and maintained by Marco
            <br>Bug reports and feature requests: 
            <a href="http://github.com/jerkos/metms">metMS site</a><br>
            Discussions around the project: 
            <a href="http://groups.google.com/group/spyderlib">Google Group</a>
            <p>This project is part of the BRIDGE project
            <p>Python %3, Qt %4, PyQt %5""") \
            .arg("metMS").arg(__version__) \
            .arg(platform.python_version()).arg(QT_VERSION_STR) \
            .arg(PYQT_VERSION_STR))
Example #22
0
class MSMainWindow(QMainWindow):
    """Gui of the main window"""

    # MAX_RECENT_FILES = 10
    # start putting links spyder numpy scipy et tutti quanti
    links = (
        "http://numpy.scipy.org/",
        "http://packages.python.org/spyder/",
        "http://www.riverbankcomputing.co.uk/software/pyqt/intro",
    )

    pluginPath = path.normcase("pluginmanager/plugins/")

    def __init__(self, availablePlugins):
        """
        Constructor with all the models needed setup menus
        
        """
        QMainWindow.__init__(self)
        self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks)
        self.plugins = availablePlugins
        self.pluginsInst = []
        settings = QSettings(
            "INRA/INSA", "-".join([QApplication.instance().APPLICATION_NAME_STR, QApplication.instance().VERSION_STR])
        )
        self.recentFiles = list(settings.value("RecentFiles").toStringList())
        self.setStyleSheet(stylesheet)
        self.pipeline = MSPipelineToolBar("Pipeline toolbar", parent=self)
        self.addToolBar(0x1, self.pipeline)

        self._setupModels()
        self._setupUi()
        self._setupMenus()

    def _setupModels(self):
        """
        Warning:Causes segfault when horizontal labels set to True
        
        on aura peu etre a la fin un model par sampleList c'est ce qui parait
        le plus logique
        
        """
        # drag and drop table sample
        self.sampleModel = QStandardItemModel(self)
        self.sampleModel.setHorizontalHeaderLabels(["Sample", "Class"])
        # treeView1
        self.spectraModel = QStandardItemModel(self)
        # treeview2
        self.peakModel = QStandardItemModel(self)
        # treeview3
        self.clusterModel = QStandardItemModel(self)

    def _setupMenus(self):
        # file
        self.fileMenu = QMenu("&File")
        self.fileMenu.setTearOffEnabled(True)
        self.op = QMenu("&Open...", self.fileMenu)
        self.op.setIcon(QIcon(path.normcase("gui/icons/fileopen.png")))

        open_ = QAction("&Open rawfiles", self)
        open_.setToolTip("Open an mzXML or netCDF file")
        open_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O))
        open_icon = QIcon(path.normcase("gui/icons/fileopen.png"))
        open_.setIcon(open_icon)
        self.op.addAction(open_)

        load_ = QAction("&Open projects...", self)
        load_.setToolTip("load binary file containing saved objects")
        load_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
        load_icon = QIcon(QPixmap(path.normcase("gui/icons/project_open.png")))
        load_.setIcon(load_icon)
        self.op.addAction(load_)

        self.fileMenu.addMenu(self.op)

        save_ = QAction("&Save...", self)
        save_.setToolTip("save the actual application model")
        save_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
        save_icon = QIcon(path.normcase("gui/icons/save_all.png"))
        save_.setIcon(save_icon)
        self.fileMenu.addAction(save_)

        pkl = QAction("&load a peaklist", self)  # TODO:load peaklist
        pkl.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_P))
        pkl.setToolTip("load a peaklist and process it")
        pkl.setIcon(QIcon(path.normcase("gui/icons/featuredetect.png")))
        self.fileMenu.addAction(pkl)

        convert_ = QAction("&Convert...", self)
        convert_.setEnabled(False)
        convert_.setToolTip("Convert a .wiff file if Analyst(c) is installed")
        convert_icon = QIcon(path.normcase("gui/icons/goto.png"))
        convert_.setIcon(convert_icon)
        self.fileMenu.addAction(convert_)

        a = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Launch a batch")
        a.setEnabled(False)

        b = self.fileMenu.addAction(QIcon(path.normcase("gui/icons/process.png")), "&Merge")
        b.setToolTip("Merge MRM file")
        # b.setEnabled(False)

        self.fileMenu.addSeparator()
        #
        #        for i in xrange(self.MAX_RECENT_FILES):
        #            a = QAction('', self)
        #            a.setVisible(False)
        #            self.fileMenu.addAction(a)
        #
        #        for i in xrange(min(self.MAX_RECENT_FILES, len(self.recentFiles))):
        #            self.fileMenu.actions()[5+i].setVisible(True)
        #            self.fileMenu.actions()[5+i].setText(self.recentFiles[i].split('/')[-1])

        exit_action = QAction("&Exit", self)
        exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q))
        exit_action.setIcon(QIcon(QPixmap(path.normcase("gui/icons/exit.png"))))
        self.fileMenu.addAction(exit_action)

        self.menuBar().addMenu(self.fileMenu)

        self.editMenu = QMenu("&Edit")
        self.editMenu.setTearOffEnabled(True)
        self.editMenu.addAction(QIcon(path.normcase("gui/icons/edit_undo.png")), "&Undo...")
        self.editMenu.addAction(QIcon(path.normcase("gui/icons/edit_redo.png")), "&Redo...")
        self.editMenu.actions()[0].setEnabled(False)
        self.editMenu.actions()[1].setEnabled(False)
        self.editMenu.addSeparator()
        self.editMenu.addAction(QIcon(path.normcase("gui/icons/run.png")), "&Preferences")
        self.exportMenu = QMenu("&Export...")
        self.exportMenu.setIcon(QIcon(path.normcase("gui/icons/file_export.png")))
        self.exportMenu.addAction("&Peaklist")
        self.exportMenu.addAction("&Clusters intensity matrix")
        self.editMenu.addMenu(self.exportMenu)
        self.menuBar().addMenu(self.editMenu)

        # view
        self.viewMenu = QMenu("&View")
        self.viewMenu.setTearOffEnabled(True)
        self.viewMenu.addAction(
            QIcon(path.normcase("gui/icons/window_duplicate")),
            "&Cascade View",
            self.mdiArea.cascadeSubWindows,
            QKeySequence(Qt.CTRL + Qt.Key_K),
        )
        self.viewMenu.addAction(
            QIcon(path.normcase("gui/icons/view_icon")),
            "&Title View",
            self.mdiArea.tileSubWindows,
            QKeySequence(Qt.CTRL + Qt.Key_N),
        )
        self.viewMenu.addAction(
            QIcon(path.normcase("gui/icons/stop_process.png")),
            "&Close all subWindows",
            self.mdiArea.closeAllSubWindows,
            QKeySequence(Qt.CTRL + Qt.Key_W),
        )

        self.plotting = QMenu("&Plotting...")
        self.plotting.setIcon(QIcon(QPixmap(path.normcase("gui/icons/plot.png"))))
        self.plotting.addAction("&3D Plot")
        # self.plotting.addAction("&Cytoscape web")
        self.plotting.addAction("&Spectrogram Plot")

        # self.multiplePlot = QAction("&Visualize Raw/Treated Data", self)
        # self.multiplePlot.setCheckable(True)
        # self.multiplePlot.setEnabled(False)
        # self.sub_plot_.addAction(self.multiplePlot)

        self.viewMenu.addMenu(self.plotting)
        self.viewMenu.addSeparator()
        self.show_hide = QMenu("&Show/Hide")
        m = self.createPopupMenu()
        m.setTitle("&Show/Hide")
        self.viewMenu.addMenu(m)
        # self.pref = QMenu("&Preferences")

        # self.pref.addAction(self.multiplePlot)
        # self.viewMenu.addMenu(self.pref)
        self.menuBar().addMenu(self.viewMenu)

        # algorithm
        self.algoMenu = QMenu("&Algorithm")
        self.algoMenu.setTearOffEnabled(True)
        self.preProcessing = QMenu("&PreProcessing(experimental)")
        self.preProcessing.addAction("&Smoothing raw data...")
        self.preProcessing.addAction("&Cut off raw data...")
        self.preProcessing.addAction("&Calibration (mz dimension)")
        self.preProcessing.addAction("&Resize sample...")

        self.algoMenu.addMenu(self.preProcessing)

        self.peakPickingMenu = QMenu("&Peack Picking & Alignement(XCMS)", self)
        self.peakPickingMenu.setIcon(QIcon(path.normcase("gui/icons/pickedpeakicon.png")))

        matched = QAction("&MatchedFiltered", self)
        matched.setIcon(QIcon(path.normcase("gui/icons/RLogo")))
        matched.setToolTip("Peak Detection and Integration using MatchedFiltered algorithm")
        self.peakPickingMenu.addAction(matched)

        centwave = QAction("&CentWave", self)
        centwave.setIcon(QIcon(path.normcase("gui/icons/RLogo")))
        centwave.setToolTip("Peak Detection and Integration using CentWave algorithm")
        self.peakPickingMenu.addAction(centwave)
        # peak_.setShortcut(.QKeySequence(CTRL + Key_P))
        # peak_icon=.QIcon(.QPixmap(path.normcase("gui/icons/pickedpeakicon.png")))
        # peak_.setIcon(peak_icon)
        self.algoMenu.addMenu(self.peakPickingMenu)

        self.alignment = QMenu("&Alignment")
        self.alignment.setIcon(QIcon(path.normcase("gui/icons/format_indent_more.png")))
        self.alignment.addAction("&Polynomial fitting(exp)")
        self.alignment.addAction("&DynamicTimeWarping")
        self.alignment.addAction("&ObiWarp")
        self.alignment.actions()[2].setEnabled(False)
        self.algoMenu.addMenu(self.alignment)

        self.algoMenu.addAction("Normalization")

        clust_ = QAction("&Clustering", self)
        clust_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L))
        clust_icon = QIcon(QPixmap(path.normcase("gui/icons/cluster.png")))
        clust_.setIcon(clust_icon)
        self.algoMenu.addAction(clust_)

        id_ = QAction("&Identification", self)
        id_.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_I))
        id_.setToolTip("Try to identify peaks with several methods")
        id_.setIcon(QIcon(QPixmap(path.normcase("gui/icons/findcompound.png"))))
        self.algoMenu.addAction(id_)
        self.menuBar().addMenu(self.algoMenu)

        # tools
        self.toolsMenu = QMenu("&Tools")
        self.toolsMenu.setTearOffEnabled(True)
        web = QAction("&Web Browser", self)
        web.setIcon(QIcon(QPixmap(path.normcase("gui/icons/applications_internet.png"))))
        self.toolsMenu.addAction(web)
        # cyto = QAction("&cytoscape", self)
        # cyto_icon =QIcon(QPixmap(path.normcase("gui/icons/cytoscape.jpeg")))
        # cyto.setIcon(cyto_icon)
        # self.toolsMenu.addAction(cyto)
        editor = QAction("&Editor", self)
        editor.setIcon(QIcon(QPixmap(path.normcase("gui/icons/document_sign.png"))))
        self.toolsMenu.addAction(editor)
        pet = QAction("&Short Periodic Table", self)
        pet.setIcon(QIcon(QPixmap(path.normcase("gui/icons/pet.jpg"))))
        self.toolsMenu.addAction(pet)
        self.menuBar().addMenu(self.toolsMenu)

        # plugins
        self.pluginMenu = QMenu("&Plugins")
        self.pluginMenu.setTearOffEnabled(True)
        instPl = QAction("&Install a plugin", self)
        instPl.setIcon(QIcon(path.normcase("gui/icons/pluginInstall.png")))
        self.pluginMenu.addAction(instPl)
        self.launchingMenu = QMenu("&Launch PLugins", self)
        self.launchingMenu.setIcon(QIcon(path.normcase("gui/icons/plugin")))

        for plug in self.plugins:
            # fullname="".join([self.pluginPath, str(plug)])
            mod = imp.load_source(self.__module__, plug)
            if mod.autoActivation:
                qApp = QApplication.instance()
                name = getattr(mod, "className")
                cls = getattr(mod, name)
                p = cls(qApp.model, self, parent=self)
                # p=qApp.pluginManager.loadPlugin(qApp.model, self, plug.split('/')[-1])
                self.pluginsInst.append(p)
            else:
                self.launchingMenu.addAction(plug.split("/")[-1])
        self.pluginMenu.addMenu(self.launchingMenu)
        self.pluginMenu.addAction(QIcon(path.normcase("gui/icons/process_stop.png")), "&Remove loaded Plugin")
        self.menuBar().addMenu(self.pluginMenu)

        # about
        self.aboutMenu = QMenu("&About")
        self.aboutMenu.setTearOffEnabled(True)
        metms = QAction(QIcon(path.normcase("gui/icons/deluge.png")), "&about metMS...", self)
        self.aboutMenu.addAction(metms)

        pyqt = QAction("&about PyQt4...", self)
        pyqt_icon = QIcon(QPixmap(path.normcase("gui/icons/logo_QT4.png")))
        pyqt.setIcon(pyqt_icon)
        self.aboutMenu.addAction(pyqt)
        metms = QAction("&metMS Documentation", self)
        metms_icon = QIcon(QPixmap(path.normcase("gui/icons/deluge.png")))
        metms.setIcon(metms_icon)
        self.aboutMenu.addAction(metms)
        self.menuBar().addMenu(self.aboutMenu)

    def _setupUi(self, background=None):
        """        
        Make the GUI
        
        """
        # mdi
        self.mdiArea = MSMdiArea(self)
        self.mdiArea.setBackground(QBrush(QPixmap(path.normcase("gui/icons/blac2.png"))))  # QColor(Qt.blue).darker()))
        self.setCentralWidget(self.mdiArea)

        # sample dock widget
        self.sampleDockWidget = QDockWidget("Samples", self)
        # sampleWidget = QWidget()
        self.sampleTableView = MSDragFromTableView()
        self.sampleTableView.setModel(self.sampleModel)
        self.sampleTableView.setSelectionBehavior(1)
        self.sampleTableView.verticalHeader().hide()
        self.sampleTableView.verticalHeader().setDefaultSectionSize(15)
        self.sampleTableView.horizontalHeader().setDefaultSectionSize(150)

        self.sampleDockWidget.setWidget(self.sampleTableView)  # sampleWidget)
        self.sampleDockWidget.visible = True

        # workflow dock
        self.workflowDockWidget = QDockWidget("Visualizer", self)
        self.workflowDockWidget.visible = True

        a = QWidget(self)
        v = QVBoxLayout(a)
        q = QToolBar()
        # self.workingSample = QLabel("Working Sample:None")
        # q.addWidget(self.workingSample)
        q.addWidget(QLabel("ppm :"))
        self.ppmEditer = QDoubleSpinBox()
        self.usePpm = QCheckBox("use ?")
        q.addWidget(self.ppmEditer)
        q.addWidget(self.usePpm)

        q.addSeparator()

        self.removeButton = QToolButton(self)
        self.removeButton.setIcon(QIcon(path.normcase("gui/icons/delete.png")))
        q.addWidget(self.removeButton)

        self.markAsGood = QAction(QIcon(path.normcase("gui/icons/button_ok.png")), "mark peak as good", self)
        self.markAsBad = QAction(QIcon(path.normcase("gui/icons/stop.png")), "mark peak as bad", self)
        self.hideItem = QAction(QIcon(path.normcase("gui/icons/list_remove.png")), "Hide Item", self)

        q.addAction(self.markAsGood)
        q.addAction(self.markAsBad)
        q.addAction(self.hideItem)
        v.addWidget(q)

        self.tabWidget = QTabWidget()
        self.tab = QWidget()
        verticalLayout = QVBoxLayout(self.tab)
        self.treeView = MSToDropTableView()
        self.treeView.verticalHeader().setDefaultSectionSize(20)

        self.treeView.setModel(self.spectraModel)
        self.spectraLabel = QLabel("Sample: None")
        verticalLayout.addWidget(self.treeView)
        verticalLayout.addWidget(self.spectraLabel)
        self.tabWidget.addTab(self.tab, QIcon(path.normcase("gui/icons/spectrumicon.png")), "Spectra")

        self.tab_2 = QWidget()
        verticalLayout_4 = QVBoxLayout(self.tab_2)
        self.treeView_2 = MSToDropTableView()  # MSTreeView(self.tab_2)# QTableView(self)#
        self.treeView_2.verticalHeader().setDefaultSectionSize(20)
        self.treeView_2.setModel(self.peakModel)
        self.peakLabel = QLabel("Sample: None")
        verticalLayout_4.addWidget(self.treeView_2)
        verticalLayout_4.addWidget(self.peakLabel)
        self.tabWidget.addTab(self.tab_2, QIcon(path.normcase("gui/icons/peakicon.png")), "Peaks List")

        self.tab_3 = QWidget()
        verticalLayout_5 = QVBoxLayout(self.tab_3)
        self.treeView_3 = MSToDropTreeView()
        self.treeView_3.setAnimated(True)
        self.treeView_3.setModel(self.clusterModel)
        self.clusterLabel = QLabel("Sample: None")
        verticalLayout_5.addWidget(self.treeView_3)
        verticalLayout_5.addWidget(self.clusterLabel)
        self.tabWidget.addTab(self.tab_3, QIcon(path.normcase("gui/icons/clustering.png")), "Clusters")

        self.tabWidget.setCurrentIndex(0)

        for l in (self.spectraLabel, self.peakLabel, self.clusterLabel):
            l.setAutoFillBackground(True)

        v.addWidget(self.tabWidget)
        self.workflowDockWidget.setWidget(a)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.workflowDockWidget)

        from gui.MetBaseGui import MSIsoCalculator

        self.isoCalc = MSIsoCalculator(self)
        self.isoCalcDockWidget = QDockWidget("isotopes calculation", self)
        self.isoCalcDockWidget.setWidget(self.isoCalc)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.isoCalcDockWidget)
        self.isoCalcDockWidget.setVisible(False)
        self.isoCalcDockWidget.visible = False

        from gui.MetBaseGui import FormulaGenerator

        self.generator = FormulaGenerator(self)
        self.generatorDockWidget = QDockWidget("formula generator", self)
        self.generatorDockWidget.setWidget(self.generator)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.generatorDockWidget)
        self.generatorDockWidget.setVisible(False)
        self.generatorDockWidget.visible = False

        self.compoundTreeView = MSCompoundTreeView(self)
        self.compoundDockWidget = QDockWidget("Compounds", self)
        self.compoundDockWidget.setWidget(self.compoundTreeView)
        self.addDockWidget(Qt.DockWidgetArea(0x2), self.compoundDockWidget)
        self.compoundDockWidget.setVisible(False)
        self.compoundDockWidget.visible = False

        self.comparativeTableView = QTableView(self)
        self.comparativeTableView.horizontalHeader().setStretchLastSection(True)
        self.comparativeTableView.verticalHeader().setDefaultSectionSize(20)
        self.comparativeDock = QDockWidget("Comparative View", self)
        self.comparativeDock.setWidget(self.comparativeTableView)
        self.addDockWidget(Qt.DockWidgetArea(0x8), self.comparativeDock)
        self.comparativeDock.setVisible(False)
        self.comparativeDock.visible = False

        self.tabifyDockWidget(self.compoundDockWidget, self.isoCalcDockWidget)
        self.tabifyDockWidget(self.isoCalcDockWidget, self.workflowDockWidget)
        self.tabifyDockWidget(self.workflowDockWidget, self.generatorDockWidget)
        # set the end

        # WARNING: possible that the internal shell widget cause random segfault
        # with the error of QObject::killTimers...? not sure !
        self.shell = QWidget()  # InternalShell(namespace={'metms': QApplication.instance()},
        #              parent=self,
        #              multithreaded=False)
        self.shellDock = QDockWidget("Python Shell", self)
        self.shellDock.setWindowIcon(QIcon(path.normcase("gui/icons/stop.png")))
        self.shellDock.setWidget(self.shell)
        self.shellDock.setMinimumWidth(255)
        self.shellDock.visible = True
        self.addDockWidget(0x2, self.shellDock)

        self.addDockWidget(0x2, self.sampleDockWidget)
        self.tabifyDockWidget(self.shellDock, self.sampleDockWidget)

        self.pb = QProgressBar(self)
        self.pb.setMaximumWidth(245)

        self.stopProcess = QToolButton(self)
        self.stopProcess.setIcon(QIcon(path.normcase("gui/icons/process_stop.png")))
        m = QMenu()
        # self.connect(m, SIGNAL('triggered(QAction*'), QApplication.instance().taskManager.abortByName)
        self.stopProcess.setMenu(m)
        self.stopProcess.setPopupMode(1)  # Menu Button
        # self.connect(self.stopProcess, SIGNAL("clicked()"), self.stopThread)

        self.statusBar().addPermanentWidget(self.stopProcess)
        self.statusBar().addPermanentWidget(self.pb)

    def updateStopProcessMenu(self):
        """
        update the menu of the stop process
        button, based directly on the processes
        stored by the task manager
        
        """
        self.stopProcess.menu().clear()
        for c in QApplication.instance().taskManager:
            self.stopProcess.menu().addAction(c.title)

        # QApplication.instance().taskManager.abort(QApplication.instance().taskManager[-1])

    def addMdiSubWindow(self, plot, title="", showMaximized=False):
        """ 
        Allow addition of new window in the mdiarea
        
        """
        win = self.mdiArea.addSubWindow(plot)
        # print "widget parent", plot.parent()
        win.setAttribute(Qt.WA_DeleteOnClose)
        # win.connect(win, SIGNAL('destroyed(QObject *)'), self.testdestroy)
        # plot.setParent(win)
        win.setWindowTitle(title)
        if showMaximized:
            win.showMaximized()
        else:
            win.resize(400, 300)
        win.show()
        return win

    def updateTreeView(self):
        """
        Tree View update switch spectre/chromato
        
        """
        if self.treeView.model() == self.spectraModel:
            self.treeView.setModel(self.chromaModel)
            self.tabWidget.setTabText(0, "Chroma")
        else:
            self.treeView.setModel(self.spectraModel)
            # self.treeView.setSelectionMode(1)
            self.tabWidget.setTabText(0, "Spectra")

    def addTreeViewModel(self, model1, model2):
        """Add a model """
        self.chromaModel.appendRow(model1)
        self.spectraModel.appendRow(model2)

    def _actionHovered(self, action):
        """emulate tooltip cause they do not work that much"""
        tip = action.toolTip()
        QToolTip.showText(QCursor.pos(), tip)

    def showErrorMessage(self, title, string):
        QMessageBox.critical(self, title, string, 0, 0)

    def showWarningMessage(self, title, string):
        return QMessageBox.warning(self, title, string, QMessageBox.Ok | QMessageBox.Cancel)

    def showInformationMessage(self, title, string):
        QMessageBox.information(self, title, string, 0)

    def updateProgressBar(self, i):
        """update the value of the progress bar for all the treatment"""

        self.pb.setValue(min(i, 100))

    def to_indetermined_mode(self):
        self.pb.setMaximum(0)

    def to_determined_mode(self):
        self.pb.setMaximum(100)

    def showInStatusBar(self, string, time=5000):
        self.statusBar().showMessage(string, time)

    def addInterpreterDock(self, shell):
        self.shellDock = QDockWidget(self)
        self.shellDock.setWidget(shell)
        self.shellDock.setWindowTitle("shell")
        self.addDockWidget(0x2, self.shellDock)

    def showMetMSInformation(self):

        QMessageBox.about(
            self,
            self.tr("About %1").arg("metMS"),
            self.tr(
                """<b>%1 %2</b>
            <br>metabolite Mass Spectrometry
            <p>Copyright &copy; 2010 Marco INSA, INRA
            <br>Licensed under the terms of the CeciLL License
            <p>Developed and maintained by Marco
            <br>Bug reports and feature requests: 
            <a href="http://github.com/jerkos/metms">metMS site</a><br>
            Discussions around the project: 
            <a href="http://groups.google.com/group/spyderlib">Google Group</a>
            <p>This project is part of the BRIDGE project
            <p>Python %3, Qt %4, PyQt %5"""
            )
            .arg("metMS")
            .arg(__version__)
            .arg(platform.python_version())
            .arg(QT_VERSION_STR)
            .arg(PYQT_VERSION_STR),
        )
Example #23
0
class CartoDBPlugin(QObject):
    # initialize plugin directory
    PLUGIN_DIR = os.path.dirname(os.path.abspath(__file__))

    def __init__(self, iface):
        QObject.__init__(self)
        QgsMessageLog.logMessage(
            'GDAL Version: ' + str(gdal.VersionInfo('VERSION_NUM')),
            'CartoDB Plugin', QgsMessageLog.INFO)

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

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

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

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

        # SQLite available?
        driverName = "SQLite"
        self.sqLiteDrv = ogr.GetDriverByName(driverName)
        if self.sqLiteDrv is None:
            QgsMessageLog.logMessage('SQLite driver not found',
                                     'CartoDB Plugin', QgsMessageLog.CRITICAL)
        else:
            QgsMessageLog.logMessage('SQLite driver is found',
                                     'CartoDB Plugin', QgsMessageLog.INFO)
            self.databasePath = CartoDBPlugin.PLUGIN_DIR + '/db/database.sqlite'
            shutil.copyfile(
                CartoDBPlugin.PLUGIN_DIR + '/db/init_database.sqlite',
                self.databasePath)
        self.layers = []
        self.countLoadingLayers = 0
        self.countLoadedLayers = 0

        self._cdbMenu = None
        self._mainAction = None
        self._loadDataAction = None
        self._createVizAction = None
        self._addSQLAction = None
        self.toolbar = CartoDBToolbar()
        self._toolbarAction = None
        self._menu = None

    def initGui(self):
        self._cdbMenu = QMenu("CartoDB plugin", self.iface.mainWindow())
        self._cdbMenu.setIcon(QIcon(":/plugins/qgis-cartodb/images/icon.png"))
        self._mainAction = QAction(self.tr('Add CartoDB Layer'),
                                   self.iface.mainWindow())
        self._mainAction.setIcon(
            QIcon(":/plugins/qgis-cartodb/images/icons/add.png"))
        self._loadDataAction = QAction(self.tr('Upload layers to CartoDB'),
                                       self.iface.mainWindow())
        self._loadDataAction.setIcon(
            QIcon(":/plugins/qgis-cartodb/images/icons/upload.png"))
        self._createVizAction = QAction(self.tr('Create New Map'),
                                        self.iface.mainWindow())
        self._createVizAction.setIcon(
            QIcon(":/plugins/qgis-cartodb/images/icons/map.png"))
        self._addSQLAction = QAction(self.tr('Add SQL CartoDB Layer'),
                                     self.iface.mainWindow())
        self._addSQLAction.setIcon(
            QIcon(":/plugins/qgis-cartodb/images/icons/sql.png"))

        self.toolbar.setClick(self.connectionManager)
        self.toolbar.error.connect(self.toolbarError)
        self._toolbarAction = self.iface.addWebToolBarWidget(self.toolbar)
        worker = CartoDBPluginWorker(self.toolbar, 'connectCartoDB')
        worker.start()

        if not self.toolbar.isCurrentUserValid():
            self._mainAction.setEnabled(False)
            self._loadDataAction.setEnabled(False)
            self._createVizAction.setEnabled(False)
            self._addSQLAction.setEnabled(False)

        self._mainAction.triggered.connect(self.run)
        self._loadDataAction.triggered.connect(self.upload)
        self._createVizAction.triggered.connect(self.createNewMap)
        self._addSQLAction.triggered.connect(self.addSQL)

        self._cdbMenu.addAction(self._mainAction)
        self._cdbMenu.addAction(self._loadDataAction)
        self._cdbMenu.addAction(self._createVizAction)
        self._cdbMenu.addAction(self._addSQLAction)
        try:
            self.iface.layerToolBar().addAction(self._mainAction)
        except:
            self.iface.addWebToolBarIcon(self._mainAction)
        self.iface.addWebToolBarIcon(self._loadDataAction)
        self.iface.addWebToolBarIcon(self._createVizAction)
        try:
            self.iface.layerToolBar().addAction(self._addSQLAction)
        except:
            self.iface.addWebToolBarIcon(self._addSQLAction)

        # Create Web menu, if it doesn't exist yet
        tmpAction = QAction("Temporal", self.iface.mainWindow())
        self.iface.addPluginToWebMenu("_tmp", tmpAction)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self._cdbMenu)
        self.iface.removePluginWebMenu("_tmp", tmpAction)

        # Register plugin layer type
        self.pluginLayerType = CartoDBPluginLayerType(self.iface,
                                                      self.createLayerCB)
        QgsPluginLayerRegistry.instance().addPluginLayerType(
            self.pluginLayerType)

    def unload(self):
        self.iface.removeWebToolBarIcon(self._mainAction)
        self.iface.removeWebToolBarIcon(self._loadDataAction)
        self.iface.removeWebToolBarIcon(self._createVizAction)
        self.iface.removeWebToolBarIcon(self._addSQLAction)
        self.iface.webMenu().removeAction(self._cdbMenu.menuAction())
        self.iface.removeWebToolBarIcon(self._toolbarAction)

        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(
            CartoDBPluginLayer.LAYER_TYPE)

    def connectionManager(self):
        dlg = CartoDBConnectionsManager()
        dlg.notfoundconnections.connect(self.connectionsNotFound)
        dlg.deleteconnetion.connect(self.onDeleteUser)
        dlg.show()

        result = dlg.exec_()
        if result == 1 and dlg.currentUser is not None and dlg.currentApiKey is not None:
            self.toolbar.setUserCredentials(dlg.currentUser, dlg.currentApiKey,
                                            dlg.currentMultiuser)
            self._mainAction.setEnabled(True)
            self._loadDataAction.setEnabled(True)
            self._createVizAction.setEnabled(True)
            self._addSQLAction.setEnabled(True)

    def connectionsNotFound(self):
        self.toolbarError("")
        self.toolbar.reset()

    def onDeleteUser(self, user):
        if self.toolbar.currentUser == user:
            self.toolbar.setConnectText()

    def toolbarError(self, error):
        self._mainAction.setEnabled(False)
        self._loadDataAction.setEnabled(False)
        self._createVizAction.setEnabled(False)
        self._addSQLAction.setEnabled(False)

    def run(self):
        # Create and show the dialog
        dlg = CartoDBPluginDialog(self.toolbar)
        dlg.show()

        result = dlg.exec_()
        # See if OK was pressed
        if result == 1 and dlg.currentUser is not None and dlg.currentApiKey is not None:
            selectedItems = dlg.getTablesListSelectedItems()
            countLayers = len(selectedItems)
            self.countLoadingLayers = self.countLoadingLayers + countLayers
            if countLayers > 0:
                self.progressMessageBar, self.progress = self.addLoadingMsg(
                    self.countLoadingLayers)
                self.iface.messageBar().pushWidget(
                    self.progressMessageBar,
                    self.iface.messageBar().INFO)
                self.iface.mainWindow().statusBar().showMessage(
                    self.tr('Processed {} %').format(0))
                for i, table in enumerate(selectedItems):
                    widget = dlg.getItemWidget(table)
                    worker = CartoDBLayerWorker(
                        self.iface,
                        widget.tableName,
                        widget.tableOwner,
                        dlg,
                        filterByExtent=dlg.filterByExtent(),
                        readonly=widget.readonly,
                        multiuser=widget.multiuser)
                    worker.finished.connect(self.addLayer)
                    self.worker = worker
                    worker.load()
        elif dlg.loadSQL:
            self.addSQL()

    def addLayer(self, layer):
        try:
            self.worker.deleteLater()
        except Exception, e:
            pass

        self.countLoadedLayers = self.countLoadedLayers + 1

        if layer.readonly:
            self.iface.messageBar().pushMessage(
                self.tr('Warning'),
                self.tr('Layer {}  is loaded in readonly mode').format(
                    layer.layerName),
                level=self.iface.messageBar().WARNING,
                duration=5)
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        self.layers.append(layer)
        self.progressMessageBar.setText(
            str(self.countLoadedLayers) + '/' + str(self.countLoadingLayers))
        percent = self.countLoadedLayers / float(self.countLoadingLayers) * 100
        self.iface.mainWindow().statusBar().showMessage(
            self.tr('Processed {}% - Loaded: {}').format(
                int(percent), layer.cartoTable))
        self.progress.setValue(self.countLoadedLayers)
        if self.countLoadedLayers == self.countLoadingLayers:
            self.iface.mainWindow().statusBar().clearMessage()
            self.iface.messageBar().popWidget(self.progressMessageBar)
            self.countLoadedLayers = 0
            self.countLoadingLayers = 0
Example #24
0
    def set_actions(self):
        """Setup actions"""
        import_action = create_action(self,
                                      self.tr("Import data..."),
                                      None,
                                      'ws_open.png',
                                      self.tr("Import data to workspace"),
                                      triggered=self.import_data)
        save_as_action = create_action(self,
                                       self.tr("Save workspace as..."),
                                       None,
                                       'ws_save_as.png',
                                       self.tr("Save workspace as..."),
                                       triggered=self.save_as)
        exclude_private_action = create_action(
            self,
            self.tr("Exclude private references"),
            tip=self.tr("Exclude references which name starts"
                        " with an underscore"),
            toggled=self.toggle_exclude_private)
        exclude_private_action.setChecked(CONF.get(self.ID, 'exclude_private'))
        exclude_upper_action = create_action(
            self,
            self.tr("Exclude capitalized references"),
            tip=self.tr("Exclude references which name starts with an "
                        "upper-case character"),
            toggled=self.toggle_exclude_upper)
        exclude_upper_action.setChecked(CONF.get(self.ID, 'exclude_upper'))
        exclude_unsupported_action = create_action(
            self,
            self.tr("Exclude unsupported data types"),
            tip=self.tr("Exclude references to unsupported data types"
                        " (i.e. which won't be handled/saved correctly)"),
            toggled=self.toggle_exclude_unsupported)
        exclude_unsupported_action.setChecked(
            CONF.get(self.ID, 'exclude_unsupported'))

        refresh_action = create_action(self,
                                       self.tr("Refresh workspace"),
                                       None,
                                       'ws_refresh.png',
                                       self.tr("Refresh workspace"),
                                       triggered=self.refresh_editor)

        autorefresh_action = create_action(self,
                                           self.tr("Auto refresh"),
                                           toggled=self.toggle_autorefresh)
        autorefresh_action.setChecked(CONF.get(self.ID, 'autorefresh'))

        autosave_action = create_action(
            self,
            self.tr("Auto save"),
            toggled=self.toggle_autosave,
            tip=self.tr("Automatically save workspace in a temporary file"
                        " when quitting"))
        autosave_action.setChecked(CONF.get(self.ID, 'autosave'))

        clear_action = create_action(
            self,
            self.tr("Clear workspace"),
            icon=get_icon('clear.png'),
            tip=self.tr("Clear all data from workspace"),
            triggered=self.clear)
        font_action1 = create_action(self,
                                     self.tr("Header Font..."),
                                     None,
                                     'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font1)
        font_action2 = create_action(self,
                                     self.tr("Value Font..."),
                                     None,
                                     'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font2)

        option_menu = QMenu(self.tr("Workspace settings"), self)
        option_menu.setIcon(get_icon('tooloptions.png'))
        add_actions(
            option_menu,
            (autosave_action, None, self.truncate_action, self.inplace_action,
             None, exclude_private_action, exclude_upper_action,
             exclude_unsupported_action, font_action1, font_action2))
        menu_actions = (import_action, save_as_action, refresh_action,
                        autorefresh_action, clear_action, option_menu)
        toolbar_actions = (refresh_action, import_action, save_as_action)
        return (menu_actions, toolbar_actions)
Example #25
0
class LDMPPlugin:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale and translation
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'LDMP_{}.qm'.format(locale))
        QgsMessageLog.logMessage(
            'Starting trends.earth version {} using locale "{}" in path {}.'.
            format(__version__, locale, locale_path),
            tag="trends.earth",
            level=QgsMessageLog.INFO)

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)
                QgsMessageLog.logMessage("Translator installed.",
                                         tag="trends.earth",
                                         level=QgsMessageLog.INFO)

        # Declare instance attributes
        self.actions = []
        self.menu = QMenu(QApplication.translate('LDMP', u'&trends.earth'))
        self.menu.setIcon(
            QIcon(':/plugins/LDMP/trends_earth_logo_square_32x32.png'))
        self.raster_menu = self.iface.rasterMenu()
        self.raster_menu.addMenu(self.menu)
        self.toolbar = self.iface.addToolBar(u'trends.earth')

        self.dlg_settings = DlgSettings()
        self.dlg_calculate = DlgCalculate()
        self.dlg_jobs = DlgJobs()
        self.dlg_timeseries = DlgTimeseries()
        self.dlg_reporting = DlgReporting()
        self.dlg_download = DlgDownload()
        self.dlg_load_data = DlgLoadData()
        self.dlg_about = DlgAbout()

    # 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('LDMP', message)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.menu.addAction(action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        self.add_action(':/plugins/LDMP/icons/wrench.svg',
                        text=QApplication.translate('LDMP', u'Settings'),
                        callback=self.run_settings,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'LDMT Settings'))

        self.add_action(':/plugins/LDMP/icons/calculator.svg',
                        text=QApplication.translate('LDMP',
                                                    u'Calculate indicators'),
                        callback=self.run_calculate,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'Calculate land degradation indicators'))

        self.add_action(':/plugins/LDMP/icons/graph.svg',
                        text=QApplication.translate('LDMP', u'Plot data'),
                        callback=self.run_plot,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'Plot time series datasets'))

        self.add_action(
            ':/plugins/LDMP/icons/cloud-download.svg',
            text=QApplication.translate('LDMP',
                                        u'View Google Earth Engine tasks'),
            callback=self.get_jobs,
            parent=self.iface.mainWindow(),
            status_tip=QApplication.translate('LDMP',
                                              'View cloud processing tasks'))

        self.add_action(':/plugins/LDMP/icons/document.svg',
                        text=QApplication.translate('LDMP', u'Reporting tool'),
                        callback=self.run_reporting,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'Land degradation reporting'))

        self.add_action(':/plugins/LDMP/icons/globe.svg',
                        text=QApplication.translate('LDMP',
                                                    u'Download raw data'),
                        callback=self.run_download,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'Download raw datasets'))

        self.add_action(':/plugins/LDMP/icons/folder.svg',
                        text=QApplication.translate('LDMP', u'Load data'),
                        callback=self.load_data,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'Load local data'))

        self.add_action(':/plugins/LDMP/icons/info.svg',
                        text=QApplication.translate('LDMP', u'About'),
                        callback=self.run_about,
                        parent=self.iface.mainWindow(),
                        status_tip=QApplication.translate(
                            'LDMP', 'About trends.earth'))

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginRasterMenu(
                QApplication.translate('LDMP', u'&trends.earth'), action)
            self.iface.removeToolBarIcon(action)
        # remove the menu
        self.raster_menu.removeAction(self.menu.menuAction())
        # remove the toolbar
        del self.toolbar

    def run_settings(self):
        self.dlg_settings.show()
        result = self.dlg_settings.exec_()

    def run_download(self):
        self.dlg_download.show()
        result = self.dlg_download.exec_()

    def run_calculate(self):
        # show the dialog
        self.dlg_calculate.show()
        result = self.dlg_calculate.exec_()

    def get_jobs(self):
        # show the dialog
        self.dlg_jobs.show()
        result = self.dlg_jobs.exec_()

    def run_plot(self):
        self.dlg_timeseries.show()
        result = self.dlg_timeseries.exec_()

    def run_reporting(self):
        self.dlg_reporting.show()
        result = self.dlg_reporting.exec_()

    def load_data(self):
        self.dlg_load_data.show()
        result = self.dlg_load_data.exec_()

    def run_about(self):
        #showHelp()
        self.dlg_about.show()
        result = self.dlg_about.exec_()
class QuickMapServices:
    """QGIS Plugin Implementation."""

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

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__).decode(sys.getfilesystemencoding())

        # initialize locale
        self.translator = QTranslator()

        self.locale = Locale.get_locale()
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QuickMapServices_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.custom_translator = CustomTranslator()
        QCoreApplication.installTranslator(self.custom_translator)

        # Create the dialog (after translation) and keep reference
        self.info_dlg = AboutDialog()

        # Check Contrib and User dirs
        try:
            ExtraSources.check_extra_dirs()
        except:
            error_message = self.tr('Extra dirs for %s can\'t be created: %s %s') % (PluginSettings.product_name(),
                                                                                      sys.exc_type,
                                                                                      sys.exc_value)
            self.iface.messageBar().pushMessage(self.tr('Error'),
                                                error_message,
                                                level=QgsMessageBar.CRITICAL)

        # Declare instance attributes
        self.service_actions = []
        self.service_layers = []  # TODO: id and smart remove
        self._scales_list = None

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

    def initGui(self):
        #import pydevd
        #pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False)

        # Register plugin layer type
        self.tileLayerType = TileLayerType(self)
        QgsPluginLayerRegistry.instance().addPluginLayerType(self.tileLayerType)

        # Create menu
        icon_path = self.plugin_dir + '/icons/mActionAddLayer.png'
        self.menu = QMenu(self.tr(u'QuickMapServices'))
        self.menu.setIcon(QIcon(icon_path))
        self.init_server_panel()

        self.build_menu_tree()

        # add to QGIS menu/toolbars
        self.append_menu_buttons()

    def _load_scales_list(self):
        scales_filename = os.path.join(self.plugin_dir, 'scales.xml')
        scales_list = []
        # TODO: remake when fix: http://hub.qgis.org/issues/11915
        # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message)
        xml_root = ET.parse(scales_filename).getroot()
        for scale_el in xml_root.findall('scale'):
            scales_list.append(scale_el.get('value'))
        return scales_list

    @property
    def scales_list(self):
        if not self._scales_list:
            self._scales_list = self._load_scales_list()
        return self._scales_list

    def set_nearest_scale(self):
        #get current scale
        curr_scale = self.iface.mapCanvas().scale()
        #find nearest
        nearest_scale = sys.maxint
        for scale_str in self.scales_list:
            scale = scale_str.split(':')[1]
            scale_int = int(scale)
            if abs(scale_int-curr_scale) < abs(nearest_scale - curr_scale):
                nearest_scale = scale_int

        #set new scale
        if nearest_scale != sys.maxint:
            self.iface.mapCanvas().zoomScale(nearest_scale)

    def set_tms_scales(self):
        res = QMessageBox.question(
            self.iface.mainWindow(),
            self.tr('QuickMapServices'),
            self.tr('Set SlippyMap scales for current project? \nThe previous settings will be overwritten!'),
            QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            # set scales
            QgsProject.instance().writeEntry('Scales', '/ScalesList', self.scales_list)
            # activate
            QgsProject.instance().writeEntry('Scales', '/useProjectScales', True)
            # update in main window
            # ???? no way to update: http://hub.qgis.org/issues/11917

    def insert_layer(self):
        action = self.menu.sender()
        ds = action.data()
        add_layer_to_map(ds)

    def unload(self):
        # remove menu/panels
        self.remove_menu_buttons()
        self.remove_server_panel()

        # clean vars
        self.menu = None
        self.toolbutton = None
        self.service_actions = None
        self.ds_list = None
        self.groups_list = None
        self.service_layers = None
        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(TileLayer.LAYER_TYPE)

    def build_menu_tree(self):
        # Main Menu
        self.menu.clear()

        self.groups_list = GroupsList()
        self.ds_list = DataSourcesList()

        data_sources = self.ds_list.data_sources.values()
        data_sources.sort(key=lambda x: x.alias or x.id)

        ds_hide_list = PluginSettings.get_hide_ds_id_list()

        for ds in data_sources:
            if ds.id in ds_hide_list:
                continue
            ds.action.triggered.connect(self.insert_layer)
            gr_menu = self.groups_list.get_group_menu(ds.group)
            gr_menu.addAction(ds.action)
            if gr_menu not in self.menu.children():
                self.menu.addMenu(gr_menu)

        # Scales, Settings and About actions
        self.menu.addSeparator()
        icon_set_nearest_scale_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        set_nearest_scale_act = QAction(QIcon(icon_set_nearest_scale_path), self.tr('Set proper scale'), self.iface.mainWindow())
        set_nearest_scale_act.triggered.connect(self.set_nearest_scale)
        self.menu.addAction(set_nearest_scale_act)  # TODO: uncomment after fix
        self.service_actions.append(set_nearest_scale_act)

        icon_scales_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        scales_act = QAction(QIcon(icon_scales_path), self.tr('Set SlippyMap scales'), self.iface.mainWindow())
        scales_act.triggered.connect(self.set_tms_scales)
        #self.menu.addAction(scales_act)  # TODO: uncomment after fix
        self.service_actions.append(scales_act)

        icon_settings_path = self.plugin_dir + '/icons/mapservices.png'
        server_panel_act = self.server_toolbox.toggleViewAction()
        server_panel_act.setIcon(QIcon(icon_settings_path))
        server_panel_act.setText(self.tr('Search QMS'))
        self.service_actions.append(server_panel_act)
        self.menu.addAction(server_panel_act)

        icon_settings_path = self.plugin_dir + '/icons/mActionSettings.png'
        settings_act = QAction(QIcon(icon_settings_path), self.tr('Settings'), self.iface.mainWindow())
        self.service_actions.append(settings_act)
        settings_act.triggered.connect(self.show_settings_dialog)
        self.menu.addAction(settings_act)

        icon_about_path = self.plugin_dir + '/icons/mActionAbout.png'
        info_act = QAction(QIcon(icon_about_path), self.tr('About'), self.iface.mainWindow())
        self.service_actions.append(info_act)
        info_act.triggered.connect(self.info_dlg.show)
        self.menu.addAction(info_act)


    def remove_menu_buttons(self):
        """
        Remove menus/buttons from all toolbars and main submenu
        :return:
        None
        """
        # remove menu
        if self.menu:
            self.iface.webMenu().removeAction(self.menu.menuAction())
            self.iface.addLayerMenu().removeAction(self.menu.menuAction())
        # remove toolbar button
        if self.tb_action:
            self.iface.webToolBar().removeAction(self.tb_action)
            self.iface.layerToolBar().removeAction(self.tb_action)

    def append_menu_buttons(self):
        """
        Append menus and buttons to appropriate toolbar
        :return:
        """
        # add to QGIS menu
        if PluginSettings.move_to_layers_menu():
            self.iface.addLayerMenu().addMenu(self.menu)
        else:
            # need workaround for WebMenu
            _temp_act = QAction('temp', self.iface.mainWindow())
            self.iface.addPluginToWebMenu("_tmp", _temp_act)
            self.iface.webMenu().addMenu(self.menu)
            self.iface.removePluginWebMenu("_tmp", _temp_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        if PluginSettings.move_to_layers_menu():
            self.tb_action = self.iface.layerToolBar().addWidget(toolbutton)
        else:
            self.tb_action = self.iface.webToolBar().addWidget(toolbutton)

    def show_settings_dialog(self):
        settings_dlg = SettingsDialog()
        settings_dlg.exec_()
        # apply settings
        # self.remove_menu_buttons()
        self.build_menu_tree()
        # self.append_menu_buttons()

    def init_server_panel(self):
        self.server_toolbox = QmsServiceToolbox(self.iface)
        self.iface.addDockWidget(PluginSettings.server_dock_area(), self.server_toolbox)
        self.server_toolbox.setWindowIcon(QIcon(self.plugin_dir + '/icons/mapservices.png'))
        self.server_toolbox.setVisible(PluginSettings.server_dock_visibility())
        # self.server_toolbox.setFloating(PluginSettings.dock_floating())
        # self.server_toolbox.resize(PluginSettings.dock_size())
        # self.server_toolbox.move(PluginSettings.dock_pos())
        # self.server_toolbox.setWindowIcon(QIcon(path.join(_current_path, 'edit-find-project.png')))

    def remove_server_panel(self):
        mw = self.iface.mainWindow()
        PluginSettings.set_server_dock_area(mw.dockWidgetArea(self.server_toolbox))
        PluginSettings.set_server_dock_visibility(self.server_toolbox.isVisible())
        # PluginSettings.set_dock_floating(self.__quick_tlb.isFloating())
        # PluginSettings.set_dock_pos(self.__quick_tlb.pos())
        # PluginSettings.set_dock_size(self.__quick_tlb.size())
        # PluginSettings.set_dock_geocoder_name(self.__quick_tlb.get_active_geocoder_name())
        self.iface.removeDockWidget(self.server_toolbox)
        del self.server_toolbox
Example #27
0
    def set_actions(self):
        """Setup actions"""
        import_action = create_action(self, self.tr("Import data..."), None,
            'ws_open.png', self.tr("Import data to workspace"),
            triggered=self.import_data)
        save_as_action = create_action(self, self.tr("Save workspace as..."),
            None, 'ws_save_as.png',  self.tr("Save workspace as..."),
            triggered = self.save_as)
        exclude_private_action = create_action(self,
            self.tr("Exclude private references"),
            tip=self.tr("Exclude references which name starts"
                        " with an underscore"),
            toggled=self.toggle_exclude_private)
        exclude_private_action.setChecked(CONF.get(self.ID, 'exclude_private'))
        exclude_upper_action = create_action(self,
            self.tr("Exclude capitalized references"),
            tip=self.tr("Exclude references which name starts with an "
                        "upper-case character"),
            toggled=self.toggle_exclude_upper)
        exclude_upper_action.setChecked( CONF.get(self.ID, 'exclude_upper') )
        exclude_unsupported_action = create_action(self,
            self.tr("Exclude unsupported data types"),
            tip=self.tr("Exclude references to unsupported data types"
                        " (i.e. which won't be handled/saved correctly)"),
            toggled=self.toggle_exclude_unsupported)
        exclude_unsupported_action.setChecked(CONF.get(self.ID,
                                              'exclude_unsupported'))

        refresh_action = create_action(self, self.tr("Refresh workspace"),
            None, 'ws_refresh.png', self.tr("Refresh workspace"),
            triggered = self.refresh_editor)
        
        autorefresh_action = create_action(self, self.tr("Auto refresh"),
                                           toggled=self.toggle_autorefresh)
        autorefresh_action.setChecked( CONF.get(self.ID, 'autorefresh') )
        
        autosave_action = create_action(self, self.tr("Auto save"),
            toggled=self.toggle_autosave,
            tip=self.tr("Automatically save workspace in a temporary file"
                        " when quitting"))
        autosave_action.setChecked( CONF.get(self.ID, 'autosave') )
        
        clear_action = create_action(self, self.tr("Clear workspace"),
                                 icon=get_icon('clear.png'),
                                 tip=self.tr("Clear all data from workspace"),
                                 triggered=self.clear)
        font_action1 = create_action(self, self.tr("Header Font..."),
                                     None, 'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font1)
        font_action2 = create_action(self, self.tr("Value Font..."),
                                     None, 'font.png',
                                     self.tr("Set font style"),
                                     triggered=self.change_font2)
        
        option_menu = QMenu(self.tr("Workspace settings"), self)
        option_menu.setIcon(get_icon('tooloptions.png'))
        add_actions(option_menu, (autosave_action, None,
                           self.truncate_action, self.inplace_action, None,
                           exclude_private_action, exclude_upper_action,
                           exclude_unsupported_action,
                           font_action1, font_action2))
        menu_actions = (import_action, save_as_action,
                        refresh_action, autorefresh_action, clear_action,
                        option_menu)
        toolbar_actions = (refresh_action, import_action, save_as_action)
        return (menu_actions, toolbar_actions)
Example #28
0
class QuickOSM:
    def __init__(self, iface):
        """Constructor.

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

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

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

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

        # Create the folder if it does not exist.
        get_user_query_folder(over_write=True)

        # Add to processing
        self.provider = QuickOSMAlgorithmProvider()
        Processing.addProvider(self.provider, True)

        # Add the toolbar
        self.toolbar = self.iface.addToolBar('QuickOSM')
        self.toolbar.setObjectName('QuickOSM')

        self.quickosm_menu = None
        self.dock_menu = None
        self.web_menu = None
        self.mainWindowAction = None
        self.osmFileAction = None
        self.osmFileDockWidget = None
        self.myQueriesAction = None
        self.myQueriesDockWidget = None
        self.queryAction = None
        self.queryDockWidget = None
        self.quickQueryAction = None
        self.quickQueryDockWidget = None

    def initGui(self):

        # Setup menu
        self.quickosm_menu = QMenu('Quick OSM')
        self.quickosm_menu.setIcon(QIcon(':/plugins/QuickOSM/icon.png'))
        self.dock_menu = QMenu(tr('QuickOSM', u'Dock'))
        self.web_menu = self.iface.webMenu()
        self.web_menu.addMenu(self.quickosm_menu)

        # Main window
        self.mainWindowAction = QAction(QIcon(':/plugins/QuickOSM/icon.png'),
                                        u'QuickOSM', self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.mainWindowAction.triggered.connect(self.openMainWindow)
        self.toolbar.addAction(self.mainWindowAction)
        self.iface.QuickOSM_mainWindowDialog = MainWindowDialog()

        # OSM File
        self.osmFileAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/open.png'),
            tr('ui_osm_file', 'OSM File'), self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.osmFileAction.triggered.connect(self.openOsmFileDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.osmFileAction)
        self.osmFileDockWidget = OsmFileDockWidget()
        self.iface.addDockWidget(Qt.RightDockWidgetArea,
                                 self.osmFileDockWidget)
        self.osmFileDockWidget.hide()
        self.osmFileDockWidget.setObjectName('osmFileWidget')

        # My queries
        self.myQueriesAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/favorites.png'),
            tr('ui_my_queries', 'My queries'), self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.myQueriesAction.triggered.connect(self.openMyQueriesDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.myQueriesAction)
        self.myQueriesDockWidget = MyQueriesDockWidget()
        self.iface.addDockWidget(Qt.RightDockWidgetArea,
                                 self.myQueriesDockWidget)
        self.myQueriesDockWidget.hide()
        self.myQueriesDockWidget.setObjectName('myQueriesWidget')

        # Query
        self.queryAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/edit.png'),
            tr('ui_query', 'Query'), self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.queryAction.triggered.connect(self.openQueryDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.queryAction)
        self.queryDockWidget = QueryDockWidget()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.queryDockWidget)
        self.queryDockWidget.hide()
        self.queryDockWidget.setObjectName('queryWidget')

        # Quick query
        self.quickQueryAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/quick.png'),
            tr('ui_quick_query', 'Quick query'), self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.quickQueryAction.triggered.connect(self.openQuickQueryDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.quickQueryAction)
        self.quickQueryDockWidget = QuickQueryDockWidget()
        self.iface.addDockWidget(Qt.RightDockWidgetArea,
                                 self.quickQueryDockWidget)
        self.quickQueryDockWidget.hide()
        self.quickQueryDockWidget.setObjectName('quickQueryWidget')

        # Insert in the good order
        self.quickosm_menu.addAction(self.mainWindowAction)
        self.quickosm_menu.addMenu(self.dock_menu)
        self.dock_menu.addAction(self.quickQueryAction)
        self.dock_menu.addAction(self.queryAction)
        self.dock_menu.addAction(self.myQueriesAction)
        self.dock_menu.addAction(self.osmFileAction)

        # Connect signals and slots from dock
        self.queryDockWidget.signal_new_query_successful.connect(
            self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)
        self.queryDockWidget.signal_new_query_successful.connect(
            self.myQueriesDockWidget.refresh_my_queries_tree)
        self.myQueriesDockWidget.signal_delete_query_successful.connect(
            self.myQueriesDockWidget.refresh_my_queries_tree)
        self.myQueriesDockWidget.signal_delete_query_successful.connect(
            self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)

        # Connect signals and slots from mainWindow
        self.iface.QuickOSM_mainWindowDialog.signal_new_query_successful.\
            connect(self.myQueriesDockWidget.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_new_query_successful.\
            connect(
                self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_delete_query_successful.\
            connect(self.myQueriesDockWidget.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_delete_query_successful.\
            connect(
                self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)

        # Read the config file
        json_file_config = join(dirname(abspath(__file__)), 'config.json')
        if isfile(json_file_config):
            config_json = load(open(json_file_config))
            for server in config_json['overpass_servers']:
                self.iface.QuickOSM_mainWindowDialog.comboBox_default_OAPI.\
                    addItem(server)

        # Check previous version and if new queries are available
        version = get_setting('version')
        current_version = get_current_version()
        if version != current_version:
            if new_queries_available():
                message = 'New queries are available in the plugin. Would ' \
                          'like to install them ? This will overwrite the ' \
                          'current default queries.'
                title = 'QuickOSM'
                message = tr('QuickOSM', message)
                widget = self.iface.messageBar().createMessage(title, message)
                button_ok = QPushButton(widget)
                button_ok.setText(tr('QuickOSM', 'Install'))
                button_ok.pressed.connect(self.restoreDefaultQueries)
                widget.layout().addWidget(button_ok)
                self.iface.messageBar().pushWidget(widget, QgsMessageBar.INFO,
                                                   0)

            set_setting('version', current_version)

    def restoreDefaultQueries(self):
        self.iface.QuickOSM_mainWindowDialog.restore_default_queries()
        self.iface.messageBar().popWidget()

    def unload(self):
        self.iface.removePluginWebMenu(u'&QuickOSM', self.mainWindowAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.myQueriesAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.queryAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.quickQueryAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.osmFileAction)
        self.iface.removeToolBarIcon(self.mainWindowAction)
        Processing.removeProvider(self.provider)

    def openMainWindow(self):
        self.iface.QuickOSM_mainWindowDialog.listWidget.setCurrentRow(0)
        self.iface.QuickOSM_mainWindowDialog.exec_()

    def openMyQueriesDockWidget(self):
        if self.myQueriesDockWidget.isVisible():
            self.myQueriesDockWidget.hide()
        else:
            self.myQueriesDockWidget.show()

    def openQueryDockWidget(self):
        if self.queryDockWidget.isVisible():
            self.queryDockWidget.hide()
        else:
            self.queryDockWidget.show()

    def openOsmFileDockWidget(self):
        if self.osmFileDockWidget.isVisible():
            self.osmFileDockWidget.hide()
        else:
            self.osmFileDockWidget.show()

    def openQuickQueryDockWidget(self):
        if self.quickQueryDockWidget.isVisible():
            self.quickQueryDockWidget.hide()
        else:
            self.quickQueryDockWidget.show()
Example #29
0
    def on_context_menu(web_view, menu):
        """Populate context menu, given the context/configuration."""

        window = web_view.window()

        try:  # this works for web views embedded in editor windows
            atts_button = web_view.editor.widget.findChild(gui.Button)
        except AttributeError:
            atts_button = None

        say_text = config['presets'] and strip(web_view.selectedText())

        tts_card = tts_side = None
        tts_shortcuts = False
        try:  # this works for web views in the reviewer and template dialog
            if window is aqt.mw and aqt.mw.state == 'review':
                tts_card = aqt.mw.reviewer.card
                tts_side = aqt.mw.reviewer.state
                tts_shortcuts = True
            elif web_view.objectName() == 'mainText':  # card template dialog
                parent_name = web_view.parentWidget().objectName()
                tts_card = window.card
                tts_side = ('question' if parent_name == 'groupBox'
                            else 'answer' if parent_name == 'groupBox_2'
                            else None)
        except Exception:  # just in case, pylint:disable=broad-except
            pass

        tts_question = tts_card and tts_side and \
            reviewer.has_tts('question', tts_card)
        tts_answer = tts_card and tts_side == 'answer' and \
            reviewer.has_tts('answer', tts_card)

        if not (atts_button or say_text or tts_question or tts_answer):
            return

        submenu = QMenu("Awesome&TTS", menu)
        submenu.setIcon(gui.ICON)

        needs_separator = False

        if atts_button:
            submenu.addAction(
                "Add MP3 to the Note",
                lambda: atts_button.click() if atts_button.isEnabled()
                else aqt.utils.showWarning(
                    "Select the note field to which you want to add an MP3.",
                    window,
                )
            )
            needs_separator = True

        if say_text:
            say_display = (say_text if len(say_text) < 25
                           else say_text[0:20].rstrip(' .') + "...")

            if config['presets']:
                if needs_separator:
                    submenu.addSeparator()
                else:
                    needs_separator = True

                def preset_glue((name, preset)):
                    """Closure for callback handler to access `preset`."""
                    submenu.addAction(
                        'Say "%s" w/ %s' % (say_display, name),
                        lambda: reviewer.selection_handler(say_text,
                                                           preset,
                                                           window),
                    )
                for item in sorted(config['presets'].items(),
                                   key=lambda item: item[0].lower()):
                    preset_glue(item)

            if config['groups']:
                if needs_separator:
                    submenu.addSeparator()
                else:
                    needs_separator = True

                def group_glue((name, group)):
                    """Closure for callback handler to access `group`."""
                    submenu.addAction(
                        'Say "%s" w/ %s' % (say_display, name),
                        lambda: reviewer.selection_handler_group(say_text,
                                                                 group,
                                                                 window),
                    )
                for item in sorted(config['groups'].items(),
                                   key=lambda item: item[0].lower()):
                    group_glue(item)

        if tts_question or tts_answer:
            if needs_separator:
                submenu.addSeparator()

            if tts_question:
                submenu.addAction(
                    "Play On-the-Fly TTS from Question Side",
                    lambda: reviewer.nonselection_handler('question', tts_card,
                                                          window),
                    tts_shortcuts and config['tts_key_q'] or 0,
                )

            if tts_answer:
                submenu.addAction(
                    "Play On-the-Fly TTS from Answer Side",
                    lambda: reviewer.nonselection_handler('answer', tts_card,
                                                          window),
                    tts_shortcuts and config['tts_key_a'] or 0,
                )

        menu.addMenu(submenu)
class QuickMapServices:
    """QGIS Plugin Implementation."""

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

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__).decode(sys.getfilesystemencoding())

        # initialize locale
        self.translator = QTranslator()

        self.locale = Locale.get_locale()
        locale_path = os.path.join(self.plugin_dir, "i18n", "QuickMapServices_{}.qm".format(self.locale))
        if os.path.exists(locale_path):
            self.translator.load(locale_path)
            if qVersion() > "4.3.3":
                QCoreApplication.installTranslator(self.translator)

        self.custom_translator = CustomTranslator()
        QCoreApplication.installTranslator(self.custom_translator)

        # Create the dialog (after translation) and keep reference
        self.info_dlg = AboutDialog()

        # Check Contrib and User dirs
        try:
            ExtraSources.check_extra_dirs()
        except:
            error_message = self.tr("Extra dirs for %s can't be created: %s %s") % (
                PluginSettings.product_name(),
                sys.exc_type,
                sys.exc_value,
            )
            self.iface.messageBar().pushMessage(self.tr("Error"), error_message, level=QgsMessageBar.CRITICAL)

        # Declare instance attributes
        self.service_actions = []
        self.service_layers = []  # TODO: id and smart remove
        self._scales_list = None

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

    def initGui(self):
        # import pydevd
        # pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False)

        # Register plugin layer type
        self.tileLayerType = TileLayerType(self)
        QgsPluginLayerRegistry.instance().addPluginLayerType(self.tileLayerType)

        # Create menu
        icon_path = self.plugin_dir + "/icons/mActionAddLayer.png"
        self.menu = QMenu(self.tr(u"QuickMapServices"))
        self.menu.setIcon(QIcon(icon_path))

        self.build_menu_tree()

        # add to QGIS menu/toolbars
        self.append_menu_buttons()

    def _load_scales_list(self):
        scales_filename = os.path.join(self.plugin_dir, "scales.xml")
        scales_list = []
        # TODO: remake when fix: http://hub.qgis.org/issues/11915
        # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message)
        xml_root = ET.parse(scales_filename).getroot()
        for scale_el in xml_root.findall("scale"):
            scales_list.append(scale_el.get("value"))
        return scales_list

    @property
    def scales_list(self):
        if not self._scales_list:
            self._scales_list = self._load_scales_list()
        return self._scales_list

    def set_nearest_scale(self):
        # get current scale
        curr_scale = self.iface.mapCanvas().scale()
        # find nearest
        nearest_scale = sys.maxint
        for scale_str in self.scales_list:
            scale = scale_str.split(":")[1]
            scale_int = int(scale)
            if abs(scale_int - curr_scale) < abs(nearest_scale - curr_scale):
                nearest_scale = scale_int

        # set new scale
        if nearest_scale != sys.maxint:
            self.iface.mapCanvas().zoomScale(nearest_scale)

    def set_tms_scales(self):
        res = QMessageBox.question(
            self.iface.mainWindow(),
            self.tr("QuickMapServices"),
            self.tr("Set SlippyMap scales for current project? \nThe previous settings will be overwritten!"),
            QMessageBox.Yes | QMessageBox.No,
        )
        if res == QMessageBox.Yes:
            # set scales
            QgsProject.instance().writeEntry("Scales", "/ScalesList", self.scales_list)
            # activate
            QgsProject.instance().writeEntry("Scales", "/useProjectScales", True)
            # update in main window
            # ???? no way to update: http://hub.qgis.org/issues/11917

    def insert_layer(self):
        # TODO: need factory!
        layers4add = []
        action = self.menu.sender()
        ds = action.data()
        if ds.type == KNOWN_DRIVERS.TMS:
            service_info = TileServiceInfo(self.tr(ds.alias), ds.copyright_text, ds.tms_url)
            service_info.zmin = ds.tms_zmin or service_info.zmin
            service_info.zmax = ds.tms_zmax or service_info.zmax
            if ds.tms_y_origin_top is not None:
                service_info.yOriginTop = ds.tms_y_origin_top
            service_info.epsg_crs_id = ds.tms_epsg_crs_id
            service_info.postgis_crs_id = ds.tms_postgis_crs_id
            service_info.custom_proj = ds.tms_custom_proj
            layer = TileLayer(self, service_info, False)
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.GDAL:
            layer = QgsRasterLayer(ds.gdal_source_file, self.tr(ds.alias))
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.WMS:
            qgis_wms_uri = u""
            if ds.wms_params:
                qgis_wms_uri += ds.wms_params
            if ds.wms_layers:
                layers = ds.wms_layers.split(",")
                if layers:
                    if ds.wms_turn_over:
                        layers.reverse()
                    qgis_wms_uri += "&layers=" + "&layers=".join(layers) + "&styles=" * len(layers)
            qgis_wms_uri += "&url=" + ds.wms_url
            layer = QgsRasterLayer(qgis_wms_uri, self.tr(ds.alias), KNOWN_DRIVERS.WMS.lower())
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.WFS:
            qgis_wfs_uri_base = ds.wfs_url
            o = urlparse.urlparse(qgis_wfs_uri_base)
            request_attrs = dict(urlparse.parse_qsl(o.query))

            layers_str = request_attrs.get("TYPENAME", "")
            layers = layers_str.split(",")
            for layer_name in layers:
                new_request_attrs = request_attrs
                new_request_attrs["TYPENAME"] == layer_name

                url_parts = list(o)
                url_parts[4] = "&".join(["%s=%s" % (k, v) for k, v in new_request_attrs.items()])

                qgis_wfs_uri = urlparse.urlunparse(url_parts)

                layer = QgsVectorLayer(qgis_wfs_uri, "%s - %s" % (self.tr(ds.alias), layer_name), "WFS")
                layers4add.append(layer)

        for layer in layers4add:
            if not layer.isValid():
                error_message = self.tr("Layer %s can't be added to the map!") % ds.alias
                self.iface.messageBar().pushMessage(self.tr("Error"), error_message, level=QgsMessageBar.CRITICAL)
                QgsMessageLog.logMessage(error_message, level=QgsMessageLog.CRITICAL)
            else:
                # Set attribs
                layer.setAttribution(ds.copyright_text)
                layer.setAttributionUrl(ds.copyright_link)
                # Insert to bottom
                QgsMapLayerRegistry.instance().addMapLayer(layer, False)
                toc_root = QgsProject.instance().layerTreeRoot()
                toc_root.insertLayer(len(toc_root.children()), layer)
                # Save link
                self.service_layers.append(layer)
                # Set OTF CRS Transform for map
                if PluginSettings.enable_otf_3857() and ds.type == KNOWN_DRIVERS.TMS:
                    self.iface.mapCanvas().setCrsTransformEnabled(True)
                    self.iface.mapCanvas().setDestinationCrs(TileLayer.CRS_3857)

    def unload(self):
        # remove menu/
        self.remove_menu_buttons()

        # clean vars
        self.menu = None
        self.toolbutton = None
        self.service_actions = None
        self.ds_list = None
        self.groups_list = None
        self.service_layers = None
        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(TileLayer.LAYER_TYPE)

    def build_menu_tree(self):
        # Main Menu
        self.menu.clear()

        self.groups_list = GroupsList()
        self.ds_list = DataSourcesList()

        data_sources = self.ds_list.data_sources.values()
        data_sources.sort(key=lambda x: x.alias or x.id)

        ds_hide_list = PluginSettings.get_hide_ds_id_list()

        for ds in data_sources:
            if ds.id in ds_hide_list:
                continue
            ds.action.triggered.connect(self.insert_layer)
            gr_menu = self.groups_list.get_group_menu(ds.group)
            gr_menu.addAction(ds.action)
            if gr_menu not in self.menu.children():
                self.menu.addMenu(gr_menu)

        # Scales, Settings and About actions
        self.menu.addSeparator()
        icon_set_nearest_scale_path = self.plugin_dir + "/icons/mActionSettings.png"  # TODO change icon
        set_nearest_scale_act = QAction(
            QIcon(icon_set_nearest_scale_path), self.tr("Set proper scale"), self.iface.mainWindow()
        )
        set_nearest_scale_act.triggered.connect(self.set_nearest_scale)
        self.menu.addAction(set_nearest_scale_act)  # TODO: uncomment after fix
        self.service_actions.append(set_nearest_scale_act)

        icon_scales_path = self.plugin_dir + "/icons/mActionSettings.png"  # TODO change icon
        scales_act = QAction(QIcon(icon_scales_path), self.tr("Set SlippyMap scales"), self.iface.mainWindow())
        scales_act.triggered.connect(self.set_tms_scales)
        # self.menu.addAction(scales_act)  # TODO: uncomment after fix
        self.service_actions.append(scales_act)

        icon_settings_path = self.plugin_dir + "/icons/mActionSettings.png"
        settings_act = QAction(QIcon(icon_settings_path), self.tr("Settings"), self.iface.mainWindow())
        self.service_actions.append(settings_act)
        settings_act.triggered.connect(self.show_settings_dialog)
        self.menu.addAction(settings_act)

        icon_about_path = self.plugin_dir + "/icons/mActionAbout.png"
        info_act = QAction(QIcon(icon_about_path), self.tr("About"), self.iface.mainWindow())
        self.service_actions.append(info_act)
        info_act.triggered.connect(self.info_dlg.show)
        self.menu.addAction(info_act)

    def remove_menu_buttons(self):
        """
        Remove menus/buttons from all toolbars and main submenu
        :return:
        None
        """
        # remove menu
        if self.menu:
            self.iface.webMenu().removeAction(self.menu.menuAction())
            self.iface.addLayerMenu().removeAction(self.menu.menuAction())
        # remove toolbar button
        if self.tb_action:
            self.iface.webToolBar().removeAction(self.tb_action)
            self.iface.layerToolBar().removeAction(self.tb_action)

    def append_menu_buttons(self):
        """
        Append menus and buttons to appropriate toolbar
        :return:
        """
        # add to QGIS menu
        if PluginSettings.move_to_layers_menu():
            self.iface.addLayerMenu().addMenu(self.menu)
        else:
            # need workaround for WebMenu
            _temp_act = QAction("temp", self.iface.mainWindow())
            self.iface.addPluginToWebMenu("_tmp", _temp_act)
            self.iface.webMenu().addMenu(self.menu)
            self.iface.removePluginWebMenu("_tmp", _temp_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        if PluginSettings.move_to_layers_menu():
            self.tb_action = self.iface.layerToolBar().addWidget(toolbutton)
        else:
            self.tb_action = self.iface.webToolBar().addWidget(toolbutton)

    def show_settings_dialog(self):
        settings_dlg = SettingsDialog()
        settings_dlg.exec_()
        # apply settings
        # self.remove_menu_buttons()
        self.build_menu_tree()
class FileController_OpusData(FileController):
    def __init__(self, manager, data_path, parent_widget):

        FileController.__init__(self, manager, data_path, parent_widget)

        self.actRefresh = QAction(IconLibrary.icon('reload'), "Refresh Tree", self.treeview)
        QObject.connect(self.actRefresh, SIGNAL("triggered()"), self.refreshAction)

        self.actViewDataset = QAction(IconLibrary.icon('inspect'), "View Dataset", self.treeview)
        QObject.connect(self.actViewDataset, SIGNAL("triggered()"), self.viewDatasetAction)

        self.actOpenTextFile = QAction(IconLibrary.icon('text'), "Open Text File", self.treeview)
        QObject.connect(self.actOpenTextFile, SIGNAL("triggered()"), self.openTextFile)

        self.tool_library_node = self.manager.project.find('data_manager/tool_library')

    def viewDatasetAction(self):
        #print "viewDatasetAction"
        model = self.model
        table_name = str(model.fileName(self.currentIndex))
        table_name_full = str(model.filePath(self.currentIndex))
        parentIndex = model.parent(self.currentIndex)
        parent_name = str(model.fileName(parentIndex))
        parent_name_full = str(model.filePath(parentIndex))
        storage = StorageFactory().get_storage('flt_storage', storage_location=parent_name_full)
        columns = storage.get_column_names(table_name)
        # temporarily use the table name for the dataset name
        # dataset_name = DatasetFactory().dataset_name_for_table(table_name)
        # Aaron - please check this way of getting the XMLConfiguration -- is this the best way?

#        general = self.mainwindow.toolboxBase.opus_core_xml_configuration.get_section('general')
#        # problem: this gets the package order for the current project, but the viewer shows all the data
#        package_order = general['dataset_pool_configuration'].package_order

        # PREVIOUS HACK:
        # package_order = ['seattle_parcel','urbansim_parcel', 'eugene', 'urbansim', 'opus_core']
        # temporary code: just use a generic dataset for now
        data = Dataset(in_storage=storage, dataset_name=table_name, in_table_name=table_name, id_name=[])
        # code to get a more specialized dataset if possible (doesn't work with table names not ending in 's'
        # unless they are in the exceptions list in DatasetFactory)
        # data = DatasetFactory().search_for_dataset_with_hidden_id(dataset_name, package_order,
        #    arguments={'in_storage': storage, 'in_table_name': table_name})
        # Need to add a new tab to the main tabs for display of the data
        container = QWidget()
        widgetLayout = QVBoxLayout(container)
        summaryGroupBox = QGroupBox(container)
        summaryGroupBox.setTitle(QString("Year: %s  Run name: %s" % (parent_name,table_name_full.split('/')[-3])))
        summaryGroupBox.setFlat(True)
        summaryGroupBoxLayout = QVBoxLayout(summaryGroupBox)
        # Grab the summary data
        buffer = StringIO()
        data.summary(output=buffer)
        strng = buffer.getvalue()
        buffer.close()
        textBrowser = QTextBrowser()
#        textBrowser.insertPlainText(strng)
        textBrowser.insertHtml(self.parse_dataset_summary(strng))
        summaryGroupBoxLayout.addWidget(textBrowser)

        widgetLayout.addWidget(summaryGroupBox)

        tableGroupBox = QGroupBox(container)
        tableGroupBox.setTitle(QString("Table View"))
        tableGroupBox.setFlat(True)
        tableGroupBoxLayout = QVBoxLayout(tableGroupBox)
        tv = QTableView()
        header = columns
        tabledata_tmp = []
        for column in columns:
            tabledata_tmp.append(data.get_attribute(column))

        # Transpose the lists
        tabledata = map(None,*tabledata_tmp)

        # If the table data is not empty then we display it
        if tabledata:
            #tv.resizeColumnsToContents()
            tm = TableModel(tabledata, header, container)
            tv.setModel(tm)
            tv.setSortingEnabled(True)
            tableGroupBoxLayout.addWidget(tv)

        widgetLayout.addWidget(tableGroupBox)

        container.tabIcon = IconLibrary.icon('inspect')
        container.tabLabel = QString(table_name)
        self.manager._attach_tab(container)

    def parse_dataset_summary(self, summary):
        html = ['''<style type="text/css">

            table.prettytable {
              background: white;
            }
            table.prettytable th {
              border: 1px black solid;
              padding: 0.2em;
              background: gainsboro;
              text-align: left;
                border-width: thin thin thin thin;
                padding: 2px 2px 2px 2px;
                border-style: inset inset inset inset;
                border-color: gray gray gray gray;
            }
            table.prettytable td {
              border: 1px black solid;
              padding: 0.2em;
            }

            table.prettytable caption {
              margin-left: inherit;
              margin-right: inherit;
            }
            #text a {
                color: #000000;
                position: relative;
                text-decoration: underline;
            }
            </style>''',
            '<body>',
            '<div id="text">',
            '<table class="prettytable">'
            ]

        summary_lines = summary.split('\n')
        for i, line in enumerate(summary_lines):
            if i == 1: continue
            html.append('<tr>')
            if i == 0:
                header = line.split()[1:]
                html.append(''.join(['<th>%s</th>'%col for col in header]))
            else:

                row = line.split()
                if len(row) == 0: continue
                if row[0] == 'Size:':
                    start_end = i
                    break
                html.append(''.join(['<td>%s</td>'%col for col in row]))

            html.append('</tr>')
        html.append('</table>')
        try:
            html.append('<br><br>' + '<br>'.join(summary_lines[start_end:]))
        except:
            pass
        html.append('</div></body>')
        return QString('\n'.join(html))


    def refreshAction(self):
        #print "refreshAction"
        self.model.refresh(self.treeview.rootIndex())

# Disabling editor support for now

    def openTextFile(self):
        print 'openTextFile %s' % self.model.filePath(self.currentIndex)
        pass
#        print "openTextFile pressed with column = %s and item = %s" % \
#              (self.currentColumn, self.model.filePath(self.currentIndex))
#        if self.mainwindow.editorStuff:
#            print "Loading into qscintilla..."
#            filename = self.model.filePath(self.currentIndex)
#            self.mainwindow.editorStuff.clear()
#            try:
#                f = open(filename,'r')
#            except:
#                return
#            for l in f.readlines():
#                self.mainwindow.editorStuff.append(l)
#            f.close()
#            self.mainwindow.editorStatusLabel.setText(QString(filename))
#            self.mainwindow.openEditorTab()

    def fillInAvailableTools(self):

        # Operations on the selected item
        choices = {}

        # Classification for the selected item
        classification = ""

        if self.model.isDir(self.currentIndex):
            regex = QRegExp("\\d{4}") # match directory names with four digits
            name = self.model.fileName(self.currentIndex)
            parentname = self.model.fileName(self.model.parent(self.currentIndex))
            isdir = self.model.isDir(self.currentIndex)
            parentisdir = self.model.isDir(self.model.parent(self.currentIndex))
            # print "%s %s %s %s" % (name, parentname,isdir,parentisdir)
            if isdir and regex.exactMatch(name):
                # We have a database dir
                # print "Database Dir"
                classification = "database"
            elif parentisdir and regex.exactMatch(parentname):
                # We have a dataset
                # print "Dataset Dir"
                classification = "dataset"
        else:
            regex = QRegExp("\\d{4}")
            model = self.model
            parentIndex = model.parent(self.currentIndex)
            parentparentIndex = model.parent(parentIndex)
            parentparentname = model.fileName(parentparentIndex)
            parentparentisdir = model.isDir(parentparentIndex)
            if parentparentisdir and regex.exactMatch(parentparentname):
                # We have a file with a parentparent which is a database classification
                classification = "array"

        # Build up a list of available operations based on the classification

        tool_set_nodes = [tool_set_node for tool_set_node in self.tool_library_node
                          if tool_set_node.tag == 'tool_group']
        tool_file_nodes = []
        for tool_set_node in tool_set_nodes:
            tool_file_nodes.extend([node for node in tool_set_node
                           if node.tag == 'tool'])

        # Find all tool_nodes that acts on the resolved classification
        # (by looking at the XML node 'acts_on')
        for tool_node in tool_file_nodes:
            acts_on_node = tool_node.find('acts_on')
            exports_to_node = tool_node.find('exports_to')

            if acts_on_node is None or exports_to_node is None:
                # This tool doesn't export anything
                continue

            tool_classifications = acts_on_node.text.split(',')
            exports_to_value = exports_to_node.text
            if classification in tool_classifications:
                choices[exports_to_value] = tool_node

        self.classification = classification
        return choices

#         print "Classification = " + classification
#        dbxml = self.treeview.model().index(0,0,QModelIndex()).parent()
#         First loop through all tool_sets
#        setsindexlist = self.treeview.findElementIndexByType("tool_library",dbxml,True)
#        for setsindex in setsindexlist:
#            if setsindex.isValid():
#                print "Found valid tool_sets"
#                 Now loop through all tool_set and find the ones with a matching classification
#                tsindexlist = self.xml_model.findElementIndexByType("tool_file",setsindex,True)
#                for tsindex in tsindexlist:
#                    if tsindex.isValid():
#                        print "Found valid tool_set"
#                        classificationtext = ""
#                        tsitem = tsindex.internalPointer()
#                         We use the dom tree to find the classification because it is a hidden node
#                         in the XML tree and will not show up via a search on the model indexes (i.e. it
#                         is not actually in the model/view since it is hidden.
#                        if tsitem.node().hasChildNodes():
#                            tschildren = tsitem.node().childNodes()
#                            for x in xrange(0,tschildren.count(),1):
#                                if tschildren.item(x).isElement():
#                                    tselement = tschildren.item(x).toElement()
#                                    if tselement.hasAttribute(QString("type")) and \
#                                           (tselement.attribute(QString("type")) == QString("acts_on")):
#                                        if tselement.hasChildNodes():
#                                            classchildren = tselement.childNodes()
#                                            for x in xrange(0,classchildren.count(),1):
#                                                if classchildren.item(x).isText():
#                                                    print "Found some text in the classification element"
#                                                    classificationtext = classchildren.item(x).nodeValue()
#                                                    classificationtext = str(classchildren.item(x).nodeValue()).split(',')
#                                    if tselement.hasAttribute(QString("type")) and \
#                                           (tselement.attribute(QString("type")) == QString("exports_to")):
#                                        print tselement.text()
#                                        export_to_text = tselement.text()
#                        tagName = tsitem.domNode.toElement().tagName()
#                        for i in classificationtext:
#                            if i != "" and i == classification:
#                                choices[tagName] = export_to_text
#        self.classification = classification
#        return choices

    def dataActionMenuFunction(self,action):
        QObject.disconnect(self.menu, SIGNAL("triggered(QAction*)"),self.dataActionMenuFunction)
        if action != self.actRefresh:
            actiontext = str(action.text())
            tool_node = self.dynactions[actiontext]
            filename = self.model.fileName(self.currentIndex)
            filepath = self.model.filePath(self.currentIndex)
            parentfilepath = self.model.filePath(self.currentIndex.parent())

            params = self.getOptionalParams()
            window = ExecuteToolGui(parent_widget = self.treeview,
                                    tool_node = tool_node,
                                    tool_config = None,
                                    tool_library_node = self.tool_library_node, 
                                    params=params)
            window.show()
        return

    def getOptionalParams(self):
        params = {'tool_path': get_path_to_tool_modules(self.manager.project)}
        if self.classification == 'database':
            params['opus_data_directory'] = str(self.model.filePath(self.currentIndex.parent()))
            params['opus_data_year'] = str(self.model.fileName(self.currentIndex))
            params['opus_table_name'] = 'ALL'
        elif self.classification == 'dataset':
            params['opus_data_directory'] = str(self.model.filePath(self.currentIndex.parent().parent()))
            params['opus_data_year'] = str(self.model.fileName(self.currentIndex.parent()))
            params['opus_table_name'] = str(self.model.fileName(self.currentIndex))
        return params

    def process_custom_menu(self, position):
        self.currentColumn = self.treeview.indexAt(position).column()
        self.currentIndex = self.treeview.indexAt(position)

        self.menu = QMenu(self.treeview)

        if self.currentIndex.isValid():
            if self.model.fileInfo(self.currentIndex).suffix() == "txt":
                self.menu.addAction(self.actOpenTextFile)
            else:
                # Do stuff for directories
                choices = self.fillInAvailableTools()
                if self.classification == "dataset":
                    self.export_menu = QMenu(QString('Export Opus dataset to'), self.treeview)
                    self.export_menu.setIcon(IconLibrary.icon('export'))
                    if len(choices) > 0:
                        self.dynactions = {}
                        for export_type,tool_node in choices.iteritems():
                            dynaction = QAction(IconLibrary.icon('spreadsheet'), export_type, self.treeview)
                            self.export_menu.addAction(dynaction)
                            self.dynactions[export_type] = tool_node
                        QObject.connect(self.export_menu, SIGNAL("triggered(QAction*)"),
                                        self.dataActionMenuFunction)
                    self.menu.addMenu(self.export_menu)
                    self.menu.addSeparator()
                    # We need to provide the option to open the dataset
                    self.menu.addAction(self.actViewDataset)
                if self.classification == "database":
                    self.export_menu = QMenu(QString('Export Opus database to'))
                    self.export_menu.setIcon(IconLibrary.icon('export'))
                    if len(choices) > 0:
                        self.dynactions = {}
                        for export_type,tool_node in choices.iteritems():
                            dynaction = QAction(IconLibrary.icon('spreadsheet'), export_type, self.treeview)
                            self.export_menu.addAction(dynaction)
                            self.dynactions[export_type] = tool_node
                        QObject.connect(self.export_menu, SIGNAL("triggered(QAction*)"),
                                        self.dataActionMenuFunction)
                    self.menu.addMenu(self.export_menu)
                    self.menu.addSeparator()

        # Now tack on a refresh for all right clicks
        #print "Setting model refresh"
        self.menu.addAction(self.actRefresh)
        self.menu.exec_(QCursor.pos())
Example #32
0
    def set_actions(self):
        """Setup actions"""
        quit_action = create_action(self,
                                    self.tr("&Quit"),
                                    self.tr("Ctrl+Q"),
                                    'exit.png',
                                    self.tr("Quit"),
                                    triggered=self.quit)
        run_action = create_action(self,
                                   self.tr("&Run..."),
                                   None,
                                   'run_small.png',
                                   self.tr("Run a Python script"),
                                   triggered=self.run_script)
        environ_action = create_action(
            self,
            self.tr("Environment variables..."),
            icon='environ.png',
            tip=self.tr("Show and edit environment variables"
                        " (for current session)"),
            triggered=self.show_env)
        syspath_action = create_action(
            self,
            self.tr("Show sys.path contents..."),
            icon='syspath.png',
            tip=self.tr("Show (read-only) sys.path"),
            triggered=show_syspath)
        font_action = create_action(self,
                                    self.tr("&Font..."),
                                    None,
                                    'font.png',
                                    self.tr("Set shell font style"),
                                    triggered=self.change_font)
        exteditor_action = create_action(
            self,
            self.tr("External editor path..."),
            None,
            None,
            self.tr("Set external editor executable path"),
            triggered=self.change_exteditor)
        wrap_action = create_action(self,
                                    self.tr("Wrap lines"),
                                    toggled=self.toggle_wrap_mode)
        wrap_action.setChecked(CONF.get(self.ID, 'wrap'))
        calltips_action = create_action(self,
                                        self.tr("Balloon tips"),
                                        toggled=self.toggle_calltips)
        calltips_action.setChecked(CONF.get(self.ID, 'calltips'))
        codecompletion_action = create_action(
            self,
            self.tr("Code completion"),
            toggled=self.toggle_codecompletion)
        codecompletion_action.setChecked(
            CONF.get(self.ID, 'autocompletion/enabled'))
        codecompenter_action = create_action(
            self,
            self.tr("Enter key selects completion"),
            toggled=self.toggle_codecompletion_enter)
        codecompenter_action.setChecked(
            CONF.get(self.ID, 'autocompletion/enter-key'))
        rollbackimporter_action = create_action(
            self,
            self.tr("Force modules to be completely reloaded"),
            tip=self.tr("Force Python to reload modules imported when "
                        "executing a script in the interactive console"),
            toggled=self.toggle_rollbackimporter)
        rollbackimporter_action.setChecked(
            CONF.get(self.ID, 'rollback_importer'))
        try:
            imp.find_module('matplotlib')
            dockablefigures_action = create_action(
                self,
                self.tr("Dockable figures"),
                tip=self.tr("If enabled, matplotlib figures may "
                            "be docked to Spyder's main window "
                            "(will apply only for new figures)"),
                toggled=self.toggle_dockablefigures_mode)
            dockablefigures_action.setChecked(CONF.get('figure', 'dockable'))
        except ImportError:
            dockablefigures_action = None

        option_menu = QMenu(self.tr("Interactive console settings"), self)
        option_menu.setIcon(get_icon('tooloptions.png'))
        add_actions(
            option_menu,
            (font_action, wrap_action, calltips_action, codecompletion_action,
             codecompenter_action, rollbackimporter_action, exteditor_action,
             dockablefigures_action))

        menu_actions = [
            None, run_action, environ_action, syspath_action, option_menu,
            None, quit_action
        ]
        toolbar_actions = []

        # Add actions to context menu
        add_actions(self.shell.menu, menu_actions)

        return menu_actions, toolbar_actions
class QuickMapServices:
    """QGIS Plugin Implementation."""

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

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        self.translator = QTranslator()

        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'QuickMapServices_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.custom_translator = CustomTranslator()
        QCoreApplication.installTranslator(self.custom_translator)


        # Create the dialog (after translation) and keep reference
        self.settings_dlg = SettingsDialog()
        self.info_dlg = AboutDialog()

        # Declare instance attributes
        self.service_actions = []
        self.service_layers = []  # TODO: id and smart remove
        self._scales_list = None

        # TileLayer assets
        self.crs3857 = None
        self.downloadTimeout = 30  # TODO: settings
        self.navigationMessagesEnabled = Qt.Checked  # TODO: settings
        self.pluginName = 'QuickMapServices'


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


    def initGui(self):
        #import pydevd
        #pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False)

        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # Main Menu
        icon_path = self.plugin_dir + '/icons/mActionAddLayer.png'
        self.menu = QMenu(self.tr(u'QuickMapServices'))
        self.menu.setIcon(QIcon(icon_path))

        # DataSources Actions

        # Register plugin layer type
        self.tileLayerType = TileLayerType(self)
        QgsPluginLayerRegistry.instance().addPluginLayerType(self.tileLayerType)

        self.groups_list = DsGroupsList(self.locale, self.custom_translator)
        self.ds_list = DataSourcesList(self.locale, self.custom_translator)

        data_sources = self.ds_list.data_sources.values()
        data_sources.sort(key=lambda x: x.alias or x.id)

        for ds in data_sources:
            ds.action.triggered.connect(self.insert_layer)
            gr_menu = self.groups_list.get_group_menu(ds.group)
            gr_menu.addAction(ds.action)
            if gr_menu not in self.menu.children():
                self.menu.addMenu(gr_menu)

        # Scales, Settings and About actions
        icon_set_nearest_scale_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        set_nearest_scale_act = QAction(QIcon(icon_set_nearest_scale_path), self.tr('Set proper scale'), self.iface.mainWindow())
        set_nearest_scale_act.triggered.connect(self.set_nearest_scale)
        self.menu.addAction(set_nearest_scale_act)  # TODO: uncomment after fix
        self.service_actions.append(set_nearest_scale_act)

        icon_scales_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        scales_act = QAction(QIcon(icon_scales_path), self.tr('Set SlippyMap scales'), self.iface.mainWindow())
        scales_act.triggered.connect(self.set_tms_scales)
        #self.menu.addAction(scales_act)  # TODO: uncomment after fix
        self.service_actions.append(scales_act)

        icon_settings_path = self.plugin_dir + '/icons/mActionSettings.png'
        settings_act = QAction(QIcon(icon_settings_path), self.tr('Settings'), self.iface.mainWindow())
        self.service_actions.append(settings_act)
        #self.menu.addAction(settings_act)

        icon_about_path = self.plugin_dir + '/icons/mActionAbout.png'
        info_act = QAction(QIcon(icon_about_path), self.tr('About'), self.iface.mainWindow())
        self.service_actions.append(info_act)
        info_act.triggered.connect(self.info_dlg.show)
        self.menu.addAction(info_act)

        # add to QGIS menu
        self.iface.addPluginToWebMenu("_tmp", info_act)
        self.iface.webMenu().addMenu(self.menu)
        self.iface.removePluginWebMenu("_tmp", info_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        self.tb_action = self.iface.webToolBar().addWidget(toolbutton)


    def _load_scales_list(self):
        scales_filename = os.path.join(self.plugin_dir, 'scales.xml')
        scales_list = []
        # TODO: remake when fix: http://hub.qgis.org/issues/11915
        # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message)
        xml_root = ET.parse(scales_filename).getroot()
        for scale_el in xml_root.findall('scale'):
            scales_list.append(scale_el.get('value'))
        return scales_list

    @property
    def scales_list(self):
        if not self._scales_list:
            self._scales_list = self._load_scales_list()
        return self._scales_list

    def set_nearest_scale(self):
        #get current scale
        curr_scale = self.iface.mapCanvas().scale()
        #find nearest
        nearest_scale = sys.maxint
        for scale_str in self.scales_list:
            scale = scale_str.split(':')[1]
            scale_int = int(scale)
            if abs(scale_int-curr_scale) < abs(nearest_scale - curr_scale):
                nearest_scale = scale_int

        #set new scale
        if nearest_scale != sys.maxint:
            self.iface.mapCanvas().zoomScale(nearest_scale)

    def set_tms_scales(self):
        res = QMessageBox.question(
            self.iface.mainWindow(),
            self.tr('QuickMapServices'),
            self.tr('Set SlippyMap scales for current project? \nThe previous settings will be overwritten!'),
            QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            # set scales
            QgsProject.instance().writeEntry('Scales', '/ScalesList', self.scales_list)
            # activate
            QgsProject.instance().writeEntry('Scales', '/useProjectScales', True)
            # update in main window
            # ???? no way to update: http://hub.qgis.org/issues/11917


    def insert_layer(self):
        #TODO: need factory!
        action = self.menu.sender()
        ds = action.data()
        if ds.type == KNOWN_DRIVERS.TMS:
            service_info = TileServiceInfo(self.tr(ds.alias), ds.copyright_text, ds.tms_url)
            service_info.zmin = ds.tms_zmin or service_info.zmin
            service_info.zmax = ds.tms_zmax or service_info.zmax
            layer = TileLayer(self, service_info, False)
        if ds.type == KNOWN_DRIVERS.GDAL:
            layer = QgsRasterLayer(ds.gdal_source_file, self.tr(ds.alias))
        if ds.type == KNOWN_DRIVERS.WMS:
            qgis_wms_uri = u''
            if ds.wms_params:
                qgis_wms_uri += ds.wms_params
            if ds.wms_layers:
                layers = ds.wms_layers.split(',')
                if layers:
                    if ds.wms_turn_over:
                        layers.reverse()
                    qgis_wms_uri += '&layers='+'&layers='.join(layers)+'&styles='*len(layers)
            qgis_wms_uri += '&url=' + ds.wms_url
            layer = QgsRasterLayer(qgis_wms_uri, self.tr(ds.alias), KNOWN_DRIVERS.WMS.lower())

        if not layer.isValid():
            error_message = self.tr('Layer %s can\'t be added to the map!') % ds.alias
            self.iface.messageBar().pushMessage(self.tr('Error'),
                                                error_message,
                                                level=QgsMessageBar.CRITICAL)
            QgsMessageLog.logMessage(error_message, level=QgsMessageLog.CRITICAL)
        else:
            # Set attribs
            layer.setAttribution(ds.copyright_text)
            layer.setAttributionUrl(ds.copyright_link)
            # Insert to bottom
            QgsMapLayerRegistry.instance().addMapLayer(layer, False)
            toc_root = QgsProject.instance().layerTreeRoot()
            toc_root.insertLayer(len(toc_root.children()), layer)
            # Save link
            self.service_layers.append(layer)


    def unload(self):
        # remove menu
        self.iface.webMenu().removeAction(self.menu.menuAction())
        # remove toolbar button
        self.iface.webToolBar().removeAction(self.tb_action)
        # clean vars
        self.menu = None
        self.toolbutton = None
        self.service_actions = None
        self.ds_list = None
        self.groups_list = None
        self.service_layers = None
        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(TileLayer.LAYER_TYPE)
Example #34
0
class QuickMapServices:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        self.translator = QTranslator()

        self.locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir, 'i18n',
            'QuickMapServices_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.custom_translator = CustomTranslator()
        QCoreApplication.installTranslator(self.custom_translator)

        # Create the dialog (after translation) and keep reference
        self.settings_dlg = SettingsDialog()
        self.info_dlg = AboutDialog()

        # Declare instance attributes
        self.service_actions = []
        self.service_layers = []  # TODO: id and smart remove
        self._scales_list = None

        # TileLayer assets
        self.crs3857 = None
        self.downloadTimeout = 30  # TODO: settings
        self.navigationMessagesEnabled = Qt.Checked  # TODO: settings
        self.pluginName = 'QuickMapServices'

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

    def initGui(self):
        #import pydevd
        #pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False)
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        # Main Menu
        icon_path = self.plugin_dir + '/icons/mActionAddLayer.png'
        self.menu = QMenu(self.tr(u'QuickMapServices'))
        self.menu.setIcon(QIcon(icon_path))

        # DataSources Actions

        # Register plugin layer type
        self.tileLayerType = TileLayerType(self)
        QgsPluginLayerRegistry.instance().addPluginLayerType(
            self.tileLayerType)

        self.groups_list = DsGroupsList(self.locale, self.custom_translator)
        self.ds_list = DataSourcesList(self.locale, self.custom_translator)

        data_sources = self.ds_list.data_sources.values()
        data_sources.sort(key=lambda x: x.alias or x.id)

        for ds in data_sources:
            ds.action.triggered.connect(self.insert_layer)
            gr_menu = self.groups_list.get_group_menu(ds.group)
            gr_menu.addAction(ds.action)
            if gr_menu not in self.menu.children():
                self.menu.addMenu(gr_menu)

        # Scales, Settings and About actions
        icon_set_nearest_scale_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        set_nearest_scale_act = QAction(QIcon(icon_set_nearest_scale_path),
                                        self.tr('Set proper scale'),
                                        self.iface.mainWindow())
        set_nearest_scale_act.triggered.connect(self.set_nearest_scale)
        self.menu.addAction(set_nearest_scale_act)  # TODO: uncomment after fix
        self.service_actions.append(set_nearest_scale_act)

        icon_scales_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        scales_act = QAction(QIcon(icon_scales_path),
                             self.tr('Set SlippyMap scales'),
                             self.iface.mainWindow())
        scales_act.triggered.connect(self.set_tms_scales)
        #self.menu.addAction(scales_act)  # TODO: uncomment after fix
        self.service_actions.append(scales_act)

        icon_settings_path = self.plugin_dir + '/icons/mActionSettings.png'
        settings_act = QAction(QIcon(icon_settings_path), self.tr('Settings'),
                               self.iface.mainWindow())
        self.service_actions.append(settings_act)
        #self.menu.addAction(settings_act)

        icon_about_path = self.plugin_dir + '/icons/mActionAbout.png'
        info_act = QAction(QIcon(icon_about_path), self.tr('About'),
                           self.iface.mainWindow())
        self.service_actions.append(info_act)
        info_act.triggered.connect(self.info_dlg.show)
        self.menu.addAction(info_act)

        # add to QGIS menu
        self.iface.addPluginToWebMenu("_tmp", info_act)
        self.iface.webMenu().addMenu(self.menu)
        self.iface.removePluginWebMenu("_tmp", info_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        self.tb_action = self.iface.webToolBar().addWidget(toolbutton)

    def _load_scales_list(self):
        scales_filename = os.path.join(self.plugin_dir, 'scales.xml')
        scales_list = []
        # TODO: remake when fix: http://hub.qgis.org/issues/11915
        # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message)
        xml_root = ET.parse(scales_filename).getroot()
        for scale_el in xml_root.findall('scale'):
            scales_list.append(scale_el.get('value'))
        return scales_list

    @property
    def scales_list(self):
        if not self._scales_list:
            self._scales_list = self._load_scales_list()
        return self._scales_list

    def set_nearest_scale(self):
        #get current scale
        curr_scale = self.iface.mapCanvas().scale()
        #find nearest
        nearest_scale = sys.maxint
        for scale_str in self.scales_list:
            scale = scale_str.split(':')[1]
            scale_int = int(scale)
            if abs(scale_int - curr_scale) < abs(nearest_scale - curr_scale):
                nearest_scale = scale_int

        #set new scale
        if nearest_scale != sys.maxint:
            self.iface.mapCanvas().zoomScale(nearest_scale)

    def set_tms_scales(self):
        res = QMessageBox.question(
            self.iface.mainWindow(), self.tr('QuickMapServices'),
            self.
            tr('Set SlippyMap scales for current project? \nThe previous settings will be overwritten!'
               ), QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            # set scales
            QgsProject.instance().writeEntry('Scales', '/ScalesList',
                                             self.scales_list)
            # activate
            QgsProject.instance().writeEntry('Scales', '/useProjectScales',
                                             True)
            # update in main window
            # ???? no way to update: http://hub.qgis.org/issues/11917

    def insert_layer(self):
        #TODO: need factory!
        action = self.menu.sender()
        ds = action.data()
        if ds.type == KNOWN_DRIVERS.TMS:
            service_info = TileServiceInfo(self.tr(ds.alias),
                                           ds.copyright_text, ds.tms_url)
            service_info.zmin = ds.tms_zmin or service_info.zmin
            service_info.zmax = ds.tms_zmax or service_info.zmax
            layer = TileLayer(self, service_info, False)
        if ds.type == KNOWN_DRIVERS.GDAL:
            layer = QgsRasterLayer(ds.gdal_source_file, self.tr(ds.alias))
        if ds.type == KNOWN_DRIVERS.WMS:
            qgis_wms_uri = u''
            if ds.wms_params:
                qgis_wms_uri += ds.wms_params
            if ds.wms_layers:
                layers = ds.wms_layers.split(',')
                if layers:
                    qgis_wms_uri += '&layers=' + '&layers='.join(
                        layers) + '&styles=' * len(layers)
            qgis_wms_uri += '&url=' + ds.wms_url
            layer = QgsRasterLayer(qgis_wms_uri, self.tr(ds.alias),
                                   KNOWN_DRIVERS.WMS.lower())

        if not layer.isValid():
            error_message = self.tr(
                'Layer %s can\'t be added to the map!') % ds.alias
            self.iface.messageBar().pushMessage(self.tr('Error'),
                                                error_message,
                                                level=QgsMessageBar.CRITICAL)
            QgsMessageLog.logMessage(error_message,
                                     level=QgsMessageLog.CRITICAL)
        else:
            # Set attribs
            layer.setAttribution(ds.copyright_text)
            layer.setAttributionUrl(ds.copyright_link)
            # Insert to bottom
            QgsMapLayerRegistry.instance().addMapLayer(layer, False)
            toc_root = QgsProject.instance().layerTreeRoot()
            toc_root.insertLayer(len(toc_root.children()), layer)
            # Save link
            self.service_layers.append(layer)

    def unload(self):
        # remove menu
        self.iface.webMenu().removeAction(self.menu.menuAction())
        # remove toolbar button
        self.iface.webToolBar().removeAction(self.tb_action)
        # clean vars
        self.menu = None
        self.toolbutton = None
        self.service_actions = None
        self.ds_list = None
        self.groups_list = None
        self.service_layers = None
        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(
            TileLayer.LAYER_TYPE)
Example #35
0
class QuickMapServices:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__).decode(
            sys.getfilesystemencoding())

        # initialize locale
        self.translator = QTranslator()

        self.locale = Locale.get_locale()
        locale_path = os.path.join(
            self.plugin_dir, 'i18n',
            'QuickMapServices_{}.qm'.format(self.locale))
        if os.path.exists(locale_path):
            self.translator.load(locale_path)
            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        self.custom_translator = CustomTranslator()
        QCoreApplication.installTranslator(self.custom_translator)

        # Create the dialog (after translation) and keep reference
        self.info_dlg = AboutDialog()

        # Check Contrib and User dirs
        try:
            ExtraSources.check_extra_dirs()
        except:
            error_message = self.tr(
                'Extra dirs for %s can\'t be created: %s %s') % (
                    PluginSettings.product_name(), sys.exc_type, sys.exc_value)
            self.iface.messageBar().pushMessage(self.tr('Error'),
                                                error_message,
                                                level=QgsMessageBar.CRITICAL)

        # Declare instance attributes
        self.service_actions = []
        self.service_layers = []  # TODO: id and smart remove
        self._scales_list = None

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

    def initGui(self):
        #import pydevd
        #pydevd.settrace('localhost', port=9921, stdoutToServer=True, stderrToServer=True, suspend=False)

        # Register plugin layer type
        self.tileLayerType = TileLayerType(self)
        QgsPluginLayerRegistry.instance().addPluginLayerType(
            self.tileLayerType)

        # Create menu
        icon_path = self.plugin_dir + '/icons/mActionAddLayer.png'
        self.menu = QMenu(self.tr(u'QuickMapServices'))
        self.menu.setIcon(QIcon(icon_path))

        self.build_menu_tree()

        # add to QGIS menu/toolbars
        self.append_menu_buttons()

    def _load_scales_list(self):
        scales_filename = os.path.join(self.plugin_dir, 'scales.xml')
        scales_list = []
        # TODO: remake when fix: http://hub.qgis.org/issues/11915
        # QgsScaleUtils.loadScaleList(scales_filename, scales_list, importer_message)
        xml_root = ET.parse(scales_filename).getroot()
        for scale_el in xml_root.findall('scale'):
            scales_list.append(scale_el.get('value'))
        return scales_list

    @property
    def scales_list(self):
        if not self._scales_list:
            self._scales_list = self._load_scales_list()
        return self._scales_list

    def set_nearest_scale(self):
        #get current scale
        curr_scale = self.iface.mapCanvas().scale()
        #find nearest
        nearest_scale = sys.maxint
        for scale_str in self.scales_list:
            scale = scale_str.split(':')[1]
            scale_int = int(scale)
            if abs(scale_int - curr_scale) < abs(nearest_scale - curr_scale):
                nearest_scale = scale_int

        #set new scale
        if nearest_scale != sys.maxint:
            self.iface.mapCanvas().zoomScale(nearest_scale)

    def set_tms_scales(self):
        res = QMessageBox.question(
            self.iface.mainWindow(), self.tr('QuickMapServices'),
            self.
            tr('Set SlippyMap scales for current project? \nThe previous settings will be overwritten!'
               ), QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            # set scales
            QgsProject.instance().writeEntry('Scales', '/ScalesList',
                                             self.scales_list)
            # activate
            QgsProject.instance().writeEntry('Scales', '/useProjectScales',
                                             True)
            # update in main window
            # ???? no way to update: http://hub.qgis.org/issues/11917

    def insert_layer(self):
        #TODO: need factory!
        layers4add = []
        action = self.menu.sender()
        ds = action.data()
        if ds.type == KNOWN_DRIVERS.TMS:
            service_info = TileServiceInfo(self.tr(ds.alias),
                                           ds.copyright_text, ds.tms_url)
            service_info.zmin = ds.tms_zmin or service_info.zmin
            service_info.zmax = ds.tms_zmax or service_info.zmax
            if ds.tms_y_origin_top is not None:
                service_info.yOriginTop = ds.tms_y_origin_top
            service_info.epsg_crs_id = ds.tms_epsg_crs_id
            service_info.postgis_crs_id = ds.tms_postgis_crs_id
            service_info.custom_proj = ds.tms_custom_proj
            layer = TileLayer(self, service_info, False)
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.GDAL:
            layer = QgsRasterLayer(ds.gdal_source_file, self.tr(ds.alias))
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.WMS:
            qgis_wms_uri = u''
            if ds.wms_params:
                qgis_wms_uri += ds.wms_params
            if ds.wms_layers:
                layers = ds.wms_layers.split(',')
                if layers:
                    if ds.wms_turn_over:
                        layers.reverse()
                    qgis_wms_uri += '&layers=' + '&layers='.join(
                        layers) + '&styles=' * len(layers)
            qgis_wms_uri += '&url=' + ds.wms_url
            layer = QgsRasterLayer(qgis_wms_uri, self.tr(ds.alias),
                                   KNOWN_DRIVERS.WMS.lower())
            layers4add.append(layer)
        if ds.type == KNOWN_DRIVERS.WFS:
            qgis_wfs_uri_base = ds.wfs_url
            o = urlparse.urlparse(qgis_wfs_uri_base)
            request_attrs = dict(urlparse.parse_qsl(o.query))

            layers_str = request_attrs.get('TYPENAME', '')
            layers = layers_str.split(',')
            for layer_name in layers:
                new_request_attrs = request_attrs
                new_request_attrs['TYPENAME'] == layer_name

                url_parts = list(o)
                url_parts[4] = "&".join(
                    ["%s=%s" % (k, v) for k, v in new_request_attrs.items()])

                qgis_wfs_uri = urlparse.urlunparse(url_parts)

                layer = QgsVectorLayer(
                    qgis_wfs_uri, "%s - %s" % (self.tr(ds.alias), layer_name),
                    "WFS")
                layers4add.append(layer)

        for layer in layers4add:
            if not layer.isValid():
                error_message = self.tr(
                    'Layer %s can\'t be added to the map!') % ds.alias
                self.iface.messageBar().pushMessage(
                    self.tr('Error'),
                    error_message,
                    level=QgsMessageBar.CRITICAL)
                QgsMessageLog.logMessage(error_message,
                                         level=QgsMessageLog.CRITICAL)
            else:
                # Set attribs
                layer.setAttribution(ds.copyright_text)
                layer.setAttributionUrl(ds.copyright_link)
                # Insert to bottom
                QgsMapLayerRegistry.instance().addMapLayer(layer, False)
                toc_root = QgsProject.instance().layerTreeRoot()
                toc_root.insertLayer(len(toc_root.children()), layer)
                # Save link
                self.service_layers.append(layer)
                # Set OTF CRS Transform for map
                if PluginSettings.enable_otf_3857(
                ) and ds.type == KNOWN_DRIVERS.TMS:
                    self.iface.mapCanvas().setCrsTransformEnabled(True)
                    self.iface.mapCanvas().setDestinationCrs(
                        TileLayer.CRS_3857)

    def unload(self):
        # remove menu/
        self.remove_menu_buttons()

        # clean vars
        self.menu = None
        self.toolbutton = None
        self.service_actions = None
        self.ds_list = None
        self.groups_list = None
        self.service_layers = None
        # Unregister plugin layer type
        QgsPluginLayerRegistry.instance().removePluginLayerType(
            TileLayer.LAYER_TYPE)

    def build_menu_tree(self):
        # Main Menu
        self.menu.clear()

        self.groups_list = GroupsList()
        self.ds_list = DataSourcesList()

        data_sources = self.ds_list.data_sources.values()
        data_sources.sort(key=lambda x: x.alias or x.id)

        ds_hide_list = PluginSettings.get_hide_ds_id_list()

        for ds in data_sources:
            if ds.id in ds_hide_list:
                continue
            ds.action.triggered.connect(self.insert_layer)
            gr_menu = self.groups_list.get_group_menu(ds.group)
            gr_menu.addAction(ds.action)
            if gr_menu not in self.menu.children():
                self.menu.addMenu(gr_menu)

        # Scales, Settings and About actions
        self.menu.addSeparator()
        icon_set_nearest_scale_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        set_nearest_scale_act = QAction(QIcon(icon_set_nearest_scale_path),
                                        self.tr('Set proper scale'),
                                        self.iface.mainWindow())
        set_nearest_scale_act.triggered.connect(self.set_nearest_scale)
        self.menu.addAction(set_nearest_scale_act)  # TODO: uncomment after fix
        self.service_actions.append(set_nearest_scale_act)

        icon_scales_path = self.plugin_dir + '/icons/mActionSettings.png'  # TODO change icon
        scales_act = QAction(QIcon(icon_scales_path),
                             self.tr('Set SlippyMap scales'),
                             self.iface.mainWindow())
        scales_act.triggered.connect(self.set_tms_scales)
        #self.menu.addAction(scales_act)  # TODO: uncomment after fix
        self.service_actions.append(scales_act)

        icon_settings_path = self.plugin_dir + '/icons/mActionSettings.png'
        settings_act = QAction(QIcon(icon_settings_path), self.tr('Settings'),
                               self.iface.mainWindow())
        self.service_actions.append(settings_act)
        settings_act.triggered.connect(self.show_settings_dialog)
        self.menu.addAction(settings_act)

        icon_about_path = self.plugin_dir + '/icons/mActionAbout.png'
        info_act = QAction(QIcon(icon_about_path), self.tr('About'),
                           self.iface.mainWindow())
        self.service_actions.append(info_act)
        info_act.triggered.connect(self.info_dlg.show)
        self.menu.addAction(info_act)

    def remove_menu_buttons(self):
        """
        Remove menus/buttons from all toolbars and main submenu
        :return:
        None
        """
        # remove menu
        if self.menu:
            self.iface.webMenu().removeAction(self.menu.menuAction())
            self.iface.addLayerMenu().removeAction(self.menu.menuAction())
        # remove toolbar button
        if self.tb_action:
            self.iface.webToolBar().removeAction(self.tb_action)
            self.iface.layerToolBar().removeAction(self.tb_action)

    def append_menu_buttons(self):
        """
        Append menus and buttons to appropriate toolbar
        :return:
        """
        # add to QGIS menu
        if PluginSettings.move_to_layers_menu():
            self.iface.addLayerMenu().addMenu(self.menu)
        else:
            # need workaround for WebMenu
            _temp_act = QAction('temp', self.iface.mainWindow())
            self.iface.addPluginToWebMenu("_tmp", _temp_act)
            self.iface.webMenu().addMenu(self.menu)
            self.iface.removePluginWebMenu("_tmp", _temp_act)

        # add to QGIS toolbar
        toolbutton = QToolButton()
        toolbutton.setPopupMode(QToolButton.InstantPopup)
        toolbutton.setMenu(self.menu)
        toolbutton.setIcon(self.menu.icon())
        toolbutton.setText(self.menu.title())
        toolbutton.setToolTip(self.menu.title())
        if PluginSettings.move_to_layers_menu():
            self.tb_action = self.iface.layerToolBar().addWidget(toolbutton)
        else:
            self.tb_action = self.iface.webToolBar().addWidget(toolbutton)

    def show_settings_dialog(self):
        settings_dlg = SettingsDialog()
        settings_dlg.exec_()
        # apply settings
        # self.remove_menu_buttons()
        self.build_menu_tree()
Example #36
0
class QuickOSM:

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

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

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

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

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

        # Create the folder if it does not exist.
        get_user_query_folder(over_write=True)

        # Add to processing
        self.provider = QuickOSMAlgorithmProvider()
        Processing.addProvider(self.provider, True)

        # Add the toolbar
        self.toolbar = self.iface.addToolBar('QuickOSM')
        self.toolbar.setObjectName('QuickOSM')

        self.quickosm_menu = None
        self.dock_menu = None
        self.web_menu = None
        self.mainWindowAction = None
        self.osmFileAction = None
        self.osmFileDockWidget = None
        self.myQueriesAction = None
        self.myQueriesDockWidget = None
        self.queryAction = None
        self.queryDockWidget = None
        self.quickQueryAction = None
        self.quickQueryDockWidget = None

    def initGui(self):

        # Setup menu
        self.quickosm_menu = QMenu('Quick OSM')
        self.quickosm_menu.setIcon(QIcon(':/plugins/QuickOSM/icon.png'))
        self.dock_menu = QMenu(tr('QuickOSM', u'Dock'))
        self.web_menu = self.iface.webMenu()
        self.web_menu.addMenu(self.quickosm_menu)

        # Main window
        self.mainWindowAction = QAction(
            QIcon(':/plugins/QuickOSM/icon.png'),
            u'QuickOSM',
            self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.mainWindowAction.triggered.connect(self.openMainWindow)
        self.toolbar.addAction(self.mainWindowAction)
        self.iface.QuickOSM_mainWindowDialog = MainWindowDialog()

        # OSM File
        self.osmFileAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/open.png'),
            tr('ui_osm_file', 'OSM File'),
            self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.osmFileAction.triggered.connect(self.openOsmFileDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.osmFileAction)
        self.osmFileDockWidget = OsmFileDockWidget()
        self.iface.addDockWidget(
            Qt.RightDockWidgetArea, self.osmFileDockWidget)
        self.osmFileDockWidget.hide()
        self.osmFileDockWidget.setObjectName('osmFileWidget')

        # My queries
        self.myQueriesAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/favorites.png'),
            tr('ui_my_queries', 'My queries'),
            self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.myQueriesAction.triggered.connect(self.openMyQueriesDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.myQueriesAction)
        self.myQueriesDockWidget = MyQueriesDockWidget()
        self.iface.addDockWidget(
            Qt.RightDockWidgetArea, self.myQueriesDockWidget)
        self.myQueriesDockWidget.hide()
        self.myQueriesDockWidget.setObjectName('myQueriesWidget')

        # Query
        self.queryAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/edit.png'),
            tr('ui_query', 'Query'),
            self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.queryAction.triggered.connect(self.openQueryDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.queryAction)
        self.queryDockWidget = QueryDockWidget()
        self.iface.addDockWidget(Qt.RightDockWidgetArea, self.queryDockWidget)
        self.queryDockWidget.hide()
        self.queryDockWidget.setObjectName('queryWidget')

        # Quick query
        self.quickQueryAction = QAction(
            QIcon(':/plugins/QuickOSM/resources/quick.png'),
            tr('ui_quick_query', 'Quick query'),
            self.iface.mainWindow())
        # noinspection PyUnresolvedReferences
        self.quickQueryAction.triggered.connect(self.openQuickQueryDockWidget)
        self.iface.addPluginToWebMenu(u"&Quick OSM", self.quickQueryAction)
        self.quickQueryDockWidget = QuickQueryDockWidget()
        self.iface.addDockWidget(
            Qt.RightDockWidgetArea, self.quickQueryDockWidget)
        self.quickQueryDockWidget.hide()
        self.quickQueryDockWidget.setObjectName('quickQueryWidget')

        # Insert in the good order
        self.quickosm_menu.addAction(self.mainWindowAction)
        self.quickosm_menu.addMenu(self.dock_menu)
        self.dock_menu.addAction(self.quickQueryAction)
        self.dock_menu.addAction(self.queryAction)
        self.dock_menu.addAction(self.myQueriesAction)
        self.dock_menu.addAction(self.osmFileAction)

        # Connect signals and slots from dock
        self.queryDockWidget.signal_new_query_successful.connect(
            self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)
        self.queryDockWidget.signal_new_query_successful.connect(
            self.myQueriesDockWidget.refresh_my_queries_tree)
        self.myQueriesDockWidget.signal_delete_query_successful.connect(
            self.myQueriesDockWidget.refresh_my_queries_tree)
        self.myQueriesDockWidget.signal_delete_query_successful.connect(
            self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)

        # Connect signals and slots from mainWindow
        self.iface.QuickOSM_mainWindowDialog.signal_new_query_successful.\
            connect(self.myQueriesDockWidget.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_new_query_successful.\
            connect(
                self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_delete_query_successful.\
            connect(self.myQueriesDockWidget.refresh_my_queries_tree)
        self.iface.QuickOSM_mainWindowDialog.signal_delete_query_successful.\
            connect(
                self.iface.QuickOSM_mainWindowDialog.refresh_my_queries_tree)

        # Read the config file
        json_file_config = join(dirname(abspath(__file__)), 'config.json')
        if isfile(json_file_config):
            config_json = load(open(json_file_config))
            for server in config_json['overpass_servers']:
                self.iface.QuickOSM_mainWindowDialog.comboBox_default_OAPI.\
                    addItem(server)

        # Check previous version and if new queries are available
        version = get_setting('version')
        current_version = get_current_version()
        if version != current_version:
            if new_queries_available():
                message = 'New queries are available in the plugin. Would ' \
                          'like to install them ? This will overwrite the ' \
                          'current default queries.'
                title = 'QuickOSM'
                message = tr('QuickOSM', message)
                widget = self.iface.messageBar().createMessage(title, message)
                button_ok = QPushButton(widget)
                button_ok.setText(
                    tr('QuickOSM', 'Install'))
                button_ok.pressed.connect(self.restoreDefaultQueries)
                widget.layout().addWidget(button_ok)
                self.iface.messageBar().pushWidget(
                    widget, QgsMessageBar.INFO, 0)

            set_setting('version', current_version)

    def restoreDefaultQueries(self):
        self.iface.QuickOSM_mainWindowDialog.restore_default_queries()
        self.iface.messageBar().popWidget()

    def unload(self):
        self.iface.removePluginWebMenu(u'&QuickOSM', self.mainWindowAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.myQueriesAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.queryAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.quickQueryAction)
        self.iface.removePluginWebMenu(u'&QuickOSM', self.osmFileAction)
        self.iface.removeToolBarIcon(self.mainWindowAction)
        Processing.removeProvider(self.provider)

    def openMainWindow(self):
        self.iface.QuickOSM_mainWindowDialog.listWidget.setCurrentRow(0)
        self.iface.QuickOSM_mainWindowDialog.exec_()

    def openMyQueriesDockWidget(self):
        if self.myQueriesDockWidget.isVisible():
            self.myQueriesDockWidget.hide()
        else:
            self.myQueriesDockWidget.show()

    def openQueryDockWidget(self):
        if self.queryDockWidget.isVisible():
            self.queryDockWidget.hide()
        else:
            self.queryDockWidget.show()

    def openOsmFileDockWidget(self):
        if self.osmFileDockWidget.isVisible():
            self.osmFileDockWidget.hide()
        else:
            self.osmFileDockWidget.show()

    def openQuickQueryDockWidget(self):
        if self.quickQueryDockWidget.isVisible():
            self.quickQueryDockWidget.hide()
        else:
            self.quickQueryDockWidget.show()
Example #37
0
class qosm:
    """QGIS Plugin Implementation."""

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

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

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

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

        # Create the dialog (after translation) and keep reference
        self.dlg_settings = None #TODO: add settings dialog

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&QOSM')
        
        self.toolbar = self.iface.addToolBar(u'QOSM')
        self.toolbar.setObjectName(u'QOSM')
        
        self.layers = []

    # 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('qosm', message)


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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.menuObject.addAction(action)

        self.actions.append(action)

        return action

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

        #start logging
        qosmlogging.initialize_logging()
        qosmlogging.log("Initizlizing GUI")
        
        self.settingsdialog = DialogSettings(None)
        
        #add menu to web
        self.menuObject = QMenu(self.menu)
        self.menuObject.setIcon(QIcon(":/plugins/qosm/icon.png"))
        
        tmpAction = QAction("_tmp", self.iface.mainWindow())
        self.iface.addPluginToWebMenu("_tmp", tmpAction)
        self._menu = self.iface.webMenu()
        self._menu.addMenu(self.menuObject)
        self.iface.removePluginWebMenu("_tmp", tmpAction)        
        
        self.add_action(
            ':/plugins/qosm/icon_newlayer.png',
            text=self.tr(u'Add OSM tile layer'),
            callback=self.addOSMLayer,
            parent=self.iface.mainWindow())
        
        self.add_action(
            ':/plugins/qosm/icon_refresh.png',
            text=self.tr(u'Refresh OSM tile layers'),
            callback=self.refreshOSMLayers,
            parent=self.iface.mainWindow())
        
        self.add_action(
            ':/plugins/qosm/icon_settings.png',
            text=self.tr(u'QOSM Settings'),
            callback=self.qosmSettings,
            parent=self.iface.mainWindow())
        
        self.pluginLayerType = QOSMTileLayerType(self, self.onAddOSMLayer)
        QgsPluginLayerRegistry.instance().addPluginLayerType(self.pluginLayerType)
        QgsMapLayerRegistry.instance().layersWillBeRemoved["QStringList"].connect(self.cleanLayerResources)


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginWebMenu(
                self.menu,
                action)
            self.iface.removeToolBarIcon(action)
            
        self.iface.webMenu().removeAction(self.menuObject.menuAction())
            
        # remove the toolbar
        del self.toolbar
        del self.menuObject
        
        QgsPluginLayerRegistry.instance().removePluginLayerType(QOSMTileLayer.LAYER_TYPE)
        QgsMapLayerRegistry.instance().layersWillBeRemoved["QStringList"].disconnect(self.cleanLayerResources)

    @pyqtSlot()
    def cleanLayerResources(self, layers):
        reg = QgsMapLayerRegistry.instance()
        for layerid in layers:
            layer = reg.mapLayer(layerid)
            if isinstance(layer, QOSMTileLayer):
                layer.cleantiles()
                #remove from internal cache of layers
                for i in range(len(self.layers)):
                    if self.layers[i].id() == layerid:
                        self.layers.pop(i)
                        break
        
    
    def addOSMLayer(self):
        """Adds a new OSM layer and opens the properties dialog to default settings"""
        # add a new qosmtilelayer
        layer = self.pluginLayerType.createLayer()
        QgsMapLayerRegistry.instance().addMapLayer(layer)
        self.pluginLayerType.showLayerProperties(layer, newlayer=True)
    
    def refreshOSMLayers(self):
        #manual refresh OSM Layers
        for layer in self.layers:
            layer.refreshtiles()
    
    def qosmSettings(self):
        self.settingsdialog.sync_dialog()
        self.settingsdialog.show()
    
    def onAddOSMLayer(self, layer):
        self.layers.append(layer)
Example #38
0
    def get_plugin_actions(self):
        """Return a list of actions related to plugin"""
        quit_action = create_action(self, _("&Quit"), icon="exit.png", tip=_("Quit"), triggered=self.quit)
        self.register_shortcut(quit_action, "_", "Quit", "Ctrl+Q")
        run_action = create_action(
            self, _("&Run..."), None, "run_small.png", _("Run a Python script"), triggered=self.run_script
        )
        environ_action = create_action(
            self,
            _("Environment variables..."),
            icon="environ.png",
            tip=_("Show and edit environment variables" " (for current session)"),
            triggered=self.show_env,
        )
        syspath_action = create_action(
            self,
            _("Show sys.path contents..."),
            icon="syspath.png",
            tip=_("Show (read-only) sys.path"),
            triggered=self.show_syspath,
        )
        buffer_action = create_action(
            self, _("Buffer..."), None, tip=_("Set maximum line count"), triggered=self.change_max_line_count
        )
        font_action = create_action(
            self, _("&Font..."), None, "font.png", _("Set shell font style"), triggered=self.change_font
        )
        exteditor_action = create_action(
            self,
            _("External editor path..."),
            None,
            None,
            _("Set external editor executable path"),
            triggered=self.change_exteditor,
        )
        wrap_action = create_action(self, _("Wrap lines"), toggled=self.toggle_wrap_mode)
        wrap_action.setChecked(self.get_option("wrap"))
        calltips_action = create_action(self, _("Balloon tips"), toggled=self.toggle_calltips)
        calltips_action.setChecked(self.get_option("calltips"))
        codecompletion_action = create_action(self, _("Automatic code completion"), toggled=self.toggle_codecompletion)
        codecompletion_action.setChecked(self.get_option("codecompletion/auto"))
        codecompenter_action = create_action(
            self, _("Enter key selects completion"), toggled=self.toggle_codecompletion_enter
        )
        codecompenter_action.setChecked(self.get_option("codecompletion/enter_key"))

        option_menu = QMenu(_("Internal console settings"), self)
        option_menu.setIcon(get_icon("tooloptions.png"))
        add_actions(
            option_menu,
            (
                buffer_action,
                font_action,
                wrap_action,
                calltips_action,
                codecompletion_action,
                codecompenter_action,
                exteditor_action,
            ),
        )

        plugin_actions = [None, run_action, environ_action, syspath_action, option_menu, None, quit_action]

        # Add actions to context menu
        add_actions(self.shell.menu, plugin_actions)

        return plugin_actions