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())
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))
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)
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())
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)
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
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
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
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)
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)
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
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
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>"))
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())
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 © 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))
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 © 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), )
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
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)
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
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)
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()
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())
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)
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)
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 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()
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)
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