def createCaptureButtons(self, form, wasselected): tool = form.getMaptool()(self.canvas) action = QAction(QIcon(":/icons/capture"), "Capture", None) action.setObjectName("capture") action.setCheckable(True) action.toggled.connect(partial(self.setMapTool, tool)) if isinstance(tool, PointTool): add = partial(self.addNewFeature, form) tool.geometryComplete.connect(add) else: tool.finished.connect(self.openForm) tool.error.connect(partial(self.showToolError, form.label)) # Set the action as a data entry button so we can remove it later. action.setProperty("dataentry", True) self.actionGPSFeature.setVisible(not tool.isEditTool()) self.projecttoolbar.insertAction(self.topspaceraction, action) self.projecttoolbar.insertAction(self.topspaceraction, self.actionGPSFeature) self.editgroup.addAction(action) self.layerbuttons.append(action) action.setChecked(wasselected)
def setupMenuBar(self): self.fileMenu = self.menuBar().addMenu("&File") self.dateFormatMenu = self.fileMenu.addMenu("&Date format") self.dateFormatGroup = QActionGroup(self) for f in self.dateFormats: action = QAction(f, self, checkable=True, triggered=self.changeDateFormat) self.dateFormatGroup.addAction(action) self.dateFormatMenu.addAction(action) if f == self.currentDateFormat: action.setChecked(True) self.fileMenu.addAction(self.printAction) self.fileMenu.addAction(self.exitAction) self.cellMenu = self.menuBar().addMenu("&Cell") self.cellMenu.addAction(self.cell_addAction) self.cellMenu.addAction(self.cell_subAction) self.cellMenu.addAction(self.cell_mulAction) self.cellMenu.addAction(self.cell_divAction) self.cellMenu.addAction(self.cell_sumAction) self.cellMenu.addSeparator() self.cellMenu.addAction(self.colorAction) self.cellMenu.addAction(self.fontAction) self.menuBar().addSeparator() self.aboutMenu = self.menuBar().addMenu("&Help") self.aboutMenu.addAction(self.aboutSpreadSheet)
def addDocument(self, doc): a = QAction(self) a.setCheckable(True) if doc is self.mainwindow().currentDocument(): a.setChecked(True) self._acts[doc] = a self.setDocumentStatus(doc)
def _buildMenu(self): self.framelessCheck = QtGui.QAction("Frameless Window", self, checkable=True) self.connect(self.framelessCheck, SIGNAL("triggered()"), self.trayIcon.changeFrameless) self.addAction(self.framelessCheck) self.addSeparator() self.requestCheck = QtGui.QAction("Show status request notifications", self, checkable=True) self.requestCheck.setChecked(True) self.addAction(self.requestCheck) self.connect(self.requestCheck, SIGNAL("triggered()"), self.trayIcon.switchRequest) self.alarmCheck = QtGui.QAction("Show alarm notifications", self, checkable=True) self.alarmCheck.setChecked(True) self.connect(self.alarmCheck, SIGNAL("triggered()"), self.trayIcon.switchAlarm) self.addAction(self.alarmCheck) distanceMenu = self.addMenu("Alarm Distance") self.distanceGroup = QActionGroup(self) for i in range(0, 6): action = QAction("{0} Jumps".format(i), None, checkable=True) if i == 0: action.setChecked(True) action.alarmDistance = i self.connect(action, SIGNAL("triggered()"), self.changeAlarmDistance) self.distanceGroup.addAction(action) distanceMenu.addAction(action) self.addMenu(distanceMenu) self.addSeparator() self.quitAction = QAction("Quit", self) self.connect(self.quitAction, SIGNAL("triggered()"), self.trayIcon.quit) self.addAction(self.quitAction)
def add_toggle_action_to_menu(self, menu, caption, checked, call ): action = QAction(caption, menu) action.setCheckable(True) action.setChecked(checked) menu.addAction(action) action.toggled.connect(call) return action
class MiTraceView(QWidget): def __init__(self, do, parent): QWidget.__init__(self, parent) self.ui = Ui_MiTraceView() self.ui.setupUi(self) self.__do = do self.ui.commandEdit.lineEdit().returnPressed.connect(self.executeMiCommand) self.__do.gdb_connector.commandExecuted.connect(self.appendCommand) self.__do.gdb_connector.reader.asyncRecordReceived.connect(self.appendAsync) self.__timeAction = QAction(Icons.time, "Show Elapsed Time", self) self.__timeAction.setCheckable(True) self.__timeAction.setChecked(True) parent.titleBarWidget().addAction(self.__timeAction) parent.addClearAction() parent.clearRequested.connect(self.ui.traceView.clear) def appendCommand(self, cmd, rec, time): timestr = "[<i>%.3f</i>] " % time if self.__timeAction.isChecked() else "" self.ui.traceView.append("%s<b>%s</b>" % (timestr, cmd)) color = 'color="#ff3333"' if rec.class_ == GdbOutput.ERROR else "" self.ui.traceView.append("<font %s>%s</font>" % (color, rec.raw)) def appendAsync(self, rec): self.ui.traceView.append('<font color="#777777">%s</font>' % rec.raw) def executeMiCommand(self): cmd = str(self.ui.commandEdit.lineEdit().text()) self.ui.commandEdit.lineEdit().setText("") self.__do.gdb_connector.execute(cmd)
def addBranch(self, branch): a = QAction(self) a.setCheckable(True) if branch == vcs.app_repo.current_branch(): a.setChecked(True) a.setEnabled(False) self._acts[branch] = a self.setBranchStatus(branch)
def get_actions(self, menu_class): actions = [] for menu_item in menu_class.ALL: action = QAction(menu_item.name, self) action.setCheckable(True) if menu_item == menu_class.DEFAULT: action.setChecked(True) actions.append(action) return actions
def makeActions(): for col, title in enumerate(model.columnLabels()): action = QAction(title, header) action.setCheckable(True) action.setChecked(Qt.Checked) handler = partial(self.setTickersColumnEnabled, column=col) connect(action, Signals.toggled, handler) header.setResizeMode(col, header.Stretch) yield action
def getActions(self): """ @rtype: list of QAction """ advanced_toggle_action = QAction("Show Advanced Options", self) advanced_toggle_action.setObjectName("AdvancedSimulationOptions") advanced_toggle_action.setCheckable(True) advanced_toggle_action.setChecked(False) advanced_toggle_action.toggled.connect(self.toggleAdvanced) return [advanced_toggle_action]
class FunderingGeometryEditor(): def __init__(self, iface): self.iface = iface self.mapCanvas = iface.mapCanvas() self.mapTool = None # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) def initGui(self): """ runs when plugin is activated from the plugin menu """ # help self.helpAction = QAction(QIcon(":/funderingsherstel/icons/help.svg"), "Help", self.iface.mainWindow()) self.helpAction.triggered.connect(lambda: QDesktopServices().openUrl(QUrl("mailto:[email protected]"))) # Create the dock (after translation) and keep reference self.dock = DockEditorDialog(self.iface, self.mapCanvas) self.dock.setVisible(False) self.dock.visibilityChanged.connect(self.dockVisibilityChanged) # map tool actionand default state self.mapToolAction = QAction(QIcon(":/funderingsherstel/icons/fundering.svg"), u"Funderingsherstel", self.iface.mainWindow()) self.mapToolAction.setCheckable(True) self.mapToolAction.setChecked(False) self.mapToolAction.triggered.connect(self.dock.setVisible) self.iface.addToolBarIcon(self.mapToolAction) # menu self.iface.addPluginToMenu("&Funderingsherstel", self.mapToolAction) self.iface.addPluginToMenu("&Funderingsherstel", self.helpAction) def unload(self): # Unset the map tool in case it's set self.mapToolAction.setChecked(False) self.iface.removePluginMenu("&Funderingsherstel", self.helpAction) self.iface.removePluginMenu("&Funderingsherstel", self.mapToolAction) self.iface.removeToolBarIcon(self.mapToolAction) self.dock.hide() self.dock.deleteLater() def dockVisibilityChanged(self): if self.dock.isVisible() is True: self.mapTool = IdentifyGeometry(self.mapCanvas) self.mapTool.geomIdentified.connect(self.editGeometry) self.mapTool.setAction(self.mapToolAction) self.mapCanvas.setMapTool(self.mapTool) else: self.dock.close() self.mapCanvas.unsetMapTool(self.mapTool) def editGeometry(self, layer, feature): self.dock.featureSelected(layer, feature)
def populate_switch_effect_menu(self, target_menu, checked_item): effect_menu = QMenu(i18n("Effect"), target_menu) for preset in LADSPAEffects().effects(): action = QAction(preset["preset_name"],effect_menu) effect_menu.addAction(action) if checked_item == preset["label"]: action.setCheckable(True) action.setChecked(True) action.setEnabled(False) target_menu.addMenu(effect_menu)
def _buildOutputs(self): self.menuOutputs.clear() if self.mpdclient.connected(): print 'debug: Building output menu.' for output in self.mpdclient.outputs(): action = QAction(output.get('outputname', 'No name'), self.menuOutputs) action.setCheckable(True) action.setChecked(output.get('outputenabled', '0') == '1') action.outputid = output.get('outputid') self.menuOutputs.addAction(action)
def __createMenu(self): file_menu = self.menuBar().addMenu("&File") file_menu.addAction("Close", self.__quit) self.__view_menu = self.menuBar().addMenu("&View") """ @rtype: list of QAction """ advanced_toggle_action = QAction("Show Advanced Options", self) advanced_toggle_action.setObjectName("AdvancedSimulationOptions") advanced_toggle_action.setCheckable(True) advanced_toggle_action.setChecked(False) advanced_toggle_action.toggled.connect(self.toggleAdvancedMode) self.__view_menu.addAction(advanced_toggle_action)
def _onMenuAboutToShow(self): """View -> Highlighting menu is about to show. Fill it with items """ self._menu.clear() # if menu is enabled - current document is not NULL currentLanguage = core.workspace().currentDocument().language() for languageName, fileNameGlobs, firstLineGlobs, iconPath in self.iterLanguages(): # pylint: disable=W0612 action = QAction(QIcon(iconPath), languageName, self._menu) action.setCheckable(True) if languageName == currentLanguage: action.setChecked(True) self._menu.addAction(action) self._menu.triggered.connect(self._onMenuTriggered)
def context_menu_create_custom(self): self.context_menu_create_ports() self.context_menu_create_sounddevices() action_device = QAction(i18n("Default Sink"), self.popup_menu) self.popup_menu.addAction(action_device) action_device.setCheckable(True) if self.isDefaultSink(): action_device.setChecked(True) action_device.setEnabled(False) else: action_device.setChecked(False) action_device.setEnabled(True) action_device.triggered.connect(self.on_set_default_sink_triggered)
def _on_header_menu(self, point): menu = QMenu() for index, title in enumerate(self.model().header): action = QAction(self) action.setData(index) action.setText(title) action.setCheckable(True) action.setChecked(False if self.isColumnHidden(index) else True) action.triggered.connect(self._on_header_menu_action) menu.addAction(action) menu.popup(self.mapToGlobal(point)) menu.exec_()
def headerContextMenu( self, pos ): actions = [] for i, name in enumerate( self.labels[1:] ): action = QAction( name, self ) action.setCheckable( True ) action.setChecked( not self.isColumnHidden( i + 1 ) ) actions.append( action ) menu = QMenu() act = menu.exec_( actions, QCursor.pos() ) if act is None: return index = actions.index( act ) + 1 self.setColumnHidden( index, not self.isColumnHidden( index ) )
def _NH_SIPAccountManagerDidAddAccount(self, notification): account = notification.data.account action = QAction(account.id if account is not BonjourAccount() else u'Bonjour', None) action.setEnabled(True if account is not BonjourAccount() else BonjourAccount.mdns_available) action.setCheckable(True) action.setChecked(account.enabled) action.setData(account) action.triggered.connect(partial(self._AH_AccountActionTriggered, action)) self.accounts_menu.addAction(action) action = QAction(self.mwi_icons[0], account.id, None) action.setVisible(False if account is BonjourAccount() else account.enabled and account.message_summary.enabled) action.setEnabled(False if account is BonjourAccount() else account.voicemail_uri is not None) action.setData(account) action.triggered.connect(partial(self._AH_VoicemailActionTriggered, action)) self.voicemail_menu.addAction(action)
def contextMenuEvent(self, e): mdl = self.model() irow = self.rowAt(e.y()) #print "Row:", self.rowAt(e.y()) cmenu = QMenu() m_dis = QAction("disabled", self) m_dis.setCheckable(True) act = mdl.isActive(irow) if not act: m_dis.setChecked(True) self.connect(m_dis, SIGNAL("toggled(bool)"), partial(self.disableElement, irow=irow)) cmenu.addAction(m_dis) cmenu.exec_(e.globalPos())
class MainWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self._create_actions() self._create_toolbar() self._canvas = Canvas() self._canvas.scale(16, 16) self.setCentralWidget(self._canvas) def _create_actions(self): self._delete_action = QAction("Delete", None) self._delete_action.setShortcuts(QKeySequence.Delete) self._delete_action.triggered.connect(self._delete) self._select_action = QAction("Select", None) self._select_action.setCheckable(True) self._select_action.triggered.connect(self._use_select_tool) self._pen_action = QAction("Pen", None) self._pen_action.setCheckable(True) self._pen_action.setChecked(True) self._pen_action.triggered.connect(self._use_pen_tool) self._new_shape_action = QAction("New Shape", None) self._new_shape_action.triggered.connect(self._new_shape) self._tool_group = QActionGroup(None) self._tool_group.addAction(self._select_action) self._tool_group.addAction(self._pen_action) def _create_toolbar(self): toolbar = self.addToolBar("Tools") toolbar.addAction(self._delete_action) toolbar.addAction(self._select_action) toolbar.addAction(self._pen_action) toolbar.addAction(self._new_shape_action) def _use_select_tool(self): self._canvas.use_tool(SelectTool) def _use_pen_tool(self): self._canvas.use_tool(PenTool) def _new_shape(self): self._canvas.new_shape() def _delete(self): self._canvas.delete_selection()
def create_action( parent , callback , text , checkable , checked , icon_path ): pixmap = QPixmap(icon_path) icon = QIcon(pixmap) action = QAction(icon, text, parent) # action.setIcon(icon) # action.setIconText(text) action.triggered.connect(callback) action.setCheckable(checkable) action.setChecked(checked) return action
def context_menu_create_ports(self): self.port_actions = {} if len(self.pa_sink.ports.keys()) > 1: ports_menu = QMenu(i18n("Ports"), self.popup_menu) ports = self.pa_sink.ports for port in ports.keys(): action = QAction(in_unicode(ports[port]), self.popup_menu) self.port_actions[action]=port if port == self.pa_sink.active_port: action.setCheckable(True) action.setChecked(True) else: action.setChecked(False) action.setCheckable(False) ports_menu.addAction(action) self.popup_menu.addMenu(ports_menu)
def __createLanguageOptions(self): """Creates the language selection in the menubar. """ self.langGroup = QActionGroup(self) self.langGroup.setExclusive(True) self.langGroup.triggered['QAction*'].connect(self.languageChanged) for key, name in self.languages.iteritems(): action = QAction(self) action.setCheckable(True) action.setData(key) action.setText(name[0]) action.setStatusTip(name[1]) action.setActionGroup(self.langGroup) self.menuLanguage.addAction(action) if key == self.currentLanguage: action.setChecked(True)
def _create_action(self, action_name, icon_file, text, shortcuts): if action_name == "*separator*": action = QAction(self.window) action.setSeparator(True) else: if icon_file: action = QAction(QIcon(utils.resource_path(icon_file)), text, self.window) else: action = QAction(text, self.window) if shortcuts: sequences = [QKeySequence(s) for s in shortcuts] action.setShortcuts(sequences) if action_name.startswith("+"): action.setCheckable(True) if action_name.startswith("++"): action.setChecked(True) return action
def load_video_devices(self): settings = SIPSimpleSettings() action = QAction(u'System default', self.video_devices_group) action.setData(u'system_default') self.video_camera_menu.addAction(action) self.video_camera_menu.addSeparator() for device in SIPApplication.engine.video_devices: action = QAction(device, self.video_devices_group) action.setData(device) self.video_camera_menu.addAction(action) action = QAction(u'None', self.video_devices_group) action.setData(None) self.video_camera_menu.addAction(action) for action in self.video_devices_group.actions(): action.setCheckable(True) if settings.video.device == action.data(): action.setChecked(True)
def updateHeadersActions(self): # clean the current actions list: if self.header_column_count == self.header.count(): # column didn't change return self.header_column_count = self.header.count() for action in self.header_menu.actions(): self.removeAction(action) for col in xrange(self.header.count()): col_label = self.model().headerData(col, Qt.Horizontal).toString() action = QAction(col_label, self.header) action.setCheckable(True) action.setChecked(not self.header.isSectionHidden(col)) self.connect(action, SIGNAL("triggered()"), self.updateDisplayedColumns) self.header_menu.addAction(action)
def setGroupsMenu(self): self.groupsMenu.clear() addGroupAction = self.groupsMenu.addAction('Add group') addGroupAction.triggered.connect(self.addGroup) deleteGroupAction = self.groupsMenu.addAction('Delete group') deleteGroupAction.triggered.connect(self.showDeleteGroupDialog) showHostsInGroupsAction = self.groupsMenu.addAction('Show host list in groups') showHostsInGroupsAction.triggered.connect(self.changeHostListView) showHostsInGroupsAction.setCheckable(True) showHostsInGroupsAction.setChecked(self.showHostsInGroups) self.groupsMenu.addSeparator() for group, checked in self.groups.items(): action = QAction(group, self.groupsMenu) action.setCheckable(True) action.setChecked(checked) action.triggered.connect(self.groupsVisibilityChanged) self.groupsMenu.addAction(action)
def __createMenu(self): file_menu = self.menuBar().addMenu("&File") file_menu.addAction("Close", self.__quit) self.__view_menu = self.menuBar().addMenu("&View") self.__help_menu = self.menuBar().addMenu("&Help") """:type: QMenu""" """ @rtype: list of QAction """ advanced_toggle_action = QAction("Show Advanced Options", self) advanced_toggle_action.setObjectName("AdvancedSimulationOptions") advanced_toggle_action.setCheckable(True) advanced_toggle_action.setChecked(False) advanced_toggle_action.toggled.connect(self.toggleAdvancedMode) self.__view_menu.addAction(advanced_toggle_action) """ @rtype: list of QAction """ show_about = self.__help_menu.addAction("About") show_about.setMenuRole(QAction.ApplicationSpecificRole) show_about.triggered.connect(self.__showAboutMessage)
def populate_presets_menu(self, target_menu, checked_item, add_actions): effect_menu = QMenu(i18n("Presets"), target_menu) if add_actions: self.action_save_preset = QAction(i18n("Save"),effect_menu) effect_menu.addAction(self.action_save_preset) if not self.is_preset(): self.action_save_preset.setEnabled(False) self.action_save_as_preset = QAction(i18n("Save As..."),effect_menu) effect_menu.addAction(self.action_save_as_preset) effect_menu.addSeparator() for preset in LADSPAPresetLoader().presets(): action = QAction(preset["preset_name"],effect_menu) effect_menu.addAction(action) if checked_item == preset["preset_name"]: action.setCheckable(True) action.setChecked(True) action.setEnabled(False) target_menu.addMenu(effect_menu)
def contextMenuEvent(self, e): mdl = self.model() irow = self.rowAt(e.y()) icol = self.columnAt(e.x()) #print "Row:", self.rowAt(e.y()) cmenu = QMenu() m_dis = QAction("disabled", self) m_dis.setCheckable(True) act = mdl.isActive(irow) c = QApplication.clipboard() if not act: m_dis.setChecked(True) self.connect(m_dis, SIGNAL("toggled(bool)"), partial(self.disableElement, irow=irow)) if icol in [C_VAL_SP, C_VAL_RB]: pvs = mdl.data(self.indexAt(e.pos()), Qt.ToolTipRole).toString() cmenu.addAction("&Copy PV", partial(c.setText, pvs), "CTRL+C") cmenu.addAction(m_dis) cmenu.exec_(e.globalPos())
def setGroupsMenu(self): self.groupsMenu.clear() addGroupAction = self.groupsMenu.addAction('Add group') addGroupAction.triggered.connect(self.addGroup) deleteGroupAction = self.groupsMenu.addAction('Delete group') deleteGroupAction.triggered.connect(self.showDeleteGroupDialog) showHostsInGroupsAction = self.groupsMenu.addAction( 'Show host list in groups') showHostsInGroupsAction.triggered.connect(self.changeHostListView) showHostsInGroupsAction.setCheckable(True) showHostsInGroupsAction.setChecked(self.showHostsInGroups) self.groupsMenu.addSeparator() for group, checked in self.groups.items(): action = QAction(group, self.groupsMenu) action.setCheckable(True) action.setChecked(checked) action.triggered.connect(self.groupsVisibilityChanged) self.groupsMenu.addAction(action)
def setupLanguageMenu(self): self.languages = QDir(":/languages").entryList() if self.current_language is None: self.current_language = QLocale.system().name() # Retrieve Current Locale from the operating system. log.debug("Detected user's locale as %s" % self.current_language) for language in self.languages: translator = QTranslator() # Create a translator to translate Language Display Text. translator.load(":/languages/%s" % language) language_display_text = translator.translate("Translation", "Language Display Text") languageAction = QAction(self) languageAction.setCheckable(True) languageAction.setText(language_display_text) languageAction.setData(language) self.menuLanguage.addAction(languageAction) self.langActionGroup.addAction(languageAction) if self.current_language == str(language).strip("tr_").rstrip(".qm"): languageAction.setChecked(True)
def addEncoding(self): encmenu = QMenu(self) self.genc = QtGui.QActionGroup(self) action = QAction(self) action.setText(u'auto') action.encoding = None action.setCheckable(True) action.setChecked(True) self.genc.addAction(action) encmenu.addAction(action) for a, b in encodings: action = QAction(self) action.setText(a + '-*- ' + b) action.encoding = b action.setCheckable(True) self.genc.addAction(action) encmenu.addAction(action) self.view_Set_encoding_action.setMenu(encmenu) self.connect(self.genc, QtCore.SIGNAL('triggered(QAction*)'), self.onEncodingChg)
class Interpreter(MDockWidget): def __init__(self, mainWindow=None): MDockWidget.__init__(self, mainWindow) self.__mainWindow = mainWindow self.icon = QIcon(":interpreter.png") self.addAction(mainWindow) self.g_display() def g_display(self): self.setWidget(InterpreterView(self)) self.setWindowTitle(QApplication.translate("Interpreter", "Interpreter", None, QApplication.UnicodeUTF8)) def addAction(self, mainWindow): self.__action = QAction(self) self.__action.setCheckable(True) self.__action.setChecked(True) self.__action.setObjectName("actionCoreInformations") self.__action.setText(QApplication.translate("MainWindow", "DFF interpreter", None, QApplication.UnicodeUTF8)) mainWindow.menuWindow.addAction(self.__action) self.connect(self.__action, SIGNAL("triggered()"), self.changeVisibleInformations) def changeVisibleInformations(self): if not self.isVisible() : self.setVisible(True) self.__action.setChecked(True) else : self.setVisible(False) self.__action.setChecked(False)
class Test: def __init__(self, iface): # Save reference to the QGIS interface self.iface = iface self.tooltipRaster = TooltipRasterMapTool(self.iface) def initGui(self): # Create action that will start plugin configuration self.action = QAction( QIcon( os.path.dirname(os.path.realpath(__file__)) + "/icon_default.png"), "Tooltip for Raster Values", self.iface.mainWindow()) # connect the action to the run method self.action.triggered.connect(self.run) self.action.setCheckable(True) self.iface.mapCanvas().mapToolSet.connect(self.mapToolWasSet) # Add toolbar button to the Plugins toolbar self.iface.addToolBarIcon(self.action) # Add menu item to the Plugins menu self.iface.addPluginToMenu("&Tooltip for Raster Values", self.action) def unload(self): # Remove the plugin menu item and icon self.iface.removePluginMenu("&Tooltip for Raster Values", self.action) self.iface.removeToolBarIcon(self.action) # run method that performs all the real work def run(self, checked): if checked: self.iface.mapCanvas().setMapTool(self.tooltipRaster) else: self.iface.mapCanvas().unsetMapTool(self.tooltipRaster) def mapToolWasSet(self, newTool): if type(newTool) != TooltipRasterMapTool: self.action.setChecked(False)
def setup_toolbars(self): source_toolbar = self.addToolBar('SourceToolbar') self.user_interface.tbrActionToggleSourceView = QAction('C/C++', self) self.user_interface.tbrActionToggleSourceView.triggered.connect( self.toggle_source_view) self.user_interface.tbrActionToggleSourceView.setToolTip( "Toggle source code view") self.user_interface.tbrActionToggleSourceView.setCheckable(True) self.user_interface.tbrActionToggleSourceView.setChecked(True) source_toolbar.addAction(self.user_interface.tbrActionToggleSourceView) search_toolbar = self.addToolBar("SearchToolbar") search_toolbar.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea) self.ledSearchBox = QLineEdit() self.ledSearchBox.textChanged.connect(self.invalidate_search_criteria) self.ledSearchBox.keyPressEvent = self.search_box_key_pressed search_toolbar.addWidget(self.ledSearchBox) tbrActionPrevSearchMatch = QAction('<<', self) tbrActionPrevSearchMatch.triggered.connect( functools.partial(self.select_search_match, False)) tbrActionPrevSearchMatch.setToolTip("Go to previous search match") tbrActionNextSearchMatch = QAction('>>', self) tbrActionNextSearchMatch.triggered.connect( functools.partial(self.select_search_match, True)) tbrActionNextSearchMatch.setToolTip("Go to next search match") tbrActionIgnoreCase = QAction('Ignore Case', self) tbrActionIgnoreCase.setCheckable(True) tbrActionIgnoreCase.setChecked(True) tbrActionIgnoreCase.triggered.connect(self.set_search_case_sensitivity, tbrActionIgnoreCase.isChecked()) tbrActionIgnoreCase.setToolTip("Ignore case") tbrActionWrapSearch = QAction('Wrap Search', self) tbrActionWrapSearch.setCheckable(True) tbrActionWrapSearch.setChecked(True) tbrActionWrapSearch.triggered.connect(self.set_search_wrap, tbrActionWrapSearch.isChecked()) tbrActionWrapSearch.setToolTip("Wrap Search") tbrActionMatchWholeWord = QAction('Match Whole Word', self) tbrActionMatchWholeWord.setCheckable(True) tbrActionMatchWholeWord.setChecked(False) tbrActionMatchWholeWord.triggered.connect( self.set_match_whole_word, tbrActionMatchWholeWord.isChecked()) tbrActionMatchWholeWord.setToolTip("Match Whole Word") search_toolbar.addAction(tbrActionPrevSearchMatch) search_toolbar.addAction(tbrActionNextSearchMatch) search_toolbar.addAction(tbrActionIgnoreCase) search_toolbar.addAction(tbrActionMatchWholeWord) search_toolbar.addAction(tbrActionWrapSearch)
class MiTraceView(QWidget): def __init__(self, do, parent): QWidget.__init__(self, parent) self.ui = Ui_MiTraceView() self.ui.setupUi(self) self.__do = do self.ui.commandEdit.lineEdit().returnPressed.connect( self.executeMiCommand) self.__do.gdb_connector.commandExecuted.connect(self.appendCommand) self.__do.gdb_connector.reader.asyncRecordReceived.connect( self.appendAsync) self.__timeAction = QAction(Icons.time, "Show Elapsed Time", self) self.__timeAction.setCheckable(True) self.__timeAction.setChecked(True) parent.titleBarWidget().addAction(self.__timeAction) parent.addClearAction() parent.clearRequested.connect(self.ui.traceView.clear) def appendCommand(self, cmd, rec, time): timestr = "[<i>%.3f</i>] " % time if self.__timeAction.isChecked( ) else "" self.ui.traceView.append("%s<b>%s</b>" % (timestr, cmd)) color = 'color="#ff3333"' if rec.class_ == GdbOutput.ERROR else "" self.ui.traceView.append("<font %s>%s</font>" % (color, rec.raw)) def appendAsync(self, rec): self.ui.traceView.append('<font color="#777777">%s</font>' % rec.raw) def executeMiCommand(self): cmd = str(self.ui.commandEdit.lineEdit().text()) self.ui.commandEdit.lineEdit().setText("") self.__do.gdb_connector.execute(cmd)
def addAction(self, action): """ Adds the inputed action to this widget's action group. This will auto-\ create a new group if no group is already defined. :param action | <QAction> || <str> :return <QAction> """ if (not isinstance(action, QAction)): action_name = str(action) action = QAction(action_name, self) action.setObjectName(action_name) action.setCheckable(True) if (not self._actionGroup): self._actionGroup = QActionGroup(self) action.setChecked(True) self._actionGroup.addAction(action) self.reset() return action
def loadPlugins(self): sys.path.append(os.curdir + os.sep + "plugins") plugins = QActionGroup(self) plugins.setExclusive(True) simple = SimpleInterpreter() action = QAction(simple.GetName(), self) plugins.addAction(action) action.setCheckable(True) action.setChecked(True) self.interpreterPlugins[action] = simple self.ui.menuPlugins.addAction(action) QtCore.QObject.connect(action, SIGNAL("triggered()"), self.ChangeInterpreter) for s in os.listdir("plugins"): # TODO: check all errors if s.endswith(".py"): plugin = __import__(s[:-3]) if "pluginMain" in dir(plugin): pluginClass = plugin.pluginMain() name = pluginClass.GetName() type = pluginClass.GetType() if type != "interpreter": continue action = QAction(name, self) action.setCheckable(True) QtCore.QObject.connect(action, SIGNAL("triggered()"), self.ChangeInterpreter) plugins.addAction(action) self.ui.menuPlugins.addAction(action) self.interpreterPlugins[action] = pluginClass() # TODO: load from .ini file if name == "!!FibreChannel": action.setChecked(True) self.project.method.interpreter = self.interpreterPlugins[ action] else: print("pluginMain not found in " + s)
def load_audio_devices(self): settings = SIPSimpleSettings() action = QAction(u'System default', self.output_devices_group) action.setData(u'system_default') self.output_device_menu.addAction(action) self.output_device_menu.addSeparator() for device in SIPApplication.engine.output_devices: action = QAction(device, self.output_devices_group) action.setData(device) self.output_device_menu.addAction(action) action = QAction(u'None', self.output_devices_group) action.setData(None) self.output_device_menu.addAction(action) for action in self.output_devices_group.actions(): action.setCheckable(True) if settings.audio.output_device == action.data(): action.setChecked(True) action = QAction(u'System default', self.input_devices_group) action.setData(u'system_default') self.input_device_menu.addAction(action) self.input_device_menu.addSeparator() for device in SIPApplication.engine.input_devices: action = QAction(device, self.input_devices_group) action.setData(device) self.input_device_menu.addAction(action) action = QAction(u'None', self.input_devices_group) action.setData(None) self.input_device_menu.addAction(action) for action in self.input_devices_group.actions(): action.setCheckable(True) if settings.audio.input_device == action.data(): action.setChecked(True) action = QAction(u'System default', self.alert_devices_group) action.setData(u'system_default') self.alert_device_menu.addAction(action) self.alert_device_menu.addSeparator() for device in SIPApplication.engine.output_devices: action = QAction(device, self.alert_devices_group) action.setData(device) self.alert_device_menu.addAction(action) action = QAction(u'None', self.alert_devices_group) action.setData(None) self.alert_device_menu.addAction(action) for action in self.alert_devices_group.actions(): action.setCheckable(True) if settings.audio.alert_device == action.data(): action.setChecked(True)
def __init__(self, quarterwidget): QObject.__init__(self, quarterwidget) #QObject.__init__(quarterwidget) self._quarterwidget = quarterwidget self._rendermanager = self._quarterwidget.getSoRenderManager() self.contextmenu = QMenu() self.functionsmenu = QMenu("Functions") self.rendermenu = QMenu("Render Mode") self.stereomenu = QMenu("Stereo Mode") self.transparencymenu = QMenu("Transparency Type") self.functionsgroup = QActionGroup(self) self.stereomodegroup = QActionGroup(self) self.rendermodegroup = QActionGroup(self) self.transparencytypegroup = QActionGroup(self) self.rendermodes = [] self.rendermodes.append((SoRenderManager.AS_IS, "as is")) self.rendermodes.append((SoRenderManager.WIREFRAME, "wireframe")) self.rendermodes.append( (SoRenderManager.WIREFRAME_OVERLAY, "wireframe overlay")) self.rendermodes.append((SoRenderManager.POINTS, "points")) self.rendermodes.append((SoRenderManager.HIDDEN_LINE, "hidden line")) self.rendermodes.append((SoRenderManager.BOUNDING_BOX, "bounding box")) self.stereomodes = [] self.stereomodes.append((SoRenderManager.MONO, "mono")) self.stereomodes.append((SoRenderManager.ANAGLYPH, "anaglyph")) self.stereomodes.append((SoRenderManager.QUAD_BUFFER, "quad buffer")) self.stereomodes.append( (SoRenderManager.INTERLEAVED_ROWS, "interleaved rows")) self.stereomodes.append( (SoRenderManager.INTERLEAVED_COLUMNS, "interleaved columns")) self.transparencytypes = [] self.transparencytypes.append((SoGLRenderAction.NONE, "none")) self.transparencytypes.append( (SoGLRenderAction.SCREEN_DOOR, "screen door")) self.transparencytypes.append((SoGLRenderAction.ADD, "add")) self.transparencytypes.append( (SoGLRenderAction.DELAYED_ADD, "delayed add")) self.transparencytypes.append( (SoGLRenderAction.SORTED_OBJECT_ADD, "sorted object add")) self.transparencytypes.append((SoGLRenderAction.BLEND, "blend")) self.transparencytypes.append( (SoGLRenderAction.DELAYED_BLEND, "delayed blend")) self.transparencytypes.append( (SoGLRenderAction.SORTED_OBJECT_BLEND, "sorted object blend")) self.transparencytypes.append( (SoGLRenderAction.SORTED_OBJECT_SORTED_TRIANGLE_ADD, "sorted object sorted triangle add")) self.transparencytypes.append( (SoGLRenderAction.SORTED_OBJECT_SORTED_TRIANGLE_BLEND, "sorted object sorted triangle blend")) self.transparencytypes.append( (SoGLRenderAction.SORTED_LAYERS_BLEND, "sorted layers blend")) self.rendermodeactions = [] for first, second in self.rendermodes: action = QAction(second, self) action.setCheckable(True) action.setChecked(self._rendermanager.getRenderMode() == first) action.setData(QVariant(first)) self.rendermodeactions.append(action) self.rendermodegroup.addAction(action) self.rendermenu.addAction(action) self.stereomodeactions = [] for first, second in self.stereomodes: action = QAction(second, self) action.setCheckable(True) action.setChecked(self._rendermanager.getStereoMode() == first) action.setData(QVariant(first)) self.stereomodeactions.append(action) self.stereomodegroup.addAction(action) self.stereomenu.addAction(action) self.transparencytypeactions = [] for first, second in self.transparencytypes: action = QAction(second, self) action.setCheckable(True) action.setChecked(self._rendermanager.getGLRenderAction(). getTransparencyType() == first) action.setData(QVariant(first)) self.transparencytypeactions.append(action) self.transparencytypegroup.addAction(action) self.transparencymenu.addAction(action) viewall = QAction("View All", self) seek = QAction("Seek", self) self.functionsmenu.addAction(viewall) self.functionsmenu.addAction(seek) self.connect(seek, QtCore.SIGNAL("triggered(bool)"), self.seek) self.connect(viewall, QtCore.SIGNAL("triggered(bool)"), self.viewAll) self.connect(self.rendermodegroup, QtCore.SIGNAL("triggered(QAction *)"), self.changeRenderMode) self.connect(self.stereomodegroup, QtCore.SIGNAL("triggered(QAction *)"), self.changeStereoMode) self.connect(self.transparencytypegroup, QtCore.SIGNAL("triggered(QAction *)"), self.changeTransparencyType) self.contextmenu.addMenu(self.functionsmenu) self.contextmenu.addMenu(self.rendermenu) self.contextmenu.addMenu(self.stereomenu) self.contextmenu.addMenu(self.transparencymenu)
def _setupUi(self): # self.stop = QToolButton() # self.stop.setIcon(QIcon('gui/icons/tools_wizard.png')) # self.stop.setToolTip('Enable or disable the appearance of the contextMenu') layout = QVBoxLayout(self) self.smoothButton = QToolButton() #self.smoothButton.setToolButtonStyle(2) self.smoothButton.setPopupMode(2) self.smoothButton.setToolTip("Smooth the visualized data") #self.smoothButton.setText("Smooth...") self.smoothButton.setIcon( QIcon(os.path.normcase('gui/icons/smooth.png'))) self.smoothMenu = QMenu() self.connect(self.smoothMenu, SIGNAL('triggered(QAction*)'), self.smooth) self.smoothButton.setMenu(self.smoothMenu) self.pw.plotItem.toolBar.addWidget(self.smoothButton) self.flipButton = QToolButton() #self.flipButton.setToolButtonStyle(2) self.flipButton.setIcon(QIcon(os.path.normcase('gui/icons/flip.png'))) self.flipButton.setToolTip("Flip the visualized data") #self.flipButton.setText("Flip...") self.flipButton.setPopupMode(2) self.flipMenu = QMenu() self.connect(self.flipMenu, SIGNAL('triggered(QAction*)'), self.flip) self.flipButton.setMenu(self.flipMenu) self.pw.plotItem.toolBar.addWidget(self.flipButton) self.annotButton = QToolButton() #self.annotButton.setToolButtonStyle(2) self.annotButton.setPopupMode(2) #self.annotButton.setText("&Annotate...") self.annotButton.setIcon( QIcon(os.path.normcase('gui/icons/attach.png'))) self.annotMenu = QMenu() self.annotMenu.addAction("&Add Annotation") self.annotMenu.addAction("&Remove last Annotation") self.annotMenu.addAction("&Remove All Annotation") self.annotButton.setMenu(self.annotMenu) self.connect(self.annotMenu.actions()[0], SIGNAL("triggered()"), self.annotate) self.connect(self.annotMenu.actions()[1], SIGNAL("triggered()"), self.removeLastAnnot) self.connect(self.annotMenu.actions()[2], SIGNAL("triggered()"), self.removeAllAnnot) self.pw.plotItem.toolBar.addWidget(self.annotButton) self.addPlotButton = QToolButton() #self.addPlotButton.setToolButtonStyle(2) self.addPlotButton.setText("Add...") self.addPlotButton.setIcon( QIcon(os.path.normcase('gui/icons/list_add.png'))) self.addPlotButton.setToolTip("Add a new plot to the current figure") #self.addPlotButton.setText('&Add Plot') self.pw.plotItem.toolBar.addWidget(self.addPlotButton) self.showSpectra = QToolButton() self.showSpectra.setPopupMode(2) #instant popup #self.showSpectra.setToolButtonStyle(2) self.showSpectra.setIcon( QIcon(os.path.normcase('gui/icons/file_export.png'))) #self.showSpectra.setText('&Show /hide...') self.showSpectra.setToolTip('Show/hide ...') self.showMenu = QMenu() self.showTextLabels = QAction("&Show Labels", self.showMenu) self.showTextLabels.setCheckable(True) self.showTextLabels.setChecked(True) self.showMenu.addAction(self.showTextLabels) self.connect(self.showMenu.actions()[0], SIGNAL('toggled(bool)'), self.setTextLabelsVisibility) showSpectrum = QAction("&Merged Spectrum", self.showMenu) showSpectrum.setCheckable(True) if self.flags == 'chroma' or self.flags == 'spectra': showSpectrum.setEnabled(False) self.showMenu.addAction(showSpectrum) self.connect(self.showMenu.actions()[1], SIGNAL('toggled(bool)'), self.drawSpectraRequested) showNonXCMSPeak = QAction("&Show Non XCMS Peak", self.showMenu) showNonXCMSPeak.setCheckable(True) if self.flags == 'spectra': showNonXCMSPeak.setEnabled(False) self.showMenu.addAction(showNonXCMSPeak) self.connect(self.showMenu.actions()[2], SIGNAL('toggled(bool)'), self.setPixmapVisibility) showDataPoints = QAction("&Show DataPoints", self.showMenu) showDataPoints.setCheckable(True) showDataPoints.setChecked(False) self.showMenu.addAction(showDataPoints) self.connect(self.showMenu.actions()[3], SIGNAL('toggled(bool)'), self.setDataPointsVisibility) self.showSpectra.setMenu(self.showMenu) self.pw.plotItem.toolBar.addWidget(self.showSpectra) self.saveToPng = QToolButton() self.saveToPng.setIcon( QIcon(os.path.normcase('gui/icons/thumbnail.png'))) #self.saveToPng.setToolButtonStyle(2) #self.saveToPng.setText("Save to Png...") self.pw.plotItem.toolBar.addWidget(self.saveToPng) self.connect(self.saveToPng, SIGNAL('clicked()'), self.pw.writeImage) #add bar plot even if we are plotting chroma #cause we can find non xcms peaks self.barPlot = BarPlot(scene=self.pw.sceneObj) #self.barPlot.rotate(-90.) if self.flags == 'peak': self.barPlot.setPeakGroup(self.data) #TODO modify to get this close to us #on the left part xpos = self.barPlot.scene().width() * 3.5 #-bwidth; ypos = self.barPlot.scene().height() * 1.1 self.barPlot.setPos(xpos, ypos) self.barPlot.setZValue(1000) layout.addWidget(self.pw) layout.addWidget(self.pw.plotItem.toolBar)
def __init__(self, pathToLogs, trayIcon, backGroundColor): QtGui.QMainWindow.__init__(self) self.cache = Cache() if backGroundColor: self.setStyleSheet("QWidget { background-color: %s; }" % backGroundColor) uic.loadUi(resourcePath('vi/ui/MainWindow.ui'), self) self.setWindowTitle( "Spyglass " + vi.version.VERSION + "{dev}".format(dev="-SNAPSHOT" if vi.version.SNAPSHOT else "")) self.taskbarIconQuiescent = QtGui.QIcon(resourcePath("vi/ui/res/logo_small.png")) self.taskbarIconWorking = QtGui.QIcon(resourcePath("vi/ui/res/logo_small_green.png")) self.setWindowIcon(self.taskbarIconQuiescent) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.pathToLogs = pathToLogs self.mapTimer = QtCore.QTimer(self) self.connect(self.mapTimer, SIGNAL("timeout()"), self.updateMapView) self.clipboardTimer = QtCore.QTimer(self) self.oldClipboardContent = "" self.trayIcon = trayIcon self.trayIcon.activated.connect(self.systemTrayActivated) self.clipboard = QtGui.QApplication.clipboard() self.clipboard.clear(mode=self.clipboard.Clipboard) self.alarmDistance = 0 self.lastStatisticsUpdate = 0 self.chatEntries = [] self.frameButton.setVisible(False) self.scanIntelForKosRequestsEnabled = True self.initialMapPosition = None self.mapPositionsDict = {} self.autoRescanIntelEnabled = self.cache.getFromCache("changeAutoRescanIntel") # Load user's toon names self.knownPlayerNames = self.cache.getFromCache("known_player_names") if self.knownPlayerNames: self.knownPlayerNames = set(self.knownPlayerNames.split(",")) else: self.knownPlayerNames = set() diagText = "Spyglass scans EVE system logs and remembers your characters as they change systems.\n\nSome features (clipboard KOS checking, alarms, etc.) may not work until your character(s) have been registered. Change systems, with each character you want to monitor, while Spyglass is running to remedy this." QMessageBox.warning(None, "Known Characters not Found", diagText, "Ok") # Set up user's intel rooms roomnames = self.cache.getFromCache("room_names") if roomnames: roomnames = roomnames.split(",") else: roomnames = (u"TheCitadel", u"North Provi Intel", u"4THINTEL") self.cache.putIntoCache("room_names", u",".join(roomnames), 60 * 60 * 24 * 365 * 5) self.roomnames = roomnames # Disable the sound UI if sound is not available if not SoundManager().soundAvailable: self.changeSound(disable=True) else: self.changeSound() # Set up Transparency menu - fill in opacity values and make connections self.opacityGroup = QActionGroup(self.menu) for i in (100, 80, 60, 40, 20): action = QAction("Opacity {0}%".format(i), None, checkable=True) if i == 100: action.setChecked(True) action.opacity = i / 100.0 self.connect(action, SIGNAL("triggered()"), self.changeOpacity) self.opacityGroup.addAction(action) self.menuTransparency.addAction(action) # Set up Theme menu - fill in list of themes and add connections self.themeGroup = QActionGroup(self.menu) styles = Styles() for theme in styles.getStyles(): action = QAction(theme, None, checkable=True) action.theme = theme if action.theme == "default": action.setChecked(True) logging.info("Adding theme {}".format(theme)) self.connect(action, SIGNAL("triggered()"), self.changeTheme) self.themeGroup.addAction(action) self.menuTheme.addAction(action) styles = None # # Platform specific UI resizing - we size items in the resource files to look correct on the mac, # then resize other platforms as needed # if sys.platform.startswith("win32") or sys.platform.startswith("cygwin"): font = self.statisticsButton.font() font.setPointSize(8) self.statisticsButton.setFont(font) self.jumpbridgesButton.setFont(font) elif sys.platform.startswith("linux"): pass self.wireUpUIConnections() self.recallCachedSettings() self.setupThreads() self.setupMap(True) initialTheme = self.cache.getFromCache("theme") if initialTheme: self.changeTheme(initialTheme)
class SplitterResizer(QObject): """An object able to control the size of a widget in a QSpliter instance. """ def __init__(self, parent=None): QObject.__init__(self, parent) self.__splitter = None self.__widget = None self.__animationEnabled = True self.__size = -1 self.__expanded = False self.__animation = QPropertyAnimation(self, b"size_", self) self.__action = QAction("toogle-expanded", self, checkable=True) self.__action.triggered[bool].connect(self.setExpanded) def setSize(self, size): """Set the size of the controlled widget (either width or height depending on the orientation). """ if self.__size != size: self.__size = size self.__update() def size(self): """Return the size of the widget in the splitter (either height of width) depending on the splitter orientation. """ if self.__splitter and self.__widget: index = self.__splitter.indexOf(self.__widget) sizes = self.__splitter.sizes() return sizes[index] else: return -1 size_ = Property(int, fget=size, fset=setSize) def setAnimationEnabled(self, enable): """Enable/disable animation. """ self.__animation.setDuration(0 if enable else 200) def animationEnabled(self): return self.__animation.duration() == 0 def setSplitterAndWidget(self, splitter, widget): """Set the QSplitter and QWidget instance the resizer should control. .. note:: the widget must be in the splitter. """ if splitter and widget and not splitter.indexOf(widget) > 0: raise ValueError("Widget must be in a spliter.") if self.__widget: self.__widget.removeEventFilter() self.__splitter = splitter self.__widget = widget if widget: widget.installEventFilter(self) self.__update() def toogleExpandedAction(self): """Return a QAction that can be used to toggle expanded state. """ return self.__action def open(self): """Open the controlled widget (expand it to it sizeHint). """ self.__expanded = True self.__action.setChecked(True) if not (self.__splitter and self.__widget): return size = self.size() if size > 0: # Already has non zero size. return hint = self.__widget.sizeHint() if self.__splitter.orientation() == Qt.Vertical: end = hint.height() else: end = hint.width() self.__animation.setStartValue(0) self.__animation.setEndValue(end) self.__animation.start() def close(self): """Close the controlled widget (shrink to size 0). """ self.__expanded = False self.__action.setChecked(False) if not (self.__splitter and self.__widget): return self.__animation.setStartValue(self.size()) self.__animation.setEndValue(0) self.__animation.start() def setExpanded(self, expanded): """Set the expanded state. """ if self.__expanded != expanded: if expanded: self.open() else: self.close() def expanded(self): """Return the expanded state. """ return self.__expanded def __update(self): """Update the splitter sizes. """ if self.__splitter and self.__widget: splitter = self.__splitter index = splitter.indexOf(self.__widget) sizes = splitter.sizes() current = sizes[index] diff = current - self.__size sizes[index] = self.__size sizes[index - 1] = sizes[index - 1] + diff self.__splitter.setSizes(sizes) def eventFilter(self, obj, event): if event.type() == QEvent.Resize: if self.__splitter.orientation() == Qt.Vertical: size = event.size().height() else: size = event.size().width() if self.__expanded and size == 0: self.__action.setChecked(False) self.__expanded = False elif not self.__expanded and size > 0: self.__action.setChecked(True) self.__expanded = True return QObject.eventFilter(self, obj, event)
class TSToolBar(NavigationToolbar): RangeDrawEndSignal = pyqtSignal(Rectangle) BreakLineDrawEndSignal = pyqtSignal(Line2D) def __init__(self, canvas, parent, coordinates=True): # self.interaction = TSInteraction(canvas.figure) # range selector self.rect = None self.rects = [] self.pressv = None self.prev = None self.press_flag = False self.facecolor = 'b' self.alpha = 0.8 super(TSToolBar, self).__init__(canvas, parent, coordinates=True) def _init_toolbar(self): super(TSToolBar, self)._init_toolbar() self.epBreakAction = QAction(QIcon(":/TSResource/images/ep-break.png"), "Equipment break", self) self.eqBreakAction = QAction(QIcon(":/TSResource/images/eq-break.png"), "Earthquake break", self) self.eqExpBreakAction = QAction( QIcon(":/TSResource/images/eq-exp.png"), "Earthquake exponential break", self) self.eqLogBreakAction = QAction( QIcon(":/TSResource/images/eq-log.png"), "Equipment logarithic break", self) self.errorbarAction = QAction( QIcon(":/TSResource/images/errorbar.png"), "Errorbar", self) # self.errorbarAction.setCheckable(True) # self.tsToolBar.addAction(self.errorbarAction) self.actions = [ None, self.epBreakAction, self.eqBreakAction, self.eqExpBreakAction, self.eqLogBreakAction, None, self.errorbarAction ] # self.tsToolBar.addSeparator() for action in self.actions: if action is None: self.addSeparator() else: self.addAction(action) action.setCheckable(True) self.errorbarAction.triggered.connect(self._click_errorbarAction) self.epBreakAction.triggered.connect(self._click_epBreakAction) self.eqBreakAction.triggered.connect(self._click_eqBreakAction) self.eqExpBreakAction.triggered.connect(self._click_eqExpBreakAction) self.eqLogBreakAction.triggered.connect(self._click_eqLogBreakAction) def _update_buttons_checked(self): super(TSToolBar, self)._update_buttons_checked() self.epBreakAction.setChecked(self._active == 'EPBREAK') self.eqBreakAction.setChecked(self._active == 'EQBREAK') self.eqExpBreakAction.setChecked(self._active == 'EQEXPBREAK') self.eqLogBreakAction.setChecked(self._active == 'EQLOGBREAK') def disconnect_events(self): if self._idPress is not None: self._idPress = self.canvas.mpl_disconnect(self._idPress) self.mode = '' if self._idRelease is not None: self._idRelease = self.canvas.mpl_disconnect(self._idRelease) self.mode = '' def _click_epBreakAction(self, flag): if len(self.canvas.figure.get_axes()) != 0: self._active = None if self._active == 'EPBREAK' else 'EPBREAK' if self._idPress: self._idPress = self.canvas.mpl_disconnect(self._idPress) self._idDrag = self.canvas.mpl_disconnect(self._idDrag) if self._active: self._idPress = self.canvas.mpl_connect( 'button_press_event', self.break_press) self._idDrag = self.canvas.mpl_connect('motion_notify_event', self.cursor_motion) self.color = 'b' self.mode = 'epbreak' self.canvas.widgetlock(self) else: self.canvas.widgetlock.release(self) self._update_buttons_checked() def _click_eqBreakAction(self, flag): if len(self.canvas.figure.get_axes()) != 0: self._active = None if self._active == 'EQBREAK' else 'EQBREAK' if self._idPress: self._idPress = self.canvas.mpl_disconnect(self._idPress) self._idDrag = self.canvas.mpl_disconnect(self._idDrag) if self._active: self._idPress = self.canvas.mpl_connect( 'button_press_event', self.break_press) self._idDrag = self.canvas.mpl_connect('motion_notify_event', self.cursor_motion) self.color = 'r' self.mode = 'eqbreak' self.canvas.widgetlock(self) else: self.canvas.widgetlock.release(self) self._update_buttons_checked() def _click_eqExpBreakAction(self, flag): if len(self.canvas.figure.get_axes()) != 0: self._active = None if self._active == 'EQEXPBREAK' else 'EQEXPBREAK' if self._idPress: self._idPress = self.canvas.mpl_disconnect(self._idPress) if self._idDrag: self._idDrag = self.canvas.mpl_disconnect(self._idDrag) if self._idRelease: self._idRelease = self.canvas.mpl_disconnect(self._idRelease) if self._active: self._idPress = self.canvas.mpl_connect( 'button_press_event', self.range_on_press) self._idDrag = self.canvas.mpl_connect('motion_notify_event', self.range_on_move) self._idRelease = self.canvas.mpl_connect( 'button_release_event', self.range_on_release) self.mode = 'eqexpbreak' self.color = 'b' self.canvas.widgetlock(self) else: self.canvas.widgetlock.release(self) self._update_buttons_checked() def _click_eqLogBreakAction(self, flag): if len(self.canvas.figure.get_axes()) != 0: self._active = None if self._active == 'EQLOGBREAK' else 'EQLOGBREAK' if self._idPress: self._idPress = self.canvas.mpl_disconnect(self._idPress) if self._idDrag: self._idDrag = self.canvas.mpl_disconnect(self._idDrag) if self._idRelease: self._idRelease = self.canvas.mpl_disconnect(self._idRelease) if self._active: self._idPress = self.canvas.mpl_connect( 'button_press_event', self.range_on_press) self._idDrag = self.canvas.mpl_connect('motion_notify_event', self.range_on_move) self._idRelease = self.canvas.mpl_connect( 'button_release_event', self.range_on_release) self.mode = 'eqlogbreak' self.color = 'r' self.canvas.widgetlock(self) else: self.canvas.widgetlock.release(self) self._update_buttons_checked() def _click_errorbarAction(self, flag): figure = self.canvas.figure for ax in figure.get_axes(): errors = ax.lines for c in ax.collections: c.set_visible(flag) errors[0].set_visible(flag) errors[1].set_visible(flag) self.canvas.draw() def range_on_press(self, event): self.press_flag = True self.pressv = event.xdata trans = blended_transform_factory(event.inaxes.transData, event.inaxes.transAxes) w, h = 0, 1 self.rect = Rectangle((0, 0), w, h, transform=trans, visible=False, facecolor=self.color, edgecolor=self.color, alpha=self.alpha) event.inaxes.add_patch(self.rect) event.inaxes.figure.canvas.draw_idle() def range_on_move(self, event): ax = event.inaxes if ax not in self.canvas.figure.get_axes(): if self.cursor_line: self.cursor_line.remove() self.cursor_line = None self.canvas.figure.canvas.draw_idle() return if self.press_flag: minv, maxv = sorted((event.xdata, self.pressv)) self.rect.set_x(minv) self.rect.set_width(maxv - minv) self.rect.set_visible(True) else: self.cursor_motion(event) ax.figure.canvas.draw_idle() def range_on_release(self, event): self.press_flag = False if self.rect: self.RangeDrawEndSignal.emit(self.rect) def break_press(self, event): ax = event.inaxes line = ax.axvline(event.xdata, color=self.color) # self.cursor_line.remove() # self.cursor_line = None # self.canvas.draw() self.BreakLineDrawEndSignal.emit(line)
class Plugin: """The QGIS interface implementation for the InaSAFE plugin. This class acts as the 'glue' between QGIS and our custom logic. It creates a toolbar and menubar entry and launches the InaSAFE user interface if these are activated. """ def __init__(self, iface): """Class constructor. On instantiation, the plugin instance will be assigned a copy of the QGIS iface object which will allow this plugin to access and manipulate the running QGIS instance that spawned it. :param iface:Quantum GIS iface instance. This instance is automatically passed to the plugin by QGIS when it loads the plugin. :type iface: QGisAppInterface """ # Save reference to the QGIS interface self.iface = iface self.translator = None self.toolbar = None self.actions = [] # list of all QActions we create for InaSAFE self.setup_i18n() #print self.tr('InaSAFE') custom_logging.setup_logger() # For enable/disable the keyword editor icon self.iface.currentLayerChanged.connect(self.layer_changed) #noinspection PyArgumentList def setup_i18n(self, preferred_locale=None): """Setup internationalisation for the plugin. See if QGIS wants to override the system locale and then see if we can get a valid translation file for whatever locale is effectively being used. :param preferred_locale: If set will override any other way of determining locale. :type preferred_locale: str, None :raises: TranslationLoadException """ myOverrideFlag = QSettings().value('locale/overrideFlag', False) if preferred_locale is not None: myLocaleName = preferred_locale elif myOverrideFlag: myLocaleName = QSettings().value('locale/userLocale', '') else: myLocaleName = QLocale.system().name() # NOTES: we split the locale name because we need the first two # character i.e. 'id', 'af, etc myLocaleName = str(myLocaleName).split('_')[0] # Also set the system locale to the user overridden local # so that the inasafe library functions gettext will work # .. see:: :py:func:`common.utilities` os.environ['LANG'] = str(myLocaleName) LOGGER.debug('%s %s %s %s' % (preferred_locale, myOverrideFlag, QLocale.system().name(), os.environ['LANG'])) myRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) myTranslationPath = os.path.join( myRoot, 'safe_qgis', 'i18n', 'inasafe_' + str(myLocaleName) + '.qm') if os.path.exists(myTranslationPath): self.translator = QTranslator() myResult = self.translator.load(myTranslationPath) if not myResult: myMessage = 'Failed to load translation for %s' % myLocaleName raise TranslationLoadError(myMessage) # noinspection PyTypeChecker QCoreApplication.installTranslator(self.translator) LOGGER.debug('%s %s' % (myTranslationPath, os.path.exists(myTranslationPath))) def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList return QCoreApplication.translate('Plugin', message) def add_action(self, action, add_to_toolbar=True): """Add a toolbar icon to the InaSAFE toolbar. :param action: The action that should be added to the toolbar. :type action: QAction :param add_to_toolbar: Flag indicating whether the action should also be added to the InaSAFE toolbar. Defaults to True. :type add_to_toolbar: bool """ # store in the class list of actions for easy plugin unloading self.actions.append(action) self.iface.addPluginToMenu(self.tr('InaSAFE'), action) if add_to_toolbar: self.toolbar.addAction(action) #noinspection PyCallByClass def initGui(self): """Gui initialisation procedure (for QGIS plugin api). .. note:: Don't change the name of this method from initGui! This method is called by QGIS and should be used to set up any graphical user interface elements that should appear in QGIS by default (i.e. before the user performs any explicit action with the plugin). """ self.toolbar = self.iface.addToolBar('InaSAFE') self.toolbar.setObjectName('InaSAFEToolBar') # Import dock here as it needs to be imported AFTER i18n is set up from safe_qgis.widgets.dock import Dock self.dockWidget = None #-------------------------------------- # Create action for plugin dockable window (show/hide) #-------------------------------------- # pylint: disable=W0201 self.actionDock = QAction(QIcon(':/plugins/inasafe/icon.svg'), self.tr('Toggle InaSAFE Dock'), self.iface.mainWindow()) self.actionDock.setObjectName('InaSAFEDockToggle') self.actionDock.setStatusTip(self.tr('Show/hide InaSAFE dock widget')) self.actionDock.setWhatsThis(self.tr('Show/hide InaSAFE dock widget')) self.actionDock.setCheckable(True) self.actionDock.setChecked(True) self.actionDock.triggered.connect(self.toggle_dock_visibility) self.add_action(self.actionDock) #-------------------------------------- # Create action for keywords editor #-------------------------------------- self.actionKeywordsDialog = QAction( QIcon(':/plugins/inasafe/show-keyword-editor.svg'), self.tr('InaSAFE Keyword Editor'), self.iface.mainWindow()) self.actionKeywordsDialog.setStatusTip( self.tr('Open InaSAFE keywords editor')) self.actionKeywordsDialog.setWhatsThis( self.tr('Open InaSAFE keywords editor')) self.actionKeywordsDialog.setEnabled(False) self.actionKeywordsDialog.triggered.connect(self.show_keywords_editor) self.add_action(self.actionKeywordsDialog) #-------------------------------------- # Create action for reset icon #-------------------------------------- self.actionResetDock = QAction( QIcon(':/plugins/inasafe/reset-dock.svg'), self.tr('Reset Dock'), self.iface.mainWindow()) self.actionResetDock.setStatusTip(self.tr('Reset the InaSAFE Dock')) self.actionResetDock.setWhatsThis(self.tr('Reset the InaSAFE Dock')) self.actionResetDock.triggered.connect(self.reset_dock) self.add_action(self.actionResetDock) #-------------------------------------- # Create action for options dialog #-------------------------------------- self.actionOptions = QAction( QIcon(':/plugins/inasafe/configure-inasafe.svg'), self.tr('InaSAFE Options'), self.iface.mainWindow()) self.actionOptions.setStatusTip(self.tr('Open InaSAFE options dialog')) self.actionOptions.setWhatsThis(self.tr('Open InaSAFE options dialog')) self.actionOptions.triggered.connect(self.show_options) self.add_action(self.actionOptions) #-------------------------------------- # Create action for impact functions doc dialog #-------------------------------------- self.actionFunctionBrowser = QAction( QIcon(':/plugins/inasafe/show-impact-functions.svg'), self.tr('InaSAFE Impact Functions Browser'), self.iface.mainWindow()) self.actionFunctionBrowser.setStatusTip( self.tr('Open InaSAFE Impact Functions Browser')) self.actionFunctionBrowser.setWhatsThis( self.tr('Open InaSAFE Impact Functions Browser')) self.actionFunctionBrowser.triggered.connect( self.show_function_browser) self.add_action(self.actionFunctionBrowser) # Short cut for Open Impact Functions Doc self.keyAction = QAction("Test Plugin", self.iface.mainWindow()) self.iface.registerMainWindowAction(self.keyAction, "F7") self.keyAction.triggered.connect(self.shortcut_f7) #--------------------------------------- # Create action for minimum needs dialog #--------------------------------------- self.actionMinimumNeeds = QAction( QIcon(':/plugins/inasafe/show-minimum-needs.svg'), self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow()) self.actionMinimumNeeds.setStatusTip( self.tr('Open InaSAFE minimum needs tool')) self.actionMinimumNeeds.setWhatsThis( self.tr('Open InaSAFE minimum needs tool')) self.actionMinimumNeeds.triggered.connect(self.show_minimum_needs) self.add_action(self.actionMinimumNeeds) #--------------------------------------- # Create action for converter dialog #--------------------------------------- self.actionConverter = QAction( QIcon(':/plugins/inasafe/show-converter-tool.svg'), self.tr('InaSAFE Converter'), self.iface.mainWindow()) self.actionConverter.setStatusTip(self.tr('Open InaSAFE Converter')) self.actionConverter.setWhatsThis(self.tr('Open InaSAFE Converter')) self.actionConverter.triggered.connect(self.show_shakemap_importer) self.add_action(self.actionConverter) #--------------------------------------- # Create action for batch runner dialog #--------------------------------------- self.actionBatchRunner = QAction( QIcon(':/plugins/inasafe/show-batch-runner.svg'), self.tr('InaSAFE Batch Runner'), self.iface.mainWindow()) self.actionBatchRunner.setStatusTip( self.tr('Open InaSAFE Batch Runner')) self.actionBatchRunner.setWhatsThis( self.tr('Open InaSAFE Batch Runner')) self.actionBatchRunner.triggered.connect(self.show_batch_runner) self.add_action(self.actionBatchRunner) #--------------------------------------- # Create action for batch runner dialog #--------------------------------------- self.actionSaveScenario = QAction( QIcon(':/plugins/inasafe/save-as-scenario.svg'), self.tr('Save current scenario'), self.iface.mainWindow()) myMessage = self.tr('Save current scenario to text file') self.actionSaveScenario.setStatusTip(myMessage) self.actionSaveScenario.setWhatsThis(myMessage) # noinspection PyUnresolvedReferences self.actionSaveScenario.triggered.connect(self.save_scenario) self.add_action(self.actionSaveScenario) #-------------------------------------- # Create action for import OSM Dialog #-------------------------------------- self.actionImportDlg = QAction( QIcon(':/plugins/inasafe/show-osm-download.svg'), self.tr('InaSAFE OpenStreetMap Downloader'), self.iface.mainWindow()) self.actionImportDlg.setStatusTip( self.tr('InaSAFE OpenStreetMap Downloader')) self.actionImportDlg.setWhatsThis( self.tr('InaSAFE OpenStreetMap Downloader')) self.actionImportDlg.triggered.connect(self.show_osm_downloader) self.add_action(self.actionImportDlg) #-------------------------------------- # create dockwidget and tabify it with the legend #-------------------------------------- self.dockWidget = Dock(self.iface) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockWidget) myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend') if myLegendTab: self.iface.mainWindow().tabifyDockWidget(myLegendTab, self.dockWidget) self.dockWidget.raise_() # # Hook up a slot for when the dock is hidden using its close button # or view-panels # self.dockWidget.visibilityChanged.connect(self.toggle_inasafe_action) # pylint: disable=W0201 def clear_modules(self): """Unload inasafe functions and try to return QGIS to before InaSAFE. """ from safe.impact_functions import core core.unload_plugins() # next lets force remove any inasafe related modules myModules = [] for myModule in sys.modules: if 'inasafe' in myModule: # Check if it is really one of our modules i.e. exists in the # plugin directory myTokens = myModule.split('.') myPath = '' for myToken in myTokens: myPath += os.path.sep + myToken myParent = os.path.abspath( os.path.join(__file__, os.path.pardir, os.path.pardir)) myFullPath = os.path.join(myParent, myPath + '.py') if os.path.exists(os.path.abspath(myFullPath)): LOGGER.debug('Removing: %s' % myModule) myModules.append(myModule) for myModule in myModules: del (sys.modules[myModule]) for myModule in sys.modules: if 'inasafe' in myModule: print myModule # Lets also clean up all the path additions that were made myPackagePath = os.path.abspath( os.path.join(os.path.dirname(__file__), os.path.pardir)) LOGGER.debug('Path to remove: %s' % myPackagePath) # We use a list comprehension to ensure duplicate entries are removed LOGGER.debug(sys.path) sys.path = [y for y in sys.path if myPackagePath not in y] LOGGER.debug(sys.path) def unload(self): """GUI breakdown procedure (for QGIS plugin api). .. note:: Don't change the name of this method from unload! This method is called by QGIS and should be used to *remove* any graphical user interface elements that should appear in QGIS. """ # Remove the plugin menu item and icon for myAction in self.actions: self.iface.removePluginMenu(self.tr('InaSAFE'), myAction) self.iface.removeToolBarIcon(myAction) self.iface.mainWindow().removeDockWidget(self.dockWidget) self.iface.mainWindow().removeToolBar(self.toolbar) self.dockWidget.setVisible(False) self.dockWidget.destroy() self.iface.currentLayerChanged.disconnect(self.layer_changed) self.clear_modules() def toggle_inasafe_action(self, checked): """Check or uncheck the toggle inaSAFE toolbar button. This slot is called when the user hides the inaSAFE panel using its close button or using view->panels. :param checked: True if the dock should be shown, otherwise False. :type checked: bool """ self.actionDock.setChecked(checked) # Run method that performs all the real work def toggle_dock_visibility(self): """Show or hide the dock widget.""" if self.dockWidget.isVisible(): self.dockWidget.setVisible(False) else: self.dockWidget.setVisible(True) self.dockWidget.raise_() def show_minimum_needs(self): """Show the minimum needs dialog.""" # import here only so that it is AFTER i18n set up from safe_qgis.tools.minimum_needs import MinimumNeeds myDialog = MinimumNeeds(self.iface.mainWindow()) myDialog.exec_() # modal def show_options(self): """Show the options dialog.""" # import here only so that it is AFTER i18n set up from safe_qgis.tools.options_dialog import OptionsDialog myDialog = OptionsDialog(self.iface, self.dockWidget, self.iface.mainWindow()) myDialog.exec_() # modal def show_keywords_editor(self): """Show the keywords editor.""" # import here only so that it is AFTER i18n set up from safe_qgis.tools.keywords_dialog import KeywordsDialog if self.iface.activeLayer() is None: return myDialog = KeywordsDialog(self.iface.mainWindow(), self.iface, self.dockWidget) myDialog.exec_() # modal def show_function_browser(self): """Show the impact function browser tool.""" # import here only so that it is AFTER i18n set up from safe_qgis.tools.function_browser import FunctionBrowser myDialog = FunctionBrowser(self.iface.mainWindow()) myDialog.exec_() # modal def show_shakemap_importer(self): """Show the converter dialog.""" # import here only so that it is AFTER i18n set up from safe_qgis.tools.shakemap_importer import ShakemapImporter myDialog = ShakemapImporter(self.iface.mainWindow()) myDialog.exec_() # modal def show_osm_downloader(self): """Show the OSM buildings downloader dialog.""" from safe_qgis.tools.osm_downloader import OsmDownloader dialog = OsmDownloader(self.iface.mainWindow(), self.iface) dialog.exec_() # modal def show_batch_runner(self): """Show the batch runner dialog.""" from safe_qgis.batch.batch_dialog import BatchDialog myDialog = BatchDialog(parent=self.iface.mainWindow(), iface=self.iface, dock=self.dockWidget) myDialog.exec_() # modal def save_scenario(self): """Save current scenario to text file,""" self.dockWidget.save_current_scenario() def reset_dock(self): """Reset the dock to its default state.""" self.dockWidget.get_layers() def layer_changed(self, layer): """Enable or disable keywords editor icon when active layer changes. :param layer: The layer that is now active. :type layer: QgsMapLayer """ if layer is None: self.actionKeywordsDialog.setEnabled(False) else: self.actionKeywordsDialog.setEnabled(True) def shortcut_f7(self): """Executed when user press F7 - will show the shakemap importer.""" self.show_shakemap_importer()
class Main: def __init__(self, iface): '''Construtor''' self.iface = iface self.isOpen = False def initGui(self): #INICIAR VARIÁVEIS E SINAIS self.initVariables() self.initSignals() # self.openWindow() self.isOpen = True def unload(self): del self.dockWindow del self.toolbar def initVariables(self): #CRIAR ACTIONS self.a = QAction(QIcon(":/plugins/MapFinder/icons/main.png"), u'Buscar cartas', self.iface.mainWindow()) self.a.setCheckable(True) self.toolbar = self.iface.addToolBar(u'MapFinder Brasil') self.toolbar.addAction(self.a) #OUTRAS VARIAVEIS self.msgBox = QMessageBox() self.canvas = self.iface.mapCanvas() self.auxiliar = Auxiliar(self.iface) self.dockWindow = Interface(self.canvas, self.auxiliar) def initSignals(self): self.a.triggered.connect(self.openWindow) self.dockWindow.closeEvent = self.closeDock def initPlugin(self): pass def openWindow(self, b = True): if(b): self.iface.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockWindow) self.isOpen = True else: self.dockWindow.boxButton.setChecked(False) self.dockWindow.geometryButton.setChecked(False) self.dockWindow.close() def closeDock(self, e): #del self.dockWindow self.isOpen = False self.a.setChecked(False) try: self.canvas.unsetMapTool(self.dockWindow.currentTool) except: pass try: self.canvas.scene().removeItem(self.dockWindow.myToolBox.rubberBand) except: pass try: self.canvas.scene().removeItem(self.dockWindow.myToolGeom.rubberBand) except: pass def closeWindow(self, e): pass def showMessage(self, text): self.msgBox.setIcon(QMessageBox.Critical) self.msgBox.setWindowTitle("Erro") self.msgBox.setStandardButtons(QMessageBox.Ok) self.msgBox.setText(text) self.msgBox.exec_() def closeMsgBox(self, b): self.msgBox.close()
def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, checkable=False, is_checked=False, 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.setEnabled(enabled_flag) action.setCheckable(checkable) if checkable: action.setChecked(is_checked) if not checkable: action.triggered.connect(callback) else: action.toggled.connect(callback) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action
class Plugin: """The QGIS interface implementation for the Risk in a box plugin. This class acts as the 'glue' between QGIS and our custom logic. It creates a toolbar and menubar entry and launches the InaSAFE user interface if these are activated. """ def __init__(self, iface): """Class constructor. On instantiation, the plugin instance will be assigned a copy of the QGIS iface object which will allow this plugin to access and manipulate the running QGIS instance that spawned it. Args: iface - a Quantum GIS QGisAppInterface instance. This instance is automatically passed to the plugin by QGIS when it loads the plugin. Returns: None. Raises: no exceptions explicitly raised. """ # Save reference to the QGIS interface self.iface = iface self.translator = None self.setupI18n() #print self.tr('InaSAFE') def setupI18n(self, thePreferredLocale=None): """Setup internationalisation for the plugin. See if QGIS wants to override the system locale and then see if we can get a valid translation file for whatever locale is effectively being used. Args: thePreferredLocale - optional parameter which if set will override any other way of determining locale.. Returns: None. Raises: no exceptions explicitly raised. """ myOverrideFlag = QSettings().value('locale/overrideFlag', QVariant(False)).toBool() myLocaleName = None if thePreferredLocale is not None: myLocaleName = thePreferredLocale elif myOverrideFlag: myLocaleName = QSettings().value('locale/userLocale', QVariant('')).toString() else: myLocaleName = QLocale.system().name() # Also set the system locale to the user overridden local # so that the inasafe library functions gettext will work # .. see:: :py:func:`common.utilities` os.environ['LANG'] = str(myLocaleName) myRoot = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) myTranslationPath = os.path.join( myRoot, 'safe_qgis', 'i18n', 'inasafe_' + str(myLocaleName) + '.qm') if os.path.exists(myTranslationPath): self.translator = QTranslator() myResult = self.translator.load(myTranslationPath) if not myResult: myMessage = 'Failed to load translation for %s' % myLocaleName raise TranslationLoadException(myMessage) QCoreApplication.installTranslator(self.translator) def tr(self, theString): """We implement this ourself since we do not inherit QObject. Args: theString - string for translation. Returns: Translated version of theString. Raises: no exceptions explicitly raised. """ return QCoreApplication.translate('Plugin', theString) def initGui(self): """Gui initialisation procedure (for QGIS plugin api). This method is called by QGIS and should be used to set up any graphical user interface elements that should appear in QGIS by default (i.e. before the user performs any explicit action with the plugin). Args: None. Returns: None. Raises: no exceptions explicitly raised. """ # Import dock here as it needs to be imported AFTER i18n is set up from safe_qgis.dock import Dock self.dockWidget = None #-------------------------------------- # Create action for plugin dockable window (show/hide) #-------------------------------------- # pylint: disable=W0201 self.actionDock = QAction(QIcon(':/plugins/inasafe/icon.png'), self.tr('Toggle InaSAFE Dock'), self.iface.mainWindow()) self.actionDock.setStatusTip(self.tr('Show/hide InaSAFE dock widget')) self.actionDock.setWhatsThis(self.tr('Show/hide InaSAFE dock widget')) self.actionDock.setCheckable(True) self.actionDock.setChecked(True) QObject.connect(self.actionDock, SIGNAL('triggered()'), self.showHideDockWidget) # add to plugin toolbar self.iface.addToolBarIcon(self.actionDock) # add to plugin menu self.iface.addPluginToMenu(self.tr('InaSAFE'), self.actionDock) #-------------------------------------- # Create action for keywords editor #-------------------------------------- self.actionKeywordsDialog = QAction( QIcon(':/plugins/inasafe/keywords.png'), self.tr('Keyword Editor'), self.iface.mainWindow()) self.actionKeywordsDialog.setStatusTip( self.tr('Open the keywords editor')) self.actionKeywordsDialog.setWhatsThis( self.tr('Open the keywords editor')) QObject.connect(self.actionKeywordsDialog, SIGNAL('triggered()'), self.showKeywordsEditor) self.iface.addToolBarIcon(self.actionKeywordsDialog) self.iface.addPluginToMenu(self.tr('InaSAFE'), self.actionKeywordsDialog) #-------------------------------------- # Create action for reset icon #-------------------------------------- self.actionResetDock = QAction(QIcon(':/plugins/inasafe/reload.png'), self.tr('Reset Dock'), self.iface.mainWindow()) self.actionResetDock.setStatusTip(self.tr('Reset the InaSAFE Dock')) self.actionResetDock.setWhatsThis(self.tr('Reset the InaSAFE Dock')) QObject.connect(self.actionResetDock, SIGNAL('triggered()'), self.resetDock) self.iface.addToolBarIcon(self.actionResetDock) self.iface.addPluginToMenu(self.tr('InaSAFE'), self.actionResetDock) #-------------------------------------- # Create action for options dialog #-------------------------------------- self.actionOptions = QAction(QIcon(':/plugins/inasafe/options.png'), self.tr('InaSAFE Options'), self.iface.mainWindow()) self.actionOptions.setStatusTip(self.tr('Open InaSAFE options dialog')) self.actionOptions.setWhatsThis(self.tr('Open InaSAFE options dialog')) QObject.connect(self.actionOptions, SIGNAL('triggered()'), self.showOptions) self.iface.addToolBarIcon(self.actionOptions) self.iface.addPluginToMenu(self.tr('InaSAFE'), self.actionOptions) #-------------------------------------- # create dockwidget and tabify it with the legend #-------------------------------------- self.dockWidget = Dock(self.iface) self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget) myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend') if myLegendTab: self.iface.mainWindow().tabifyDockWidget(myLegendTab, self.dockWidget) self.dockWidget.raise_() # # Hook up a slot for when the current layer is changed # QObject.connect(self.iface, SIGNAL("currentLayerChanged(QgsMapLayer*)"), self.layerChanged) # pylint: disable=W0201 def unload(self): """Gui breakdown procedure (for QGIS plugin api). This method is called by QGIS and should be used to *remove* any graphical user interface elements that should appear in QGIS. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ # Remove the plugin menu item and icon self.iface.removePluginMenu(self.tr('InaSAFE'), self.actionDock) self.iface.removeToolBarIcon(self.actionDock) self.iface.removePluginMenu(self.tr('InaSAFE'), self.actionKeywordsDialog) self.iface.removeToolBarIcon(self.actionKeywordsDialog) self.iface.removePluginMenu(self.tr('InaSAFE'), self.actionResetDock) self.iface.removeToolBarIcon(self.actionResetDock) self.iface.removePluginMenu(self.tr('InaSAFE'), self.actionOptions) self.iface.removeToolBarIcon(self.actionOptions) self.iface.mainWindow().removeDockWidget(self.dockWidget) self.dockWidget.setVisible(False) self.dockWidget.destroy() QObject.disconnect(self.iface, SIGNAL("currentLayerChanged(QgsMapLayer*)"), self.layerChanged) # Run method that performs all the real work def showHideDockWidget(self): """Show or hide the dock widget. This slot is called when the user clicks the toolbar icon or menu item associated with this plugin. It will hide or show the dock depending on its current state. .. see also:: :func:`Plugin.initGui`. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ if self.dockWidget.isVisible(): self.dockWidget.setVisible(False) else: self.dockWidget.setVisible(True) self.dockWidget.raise_() def showOptions(self): """Show the options dialog. This slot is called when the user clicks the options toolbar icon or menu item associated with this plugin .. see also:: :func:`Plugin.initGui`. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ # import here only so that it is AFTER i18n set up from safe_qgis.options_dialog import OptionsDialog myDialog = OptionsDialog(self.iface.mainWindow(), self.iface, self.dockWidget) myDialog.show() def showKeywordsEditor(self): """Show the keywords editor. This slot is called when the user clicks the keyword editor toolbar icon or menu item associated with this plugin .. see also:: :func:`Plugin.initGui`. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ # import here only so that it is AFTER i18n set up from safe_qgis.keywords_dialog import KeywordsDialog if self.iface.activeLayer() is None: return myDialog = KeywordsDialog(self.iface.mainWindow(), self.iface, self.dockWidget) myDialog.show() def resetDock(self): """Reset the dock to its default state. This slot is called when the user clicks the reset icon in the toolbar or the reset menu item associated with this plugin .. see also:: :func:`Plugin.initGui`. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ self.dockWidget.getLayers() def layerChanged(self, theLayer): """Enable or disable the keywords editor icon. This slot is called when the user clicks the keyword editor toolbar icon or menu item associated with this plugin .. see also:: :func:`Plugin.initGui`. Args: None. Returns: None. Raises: no exceptions explicitly raised. """ if theLayer is None: self.actionKeywordsDialog.setEnabled(False) else: self.actionKeywordsDialog.setEnabled(True) self.dockWidget.layerChanged(theLayer)
class MSQtCanvas(QWidget, MSDialogController): """ DONE:the current peak is not updated while the user press up and down key on the treeView TODO: think about a mjor redesign of those classes """ #linePlotted = pyqtSignal(object, str) #lineRemoved = pyqtSignal(object) def __init__(self, data, title, flags="chroma", parent=None, **k): QWidget.__init__(self, parent) MSDialogController.__init__(self, 0, parent) self.model = self.qApp.model self.view = self.qApp.view self.data = data self.title = title self.flags = flags if self.flags == 'peak': if self.acTree not in (self.view.treeView_2, self.view.treeView_3): print "Unknown Error" return idx = self.acTree.selectedIndexes()[0] s = qApp.instance().dockControl.currentSample[ 1 if self.acTree is self.view.treeView_2 else 2] if s is None: print "unknow error" return values = map(float, idx.data().toString().split('/')[:2]) self.currentPeak = s.peakAt(*values) #connection to update the selected Peak object self.connect(self.acTree, SIGNAL("changedLine"), self.updateCurrentPeak) self.minX, self.maxX, self.maxY = [0] * 3 #if flags != 'peak': # self.minX, self.maxX, self.maxY = self.getMax() self.pw = PlotWidget(self.minX, self.maxX, self.maxY, parent=self, **k) #parent=self, #self.pw.setAttribute(Qt.WA_DeleteOnClose)#plotItem.setAttribute(Qt.WA_PaintOnScreen & Qt.WA_PaintUnclipped) if k.get('antialiased', False): self.pw.setRenderHint(0x01) #antialiasing i suppose self.pw.setTitle(title) self.pw.updateGrid() self._setupUi() self.connect(self, SIGNAL('linePlotted'), self.updateContextMenu) self.connect(self.view.sampleTableView, SIGNAL("disHighlightRequested(QModelIndex)"), self.disHighlightOne) self.connect(self.view.sampleTableView, SIGNAL("highlightRequested(QModelIndex)"), self.highlight) self.connect(self.view.sampleTableView, SIGNAL("noHighlightRequested()"), self.disHighlight) self.connect(self.view.ppmEditer, SIGNAL('valueChanged(double)'), self.redrawAll) self.drawnItems = {} self.trashItems = [] #why unecessary? nope to collect annotation stuff self.textLabels = [] self.pixmaps = [] self.dataPoints = None self._plotting(self.data) #initial plotting def getMax(self): localXmin = [] localXmax = [] localYmax = [] for el in self.data: if el is None: continue localXmin.append(min_f(el.x_data)) localXmax.append(max_f(el.x_data)) localYmax.append(max_l(el.y_data)) return min_f(np.array(localXmin)), max_f(np.array(localXmax)), max_l( np.array(localYmax)) def _plotting(self, data): """ refactor this shit c = Line(chrom.x_data, chrom.y_data, QColor.fromRgbF(*(self.ref.sample.color+(.7,))), parent=self.pw.plotItem.vb, scene=self.pw.scene()) #test scatter plot self.scatter = ScatterPlotItem(x=chrom.x_data, y=chrom.y_data) self.pw.addDataItem(self.scatter) self.scatter.sigClicked.connect(self.requestSpectra) """ if self.flags == 'peak': self.connect(self.pw.plotItem.vb, SIGNAL('showDiffOrSpectra(PyQt_PyObject)'), self.drawSpectra) self.ref = sorted([e for e in data if e is not None], key=lambda x: x.height)[-1] ppm = self.view.ppmEditer.value() if self.view.usePpm.isChecked( ) else self.ref.sample.ppm chrom = self.ref.sample.massExtraction(self.ref.mass(), ppm, asChromatogram=True) #show labels self.textLabels += self.showTextLabel(chrom.x_data, chrom.y_data) #drawing color = QColor.fromRgbF(*self.ref.sample.color + (.5, )) c = self.pw.plotItem.plot(chrom.x_data, chrom.y_data, pen=color) self.drawnItems[self.ref.sample] = c # peak's pixmap on the ref peak pix = PeakArrowItem(self.ref, pen=color, brush=color, pos=(self.ref.rt, self.ref.height + (self.ref.height * 6) / 100.), angle=-90, parent=self.pw.plotItem.vb) pix.setZValue(1000) self.pw.addItem(pix) #both these connections are emitted #in peak Indicator by effictivamente qApp self.connect(qApp.instance(), SIGNAL("highlightRequested"), c.setHighlighted) self.connect(qApp.instance(), SIGNAL('updateBarPlot'), self.barPlot.setPeakGroup) # self.emit(SIGNAL('linePlotted'), self.ref.sample.shortName()) #if qApp.instance().lowMemory: # chromatograms=[el.sample.loadAndExtract(el.mass(), el.sample.ppm, asChromatogram=True) \ # for el in data if el != ref and el is not None] #else: ppm = self.view.ppmEditer.value() if self.view.usePpm.isChecked( ) else self.ref.sample.ppm chromatograms=[el.sample.massExtraction(el.mass(), ppm, asChromatogram=True) \ for el in data if el is not None and el != self.ref] self.drawEics(chromatograms) #initialisation zoom on the peak self.pw.setYRange(0., self.ref.height + (self.ref.height * 12) / 100.) self.pw.setXRange(self.ref.rtmin - 20, self.ref.rtmax + 20) elif self.flags == 'chroma': ref = [d for d in data if d is not None] if not ref: print "Error, empty data to plot" return self.ref = ref[0] self.textLabels += self.showTextLabel(self.ref.x_data, self.ref.y_data) self.drawEics(data) else: #spectrum if not data: #print "NOTHING TO PLOT" return self.ref = data[0] for el in data: c = SpectrumItem(el, centroid=True, scene=self.pw.scene()) self.pw.addItem(c) self.drawnItems[el.sample] = c self.pw.plotItem.curves.append(c) self.emit(SIGNAL('linePlotted'), el.sample.shortName()) #just put time information if data: i = 0 while data[i] is None and i < len(data): i += 1 self.textLabels += self.showTextLabel(data[i].x_data, data[i].y_data) #setting the range #warning: autoRange pw function does not work well #on spectrum item maxY = max([el.y_data.max() for el in data]) minX, maxX = min([el.x_data.min() for el in data ]), max([el.x_data.max() for el in data]) self.pw.setXRange(minX, maxX, padding=0) self.pw.setYRange(0., maxY, padding=0) def drawEics(self, data): for chrom in data: color = QColor.fromRgbF(*(chrom.sample.color + (.5, ))) c = self.pw.plotItem.plot(x=chrom.x_data, y=chrom.y_data, pen=color) #c = Line(chrom.x_data, chrom.y_data, # color, # parent=self.pw.plotItem.vb, # scene=self.pw.scene()) self.drawnItems[chrom.sample] = c #self.pw.addItem(c) #self.pw.plotItem.curves.append(c) self.emit(SIGNAL('linePlotted'), chrom.sample.shortName()) if self.flags != 'peaks': self.pw.autoRange() #=========================================================================== # UI stuffs #=========================================================================== def _setupUi(self): # self.stop = QToolButton() # self.stop.setIcon(QIcon('gui/icons/tools_wizard.png')) # self.stop.setToolTip('Enable or disable the appearance of the contextMenu') layout = QVBoxLayout(self) self.smoothButton = QToolButton() #self.smoothButton.setToolButtonStyle(2) self.smoothButton.setPopupMode(2) self.smoothButton.setToolTip("Smooth the visualized data") #self.smoothButton.setText("Smooth...") self.smoothButton.setIcon( QIcon(os.path.normcase('gui/icons/smooth.png'))) self.smoothMenu = QMenu() self.connect(self.smoothMenu, SIGNAL('triggered(QAction*)'), self.smooth) self.smoothButton.setMenu(self.smoothMenu) self.pw.plotItem.toolBar.addWidget(self.smoothButton) self.flipButton = QToolButton() #self.flipButton.setToolButtonStyle(2) self.flipButton.setIcon(QIcon(os.path.normcase('gui/icons/flip.png'))) self.flipButton.setToolTip("Flip the visualized data") #self.flipButton.setText("Flip...") self.flipButton.setPopupMode(2) self.flipMenu = QMenu() self.connect(self.flipMenu, SIGNAL('triggered(QAction*)'), self.flip) self.flipButton.setMenu(self.flipMenu) self.pw.plotItem.toolBar.addWidget(self.flipButton) self.annotButton = QToolButton() #self.annotButton.setToolButtonStyle(2) self.annotButton.setPopupMode(2) #self.annotButton.setText("&Annotate...") self.annotButton.setIcon( QIcon(os.path.normcase('gui/icons/attach.png'))) self.annotMenu = QMenu() self.annotMenu.addAction("&Add Annotation") self.annotMenu.addAction("&Remove last Annotation") self.annotMenu.addAction("&Remove All Annotation") self.annotButton.setMenu(self.annotMenu) self.connect(self.annotMenu.actions()[0], SIGNAL("triggered()"), self.annotate) self.connect(self.annotMenu.actions()[1], SIGNAL("triggered()"), self.removeLastAnnot) self.connect(self.annotMenu.actions()[2], SIGNAL("triggered()"), self.removeAllAnnot) self.pw.plotItem.toolBar.addWidget(self.annotButton) self.addPlotButton = QToolButton() #self.addPlotButton.setToolButtonStyle(2) self.addPlotButton.setText("Add...") self.addPlotButton.setIcon( QIcon(os.path.normcase('gui/icons/list_add.png'))) self.addPlotButton.setToolTip("Add a new plot to the current figure") #self.addPlotButton.setText('&Add Plot') self.pw.plotItem.toolBar.addWidget(self.addPlotButton) self.showSpectra = QToolButton() self.showSpectra.setPopupMode(2) #instant popup #self.showSpectra.setToolButtonStyle(2) self.showSpectra.setIcon( QIcon(os.path.normcase('gui/icons/file_export.png'))) #self.showSpectra.setText('&Show /hide...') self.showSpectra.setToolTip('Show/hide ...') self.showMenu = QMenu() self.showTextLabels = QAction("&Show Labels", self.showMenu) self.showTextLabels.setCheckable(True) self.showTextLabels.setChecked(True) self.showMenu.addAction(self.showTextLabels) self.connect(self.showMenu.actions()[0], SIGNAL('toggled(bool)'), self.setTextLabelsVisibility) showSpectrum = QAction("&Merged Spectrum", self.showMenu) showSpectrum.setCheckable(True) if self.flags == 'chroma' or self.flags == 'spectra': showSpectrum.setEnabled(False) self.showMenu.addAction(showSpectrum) self.connect(self.showMenu.actions()[1], SIGNAL('toggled(bool)'), self.drawSpectraRequested) showNonXCMSPeak = QAction("&Show Non XCMS Peak", self.showMenu) showNonXCMSPeak.setCheckable(True) if self.flags == 'spectra': showNonXCMSPeak.setEnabled(False) self.showMenu.addAction(showNonXCMSPeak) self.connect(self.showMenu.actions()[2], SIGNAL('toggled(bool)'), self.setPixmapVisibility) showDataPoints = QAction("&Show DataPoints", self.showMenu) showDataPoints.setCheckable(True) showDataPoints.setChecked(False) self.showMenu.addAction(showDataPoints) self.connect(self.showMenu.actions()[3], SIGNAL('toggled(bool)'), self.setDataPointsVisibility) self.showSpectra.setMenu(self.showMenu) self.pw.plotItem.toolBar.addWidget(self.showSpectra) self.saveToPng = QToolButton() self.saveToPng.setIcon( QIcon(os.path.normcase('gui/icons/thumbnail.png'))) #self.saveToPng.setToolButtonStyle(2) #self.saveToPng.setText("Save to Png...") self.pw.plotItem.toolBar.addWidget(self.saveToPng) self.connect(self.saveToPng, SIGNAL('clicked()'), self.pw.writeImage) #add bar plot even if we are plotting chroma #cause we can find non xcms peaks self.barPlot = BarPlot(scene=self.pw.sceneObj) #self.barPlot.rotate(-90.) if self.flags == 'peak': self.barPlot.setPeakGroup(self.data) #TODO modify to get this close to us #on the left part xpos = self.barPlot.scene().width() * 3.5 #-bwidth; ypos = self.barPlot.scene().height() * 1.1 self.barPlot.setPos(xpos, ypos) self.barPlot.setZValue(1000) layout.addWidget(self.pw) layout.addWidget(self.pw.plotItem.toolBar) def showTextLabel(self, x, y, secure=25): """ add labels of principle peaks of spectrum or chroma on the plot, return the labels, that we can show hide """ maxis = [] #will contain tuple(rt, intens) indexes = [] #from core.MetObjects import MSAbstractTypes from scipy.ndimage import gaussian_filter1d as gauss z = gauss(y, 1) #z = MSAbstractTypes.computeBaseLine(z, 92., 0.8) i = 0 while i < len(z) - 1: while z[i + 1] >= z[i] and i < len(y) - 2: i += 1 maxis.append((x[i], y[i])) indexes.append(i) while z[i + 1] <= z[i] and i < len(z) - 2: i += 1 i += 1 labels = [] for t in sorted(maxis, key=lambda x: x[1])[-5:]: g = QGraphicsTextItem(str(t[0])) g.setFlag(QGraphicsItem.ItemIgnoresTransformations) font = QApplication.font() font.setPointSizeF(6.5) g.setFont(font) g.setDefaultTextColor(Qt.black) g.setPos(t[0], t[1]) labels.append(g) self.pw.addItem(g) return labels #=============================================================================== #SLOTS #=============================================================================== def redrawAll(self, value): self.pw.clear() self._plotting(self.data) def disHighlightOne(self, idx): if not idx.isValid(): return sample = self.model.sample(idx.data().toString(), fullNameEntry=False) if sample is None: return try: self.drawnItems[sample].setHighlighted(False) except KeyError: pass def highlight(self, idx): if not idx.isValid(): return sample = self.model.sample(idx.data().toString(), fullNameEntry=False) if sample is None: return try: self.drawnItems[sample].setHighlighted(True) except KeyError: pass #print "sample not found" self.pw.plotItem.update() #works def disHighlight(self): for key in self.drawnItems.iterkeys(): self.drawnItems[key].setHighlighted(False) self.pw.plotItem.update() def setTextLabelsVisibility(self, bool_): for t in self.textLabels: t.setVisible(bool_) def setDataPointsVisibility(self, b): if self.dataPoints is None: if self.flags == 'peak': chrom = self.ref.sample.massExtraction(self.ref.mass(), self.ref.sample.ppm, asChromatogram=True) self.dataPoints = ScatterPlotItem(x=chrom.x_data, y=chrom.y_data) else: self.dataPoints = ScatterPlotItem(x=self.ref.x_data, y=self.ref.y_data) if self.flags != 'spectra': self.dataPoints.sigClicked.connect(self.requestSpectra) self.pw.addDataItem(self.dataPoints) self.dataPoints.setVisible(b) def setPixmapVisibility(self, bool_): """ draw other peaks than the xcms peak """ if not self.pixmaps and bool_: ppm = 1. if self.ref.sample.kind == 'MRM' else self.ref.sample.ppm chrom = self.ref.sample.massExtraction(self.ref.mass(), ppm, asChromatogram=True) \ if self.flags == 'peak' else self.ref chrom.findNonXCMSPeaks() for p in chrom.peaks.ipeaks(): if self.flags == 'peak': diff = (p.height * 10) / 100 if abs(p.height - self.ref.height) < diff: continue #we assume that they are the same peaks pix = PeakIndicator(p, icon='flags') #self.connect(pix, SIGNAL("highlightRequested"), c.setHighlighted) self.connect(pix, SIGNAL('updateBarPlot'), self.barPlot.setPeakGroup) pix.setPos(p.rt, p.height + (p.height * 10) / 100.) pix.setZValue(1000) self.pixmaps.append(pix) self.pw.addItem(pix) if self.pixmaps: for t in self.pixmaps: t.setVisible(bool_) @pyqtSlot() def updateCurrentPeak(self): idx = self.acTree.selectedIndexes()[0] s = self.model.sample(idx.parent().data().toString(), fullNameEntry=False) if s is not None: self.currentPeak = s.peakAt(*map(float, idx.data().toString().split('/'))) def requestSpectra(self, scatter, l): """ idea plot all spectra between a time range and not only with only one spectra """ if not l: return ref = l[0] self.emit(SIGNAL("drawSpectrumByTime"), ref.pos(), self.ref.sample) @pyqtSlot() def drawSpectraRequested(self, bool_): """ i think this is for plotting merged spectrum """ if bool_: self.emit(SIGNAL('drawSpectraRequested'), self.currentPeak) else: self.hideRequested() def drawSpectra(self, l): self.emit( SIGNAL('drawSpectra(PyQt_PyObject, PyQt_PyObject, PyQt_PyObject)'), l[0], l[1], self.ref.sample) @pyqtSlot() def hideRequested(self): self.emit(SIGNAL('hideRequested')) self.showMenu.actions()[1].setChecked(False) @pyqtSlot() def redraw(self): """ this is for updating the view port when hiding or not samples """ chromas = [] for spl in self.model: if spl.checked: if spl in self.drawnItems.keys(): self.drawnItems[spl].setVisible(True) else: chromas.append(spl.chroma[0]) else: self.drawnItems[spl].setVisible(False) self._plotting(chromas) self.pw.plotItem.update() #works def cleanScene(self): """ remove all items in the trash """ for element in self.trashItems: self.pw.sceneObj.removeItem(element) @pyqtSlot() def updateContextMenu(self, line): self.flipMenu.addAction(line) self.smoothMenu.addAction(line) #=============================================================================== # CONTEXT MENU SLOTS #=============================================================================== @pyqtSlot(str) def flip(self, action): spl = self.model.sample(self.fullXmlPath(action.text())) if spl is None: print "can not flip, can not recognize the selected sample" return try: self.drawnItems[spl].updateData(-self.drawnItems[spl].getData()[1], self.drawnItems[spl].getData()[0]) except KeyError: pass if len(self.data) == 1: #we are flipping the text labels only #if only one dataset is flipped for item in self.textLabels: item.setPos(item.pos().x(), -item.pos().y()) @pyqtSlot(str) def smooth(self, action): """ TODO: would be good to reuse the widget in the menuControl """ from core.MetObjects import MSAbstractTypes class Dial(QDialog): choices = ['flat', 'hanning', 'hamming', 'bartlett', 'blackman'] def __init__(self, parent): QDialog.__init__(self, parent) f = QFormLayout(self) self.a = QSpinBox(self) self.a.setValue(30) self.b = QComboBox(self) self.b.addItems(self.choices) self.c = QDialogButtonBox(self) self.c.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) f.addRow("window:", self.a) f.addRow("method:", self.b) f.addRow("", self.c) self.connect(self.c, SIGNAL("accepted()"), self.sendData) self.connect(self.c, SIGNAL("rejected()"), self.reinitialize) def sendData(self): self.parent().window = self.a.value() self.parent().method = self.b.currentText() self.close() def reinitialize(self): self.parent().window = None self.parent().method = None self.close() Dial(self).exec_() if self.window and self.method: for spl in self.drawnItems.keys(): if action.text() == spl.shortName(): self.drawnItems[spl].updateData( MSAbstractTypes.averageSmoothing( self.drawnItems[spl].getData()[1], self.window, self.method), self.drawnItems[spl].getData()[0]) @pyqtSlot() def plotEIC(self): if self.flags == 'spectra': #show double combobox #select the good spectra then draw pass else: mass, ok = QInputDialog.getText(self.view, "EIC query", "mass:") if not (mass and ok): return xmlfile = self.fullXmlPath(self.selection[0].data().toString()) if not xmlfile: xmlfile = self.fullXmlPath( self.selection[0].parent().data().toString()) if not xmlfile: print "item clicked not recognized..." return sample = self.model.sample(xmlfile) if sample.kind == 'HighRes': error = (sample.ppm / 1e6) * float(mass) x, y = massExtraction(sample, float(mass), error) from core.MetObjects import MSChromatogram chrom = MSChromatogram(x_data=x, y_data=y, sample=sample) else: chrom = sample.getChromWithTrans(math.ceil(float(mass))) self.view.addMdiSubWindow( MSQtCanvas([chrom], "EIC %s" % str(mass), labels={ 'bottom': 'RT(s)', 'left': 'INTENSITY' })) #=========================================================================== # annotate stuff #=========================================================================== @pyqtSlot() def annotate(self): text, bool_ = QInputDialog.getText(self.view, "Annotation dialog", "Annotation:") g = QGraphicsTextItem(str(text)) g.setFlag(QGraphicsItem.ItemIgnoresTransformations) g.setFlag(QGraphicsItem.ItemIsMovable) g.setTextInteractionFlags(Qt.TextEditorInteraction) font = qApp.instance().font() font.setPointSizeF(10.) g.setFont(font) g.setDefaultTextColor(Qt.blue) g.setPos(500, 1e4) self.trashItems.append(g) self.pw.addItem(g) def removeAllAnnot(self): if not self.trashItems: self.view.showErrorMessage("Error", "No annotation detected") return for i in self.trashItems: self.pw.removeItem(i) def removeLastAnnot(self): if not self.trashItems: self.view.showErrorMessage("Error", "No annotation detected") self.pw.removeItem(self.trashItems[-1])
class TrackingDisplay(QToolBar): ''' Display the position of a mobile and add action for centering the map on the vehicle and erasing the track ''' def __init__(self, mobile, parent=None): super(TrackingDisplay, self).__init__(parent) self.setMovable(True) self.setFloatable(True) self.mobile = mobile self.upToDate = False self.lastFix = 0.0 self.createActions() self.mobile.newPosition.connect(self.onNewPosition) self.mobile.timeout.connect(self.onTimeout) def createActions(self): self.nameLabel = QLabel(self.mobile.name) self.nameLabel.setMinimumSize(80, 23) self.nameLabelAction = QWidgetAction(self) self.nameLabelAction.setDefaultWidget(self.nameLabel) self.addAction(self.nameLabelAction) self.enableAction = QAction("Enable Display", self) self.enableAction.setCheckable(True) self.enableAction.setChecked(True) icon = QIcon(':/plugins/PosiView/ledgrey.png') icon.addFile(':/plugins/PosiView/ledgreen.png', QSize(), QIcon.Normal, QIcon.On) self.enableAction.setIcon(icon) self.addAction(self.enableAction) self.enableAction.triggered.connect(self.onEnableClicked) self.enableAction.triggered.connect(self.mobile.setEnabled) self.addSeparator() self.posLabel = QLabel("--:--:-- 0.000000 0.000000\nd = 0.0") self.posLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.posLabel.setMinimumSize(180, 23) self.posLabel.setStyleSheet('background: red; font-size: 8pt') self.posLabelAction = QWidgetAction(self) self.posLabelAction.setDefaultWidget(self.posLabel) self.addAction(self.posLabelAction) self.centerAction = QAction(QIcon(':/plugins/PosiView/center.png'), "Center &Map", self) self.addAction(self.centerAction) self.deleteTrackAction = QAction( QIcon(':/plugins/PosiView/deletetrack.png'), 'Delete &Track', self) self.addAction(self.deleteTrackAction) self.deleteTrackAction.triggered.connect(self.mobile.deleteTrack) self.centerAction.triggered.connect(self.mobile.centerOnMap) @pyqtSlot(float, QgsPoint, float, float) def onNewPosition(self, fix, pos, depth, altitude): s = str() if fix > 0: s = strftime('%H:%M:%S', gmtime(fix)) else: s = '--:--:--' s += " {:f} {:f}\nd = {:.1f}".format(pos.y(), pos.x(), depth) if altitude > -9999: s += " alt = {:.1f}".format(altitude) self.posLabel.setText(s) if not self.upToDate: if fix > self.lastFix: self.posLabel.setStyleSheet('background: lime; font-size: 8pt') self.upToDate = True self.lastFix = fix @pyqtSlot() def onTimeout(self): self.upToDate = False self.posLabel.setStyleSheet('background: red; font-size: 8pt') @pyqtSlot(bool) def onEnableClicked(self, enable): self.upToDate = False if enable: self.posLabel.setStyleSheet('background: red; font-size: 8pt') else: self.posLabel.setStyleSheet('background: white; font-size: 8pt') def releaseMobile(self): self.mobile = None
class VolumeEditorWidget(QWidget): def __init__(self, parent=None, editor=None): super(VolumeEditorWidget, self).__init__(parent=parent) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setFocusPolicy(Qt.StrongFocus) self.editor = None if editor != None: self.init(editor) self._viewMenu = None self.allZoomToFit = QAction(QIcon(":/icons/icons/view-fullscreen.png"), "Zoom to &Fit", self) self.allZoomToFit.triggered.connect(self._fitToScreen) self.allToggleHUD = QAction(QIcon(), "Show &HUDs", self) self.allToggleHUD.setCheckable(True) self.allToggleHUD.setChecked(True) self.allToggleHUD.toggled.connect(self._toggleHUDs) self.allCenter = QAction(QIcon(), "&Center views", self) self.allCenter.triggered.connect(self._centerAllImages) self.selectedCenter = QAction(QIcon(), "C&enter view", self) self.selectedCenter.triggered.connect(self._centerImage) self.selectedZoomToFit = QAction( QIcon(":/icons/icons/view-fullscreen.png"), "Zoom to Fit", self) self.selectedZoomToFit.triggered.connect(self._fitImage) self.selectedZoomToOriginal = QAction(QIcon(), "Reset Zoom", self) self.selectedZoomToOriginal.triggered.connect( self._restoreImageToOriginalSize) self.rubberBandZoom = QAction(QIcon(), "Rubberband Zoom", self) self.rubberBandZoom.triggered.connect(self._rubberBandZoom) self.toggleSelectedHUD = QAction(QIcon(), "Show HUD", self) self.toggleSelectedHUD.setCheckable(True) self.toggleSelectedHUD.setChecked(True) self.toggleSelectedHUD.toggled.connect(self._toggleSelectedHud) def _setupVolumeExtent(self): '''Setup min/max values of position/coordinate control elements. Position/coordinate information is read from the volumeEditor's positionModel. ''' maxTime = self.editor.posModel.shape5D[0] - 1 self.quadview.statusBar.timeLabel.setHidden(maxTime == 0) self.quadview.statusBar.timeSpinBox.setHidden(maxTime == 0) self.quadview.statusBar.timeSpinBox.setRange(0, maxTime) self.quadview.statusBar.timeSpinBox.setSuffix("/{}".format(maxTime)) for i in range(3): self.editor.imageViews[i].hud.setMaximum( self.editor.posModel.volumeExtent(i) - 1) def init(self, volumina): self.editor = volumina self.hudsShown = [True] * 3 def onViewFocused(): axis = self.editor._lastImageViewFocus self.toggleSelectedHUD.setChecked( self.editor.imageViews[axis]._hud.isVisible()) self.editor.newImageView2DFocus.connect(onViewFocused) self.layout = QHBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.setLayout(self.layout) # setup quadview axisLabels = ["X", "Y", "Z"] axisColors = [QColor("#dc143c"), QColor("green"), QColor("blue")] for i, v in enumerate(self.editor.imageViews): v.hud = ImageView2DHud(v) #connect interpreter v.hud.createImageView2DHud(axisLabels[i], 0, axisColors[i], QColor("white")) v.hud.sliceSelector.valueChanged.connect( partial(self.editor.navCtrl.changeSliceAbsolute, axis=i)) self.quadview = QuadView(self, self.editor.imageViews[2], self.editor.imageViews[0], self.editor.imageViews[1], self.editor.view3d) self.quadview.installEventFilter(self) self.quadViewStatusBar = QuadStatusBar() self.quadViewStatusBar.createQuadViewStatusBar(QColor("#dc143c"), QColor("white"), QColor("green"), QColor("white"), QColor("blue"), QColor("white")) self.quadview.addStatusBar(self.quadViewStatusBar) self.layout.addWidget(self.quadview) ## Why do we have to prevent TimerEvents reaching the SpinBoxes? # # Sometimes clicking a SpinBox once caused the value to increase by # two. This is why: # # When a MouseClicked event is received by the SpinBox it fires a timerevent to control # the repeated increase of the value as long as the mouse button is pressed. The timer # is killed when it receives a MouseRelease event. If a slot connected to the valueChanged # signal of the SpinBox takes to long to process the signal the mouse release # and timer events get queued up and sometimes the timer event reaches the widget before # the mouse release event. That's why it increases the value by another step. To prevent # this we are blocking the timer events at the cost of no autorepeat anymore. # # See also: # http://lists.trolltech.com/qt-interest/2002-04/thread00137-0.html # http://www.qtcentre.org/threads/43078-QSpinBox-Timer-Issue # http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/widgets/qabstractspinbox.cpp#line1195 self.quadview.statusBar.timeSpinBox.installEventFilter(_timerEater) def setTime(t): if t == self.editor.posModel.time: return self.editor.posModel.time = t self.quadview.statusBar.timeSpinBox.valueChanged.connect(setTime) def getTime(newT): self.quadview.statusBar.timeSpinBox.setValue(newT) self.editor.posModel.timeChanged.connect(getTime) def toggleSliceIntersection(state): self.editor.navCtrl.indicateSliceIntersection = ( state == Qt.Checked) self.quadview.statusBar.positionCheckBox.stateChanged.connect( toggleSliceIntersection) self.editor.posModel.cursorPositionChanged.connect( self._updateInfoLabels) def onShapeChanged(): singletonDims = filter( lambda (i, dim): dim == 1, enumerate(self.editor.posModel.shape5D[1:4])) if len(singletonDims) == 1: # Maximize the slicing view for this axis axis = singletonDims[0][0] self.quadview.ensureMaximized(axis) self.hudsShown[axis] = self.editor.imageViews[axis].hudVisible( ) self.editor.imageViews[axis].setHudVisible(False) self.quadViewStatusBar.showXYCoordinates() self.quadview.statusBar.positionCheckBox.setVisible(False) else: self.quadViewStatusBar.showXYZCoordinates() for i in range(3): self.editor.imageViews[i].setHudVisible(self.hudsShown[i]) self.quadview.statusBar.positionCheckBox.setVisible(True) self._setupVolumeExtent() self.editor.shapeChanged.connect(onShapeChanged) self.updateGeometry() self.update() self.quadview.update() # shortcuts self._initShortcuts() def _toggleDebugPatches(self, show): self.editor.showDebugPatches = show def _fitToScreen(self): shape = self.editor.posModel.shape for i, v in enumerate(self.editor.imageViews): s = list(copy.copy(shape)) del s[i] v.changeViewPort(v.scene().data2scene.mapRect(QRectF(0, 0, *s))) def _fitImage(self): if self.editor._lastImageViewFocus is not None: self.editor.imageViews[self.editor._lastImageViewFocus].fitImage() def _restoreImageToOriginalSize(self): if self.editor._lastImageViewFocus is not None: self.editor.imageViews[self.editor._lastImageViewFocus].doScaleTo() def _rubberBandZoom(self): if self.editor._lastImageViewFocus is not None: if not self.editor.imageViews[ self.editor._lastImageViewFocus]._isRubberBandZoom: self.editor.imageViews[ self.editor._lastImageViewFocus]._isRubberBandZoom = True self.editor.imageViews[ self.editor. _lastImageViewFocus]._cursorBackup = self.editor.imageViews[ self.editor._lastImageViewFocus].cursor() self.editor.imageViews[ self.editor._lastImageViewFocus].setCursor(Qt.CrossCursor) else: self.editor.imageViews[ self.editor._lastImageViewFocus]._isRubberBandZoom = False self.editor.imageViews[ self.editor._lastImageViewFocus].setCursor( self.editor.imageViews[ self.editor._lastImageViewFocus]._cursorBackup) def _toggleHUDs(self, checked): for v in self.editor.imageViews: v.setHudVisible(checked) def _toggleSelectedHud(self, checked): if self.editor._lastImageViewFocus is not None: self.editor.imageViews[ self.editor._lastImageViewFocus].setHudVisible(checked) def _centerAllImages(self): for v in self.editor.imageViews: v.centerImage() def _centerImage(self): if self.editor._lastImageViewFocus is not None: self.editor.imageViews[ self.editor._lastImageViewFocus].centerImage() def _shortcutHelper(self, keySequence, group, description, parent, function, context=None, enabled=None, widget=None): shortcut = QShortcut(QKeySequence(keySequence), parent, member=function, ambiguousMember=function) if context != None: shortcut.setContext(context) if enabled != None: shortcut.setEnabled(True) ShortcutManager().register(group, description, shortcut, widget) return shortcut, group, description def _initShortcuts(self): self.shortcuts = [] # TODO: Fix this dependency on ImageView/HUD internals self.shortcuts.append( self._shortcutHelper( "x", "Navigation", "Minimize/Maximize x-Window", self, self.quadview.switchXMinMax, Qt.ApplicationShortcut, True, widget=self.editor.imageViews[0].hud.buttons['maximize'])) self.shortcuts.append( self._shortcutHelper( "y", "Navigation", "Minimize/Maximize y-Window", self, self.quadview.switchYMinMax, Qt.ApplicationShortcut, True, widget=self.editor.imageViews[1].hud.buttons['maximize'])) self.shortcuts.append( self._shortcutHelper( "z", "Navigation", "Minimize/Maximize z-Window", self, self.quadview.switchZMinMax, Qt.ApplicationShortcut, True, widget=self.editor.imageViews[2].hud.buttons['maximize'])) for i, v in enumerate(self.editor.imageViews): self.shortcuts.append( self._shortcutHelper("+", "Navigation", "Zoom in", v, v.zoomIn, Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("-", "Navigation", "Zoom out", v, v.zoomOut, Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("c", "Navigation", "Center image", v, v.centerImage, Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("h", "Navigation", "Toggle hud", v, v.toggleHud, Qt.WidgetShortcut)) # FIXME: The nextChannel/previousChannel functions don't work right now. #self.shortcuts.append(self._shortcutHelper("q", "Navigation", "Switch to next channel", v, self.editor.nextChannel, Qt.WidgetShortcut)) #self.shortcuts.append(self._shortcutHelper("a", "Navigation", "Switch to previous channel", v, self.editor.previousChannel, Qt.WidgetShortcut)) def sliceDelta(axis, delta): newPos = copy.copy(self.editor.posModel.slicingPos) newPos[axis] += delta newPos[axis] = max(0, newPos[axis]) newPos[axis] = min(self.editor.posModel.shape[axis] - 1, newPos[axis]) self.editor.posModel.slicingPos = newPos def jumpToFirstSlice(axis): newPos = copy.copy(self.editor.posModel.slicingPos) newPos[axis] = 0 self.editor.posModel.slicingPos = newPos def jumpToLastSlice(axis): newPos = copy.copy(self.editor.posModel.slicingPos) newPos[axis] = self.editor.posModel.shape[axis] - 1 self.editor.posModel.slicingPos = newPos # TODO: Fix this dependency on ImageView/HUD internals self.shortcuts.append( self._shortcutHelper("Ctrl+Up", "Navigation", "Slice up", v, partial(sliceDelta, i, 1), Qt.WidgetShortcut, widget=v.hud.buttons['slice'].upLabel)) self.shortcuts.append( self._shortcutHelper("Ctrl+Down", "Navigation", "Slice down", v, partial(sliceDelta, i, -1), Qt.WidgetShortcut, widget=v.hud.buttons['slice'].downLabel)) # self.shortcuts.append(self._shortcutHelper("p", "Navigation", "Slice up (alternate shortcut)", v, partial(sliceDelta, i, 1), Qt.WidgetShortcut)) # self.shortcuts.append(self._shortcutHelper("o", "Navigation", "Slice down (alternate shortcut)", v, partial(sliceDelta, i, -1), Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("Ctrl+Shift+Up", "Navigation", "10 slices up", v, partial(sliceDelta, i, 10), Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("Ctrl+Shift+Down", "Navigation", "10 slices down", v, partial(sliceDelta, i, -10), Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("Shift+Up", "Navigation", "Jump to first slice", v, partial(jumpToFirstSlice, i), Qt.WidgetShortcut)) self.shortcuts.append( self._shortcutHelper("Shift+Down", "Navigation", "Jump to last slice", v, partial(jumpToLastSlice, i), Qt.WidgetShortcut)) def _updateInfoLabels(self, pos): self.quadViewStatusBar.setMouseCoords(*pos) def eventFilter(self, watched, event): # If the user performs a ctrl+scroll on the splitter itself, # scroll all views. if event.type() == QEvent.Wheel and (event.modifiers() == Qt.ControlModifier): for view in self.editor.imageViews: if event.delta() > 0: view.zoomIn() else: view.zoomOut() return True return False def getViewMenu(self, debug_mode=False): """ Return a QMenu with a set of actions for our editor. """ if self._viewMenu is None: self._initViewMenu() for action in self._debugActions: action.setEnabled(debug_mode) action.setVisible(debug_mode) return self._viewMenu def _initViewMenu(self): self._viewMenu = QMenu("View", parent=self) self._viewMenu.setObjectName("view_menu") self._debugActions = [] # This action is saved as a member so it can be triggered from tests self._viewMenu.actionFitToScreen = self._viewMenu.addAction( "&Zoom to &fit") self._viewMenu.actionFitToScreen.triggered.connect(self._fitToScreen) def toggleHud(): hide = not self.editor.imageViews[0]._hud.isVisible() for v in self.editor.imageViews: v.setHudVisible(hide) # This action is saved as a member so it can be triggered from tests self._viewMenu.actionToggleAllHuds = self._viewMenu.addAction( "Toggle huds") self._viewMenu.actionToggleAllHuds.triggered.connect(toggleHud) def resetAllAxes(): for s in self.editor.imageScenes: s.resetAxes() self._viewMenu.addAction("Reset all axes").triggered.connect( resetAllAxes) def centerAllImages(): for v in self.editor.imageViews: v.centerImage() self._viewMenu.addAction("Center images").triggered.connect( centerAllImages) def toggleDebugPatches(show): self.editor.showDebugPatches = show actionShowTiling = self._viewMenu.addAction("Show Tiling") actionShowTiling.setCheckable(True) actionShowTiling.toggled.connect(toggleDebugPatches) qsd = QShortcut(QKeySequence("Ctrl+D"), self, member=actionShowTiling.toggle, context=Qt.WidgetShortcut) ShortcutManager().register("Navigation", "Show tiling", qsd) self._debugActions.append(actionShowTiling) def setCacheSize(cache_size): dlg = QDialog(self) layout = QHBoxLayout() layout.addWidget(QLabel("Cached Slices Per View:")) cache_size = [self.editor.cacheSize] def parseCacheSize(strSize): # TODO: Use a QValidator to make sure the user always gives a number try: cache_size[0] = int(strSize) except: pass edit = QLineEdit(str(cache_size[0]), parent=dlg) edit.textChanged.connect(parseCacheSize) layout.addWidget(edit) okButton = QPushButton("OK", parent=dlg) okButton.clicked.connect(dlg.accept) layout.addWidget(okButton) dlg.setLayout(layout) dlg.setModal(True) dlg.exec_() self.editor.cacheSize = cache_size[0] self._viewMenu.addAction("Set layer cache size").triggered.connect( setCacheSize) def enablePrefetching(enable): for scene in self.editor.imageScenes: scene.setPrefetchingEnabled(enable) actionUsePrefetching = self._viewMenu.addAction("Use prefetching") actionUsePrefetching.setCheckable(True) actionUsePrefetching.toggled.connect(enablePrefetching) def blockGuiForRendering(): for v in self.editor.imageViews: v.scene().joinRenderingAllTiles() v.repaint() QApplication.processEvents() actionBlockGui = self._viewMenu.addAction("Block for rendering") actionBlockGui.triggered.connect(blockGuiForRendering) qsw = QShortcut(QKeySequence("Ctrl+B"), self, member=actionBlockGui.trigger, context=Qt.WidgetShortcut) ShortcutManager().register("Navigation", "Block gui for rendering", qsw) self._debugActions.append(actionBlockGui) # ------ Separator ------ self._viewMenu.addAction("").setSeparator(True) # Text only actionOnlyForSelectedView = self._viewMenu.addAction( "Only for selected view") actionOnlyForSelectedView.setIconVisibleInMenu(True) font = actionOnlyForSelectedView.font() font.setItalic(True) font.setBold(True) actionOnlyForSelectedView.setFont(font) def setCurrentAxisIcon(): """Update the icon that shows the currently selected axis.""" actionOnlyForSelectedView.setIcon( QIcon(self.editor.imageViews[ self.editor._lastImageViewFocus]._hud.axisLabel.pixmap())) self.editor.newImageView2DFocus.connect(setCurrentAxisIcon) setCurrentAxisIcon() actionFitImage = self._viewMenu.addAction("Fit image") actionFitImage.triggered.connect(self._fitImage) qsa = QShortcut(QKeySequence("K"), self, member=actionFitImage.trigger, context=Qt.WidgetShortcut) ShortcutManager().register("Navigation", "Fit image on screen", qsa) def toggleSelectedHud(): self.editor.imageViews[self.editor._lastImageViewFocus].toggleHud() actionToggleSelectedHud = self._viewMenu.addAction("Toggle hud") actionToggleSelectedHud.triggered.connect(toggleSelectedHud) def resetAxes(): self.editor.imageScenes[ self.editor._lastImageViewFocus].resetAxes() self._viewMenu.addAction("Reset axes").triggered.connect(resetAxes) def centerImage(): self.editor.imageViews[ self.editor._lastImageViewFocus].centerImage() actionCenterImage = self._viewMenu.addAction("Center image") actionCenterImage.triggered.connect(centerImage) qsc = QShortcut(QKeySequence("C"), self, member=actionCenterImage.trigger, context=Qt.WidgetShortcut) ShortcutManager().register("Navigation", "Center image", qsc) def restoreImageToOriginalSize(): self.editor.imageViews[self.editor._lastImageViewFocus].doScaleTo() actionResetZoom = self._viewMenu.addAction("Reset zoom") actionResetZoom.triggered.connect(restoreImageToOriginalSize) qsw = QShortcut(QKeySequence("W"), self, member=actionResetZoom.trigger, context=Qt.WidgetShortcut) ShortcutManager().register("Navigation", "Reset zoom", qsw) def updateHudActions(): dataShape = self.editor.dataShape # if the image is 2D, do not show the HUD action (issue #190) is2D = numpy.sum(numpy.asarray(dataShape[1:4]) == 1) == 1 actionToggleSelectedHud.setVisible(not is2D) self._viewMenu.actionToggleAllHuds.setVisible(not is2D) self.editor.shapeChanged.connect(updateHudActions)
def main(icon_spec): app = QApplication(sys.argv) main_window = QMainWindow() def sigint_handler(*args): main_window.close() signal.signal(signal.SIGINT, sigint_handler) # the timer enables triggering the sigint_handler signal_timer = QTimer() signal_timer.start(100) signal_timer.timeout.connect(lambda: None) tool_bar = QToolBar() main_window.addToolBar(Qt.TopToolBarArea, tool_bar) table_view = QTableView() table_view.setSelectionBehavior(QAbstractItemView.SelectRows) table_view.setSelectionMode(QAbstractItemView.SingleSelection) table_view.setSortingEnabled(True) main_window.setCentralWidget(table_view) proxy_model = QSortFilterProxyModel() proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) proxy_model.setFilterKeyColumn(1) table_view.setModel(proxy_model) proxy_model.layoutChanged.connect(table_view.resizeRowsToContents) item_model = QStandardItemModel() proxy_model.setSourceModel(item_model) # get all icons and their available sizes QIcon.setThemeName("gnome") icons = [] all_sizes = set([]) for context, icon_names in icon_spec: for icon_name in icon_names: icon = QIcon.fromTheme(icon_name) sizes = [] for size in icon.availableSizes(): size = (size.width(), size.height()) sizes.append(size) all_sizes.add(size) sizes.sort() icons.append({ 'context': context, 'icon_name': icon_name, 'icon': icon, 'sizes': sizes, }) all_sizes = list(all_sizes) all_sizes.sort() # input field for filter def filter_changed(value): proxy_model.setFilterRegExp(value) table_view.resizeRowsToContents() filter_line_edit = QLineEdit() filter_line_edit.setMaximumWidth(200) filter_line_edit.setPlaceholderText('Filter name') filter_line_edit.setToolTip( 'Filter name optionally using regular expressions (' + QKeySequence(QKeySequence.Find).toString() + ')') filter_line_edit.textChanged.connect(filter_changed) tool_bar.addWidget(filter_line_edit) # actions to toggle visibility of available sizes/columns def action_toggled(index): column = 2 + index table_view.setColumnHidden(column, not table_view.isColumnHidden(column)) table_view.resizeColumnsToContents() table_view.resizeRowsToContents() signal_mapper = QSignalMapper() for i, size in enumerate(all_sizes): action = QAction('%dx%d' % size, tool_bar) action.setCheckable(True) action.setChecked(True) tool_bar.addAction(action) action.toggled.connect(signal_mapper.map) signal_mapper.setMapping(action, i) # set tool tip and handle key sequence tool_tip = 'Toggle visibility of column' if i < 10: digit = ('%d' % (i + 1))[-1] tool_tip += ' (%s)' % QKeySequence('Ctrl+%s' % digit).toString() action.setToolTip(tool_tip) signal_mapper.mapped.connect(action_toggled) # label columns header_labels = ['context', 'name'] for width, height in all_sizes: header_labels.append('%dx%d' % (width, height)) item_model.setColumnCount(len(header_labels)) item_model.setHorizontalHeaderLabels(header_labels) # fill rows item_model.setRowCount(len(icons)) for row, icon_data in enumerate(icons): # context item = QStandardItem(icon_data['context']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 0, item) # icon name item = QStandardItem(icon_data['icon_name']) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, 1, item) for index_in_all_sizes, size in enumerate(all_sizes): column = 2 + index_in_all_sizes if size in icon_data['sizes']: # icon as pixmap to keep specific size item = QStandardItem('') pixmap = icon_data['icon'].pixmap(size[0], size[1]) item.setData(pixmap, Qt.DecorationRole) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) else: # single space to be sortable against icons item = QStandardItem(' ') item.setFlags(item.flags() ^ Qt.ItemIsEditable) item_model.setItem(row, column, item) table_view.resizeColumnsToContents() # manually set row heights because resizeRowsToContents is not working properly for row, icon_data in enumerate(icons): if len(icon_data['sizes']) > 0: max_size = icon_data['sizes'][-1] table_view.setRowHeight(row, max_size[1]) # enable focus find (ctrl+f) and toggle columns (ctrl+NUM) def main_window_keyPressEvent(self, event, old_keyPressEvent=QMainWindow.keyPressEvent): if event.matches(QKeySequence.Find): filter_line_edit.setFocus() return if event.modifiers() == Qt.ControlModifier and event.key( ) >= Qt.Key_0 and event.key() <= Qt.Key_9: index = event.key() - Qt.Key_1 if event.key() == Qt.Key_0: index += 10 action = signal_mapper.mapping(index) if action: action.toggle() return old_keyPressEvent(self, event) main_window.keyPressEvent = new.instancemethod(main_window_keyPressEvent, table_view, None) # enable copy (ctrl+c) name of icon to clipboard def table_view_keyPressEvent(self, event, old_keyPressEvent=QTableView.keyPressEvent): if event.matches(QKeySequence.Copy): selection_model = self.selectionModel() if selection_model.hasSelection(): index = selection_model.selectedRows()[0] source_index = self.model().mapToSource(index) item = self.model().sourceModel().item(source_index.row(), 1) icon_name = item.data(Qt.EditRole) app.clipboard().setText(icon_name.toString()) return old_keyPressEvent(self, event) table_view.keyPressEvent = new.instancemethod(table_view_keyPressEvent, table_view, None) print 'Icon Theme: ', QIcon.themeName() print 'Theme Search Paths:' for item in QIcon.themeSearchPaths(): print item main_window.showMaximized() return app.exec_()
class ShapeTools: def __init__(self, iface): self.iface = iface self.canvas = iface.mapCanvas() self.settingsDialog = None self.shapeDialog = None self.xyLineDialog = None self.geodesicDensifyDialog = None self.toolbar = self.iface.addToolBar(u'Shape Tools Toolbar') self.toolbar.setObjectName(u'ShapeToolsToolbar') if processingOk: self.provider = ShapeToolsProvider() def initGui(self): # Initialize the create shape menu item icon = QIcon(os.path.dirname(__file__) + '/images/shapes.png') self.shapeAction = QAction(icon, u'Create Shapes', self.iface.mainWindow()) self.shapeAction.triggered.connect(self.shapeTool) self.iface.addPluginToVectorMenu(u'Shape Tools', self.shapeAction) self.toolbar.addAction(self.shapeAction) # Initialize the XY to Line menu item icon = QIcon(os.path.dirname(__file__) + '/images/xyline.png') self.xyLineAction = QAction(icon, u'XY to Line', self.iface.mainWindow()) self.xyLineAction.triggered.connect(self.xyLineTool) self.iface.addPluginToVectorMenu(u'Shape Tools', self.xyLineAction) self.toolbar.addAction(self.xyLineAction) # Initialize the Geodesic Densifier menu item icon = QIcon(os.path.dirname(__file__) + '/images/geodesicDensifier.png') self.geodesicDensifyAction = QAction(icon, u'Geodesic Shape Densifier', self.iface.mainWindow()) self.geodesicDensifyAction.triggered.connect(self.geodesicDensifyTool) self.iface.addPluginToVectorMenu(u'Shape Tools', self.geodesicDensifyAction) self.toolbar.addAction(self.geodesicDensifyAction) # Initialize Geodesic Measure Tool self.geodesicMeasureTool = GeodesicMeasureTool(self.iface, self.iface.mainWindow()) self.canvas.mapToolSet.connect(self.unsetTool) icon = QIcon(os.path.dirname(__file__) + '/images/measure.png') self.measureAction = QAction(icon, u'Geodesic Measure Tool', self.iface.mainWindow()) self.measureAction.triggered.connect(self.measureTool) self.measureAction.setCheckable(True) self.iface.addPluginToVectorMenu(u'Shape Tools', self.measureAction) self.toolbar.addAction(self.measureAction) # Settings icon = QIcon(os.path.dirname(__file__) + '/images/settings.png') self.settingsAction = QAction(icon, u'Settings', self.iface.mainWindow()) self.settingsAction.triggered.connect(self.settings) self.iface.addPluginToVectorMenu(u'Shape Tools', self.settingsAction) # Help icon = QIcon(os.path.dirname(__file__) + '/images/help.png') self.helpAction = QAction(icon, u'Shape Tools Help', self.iface.mainWindow()) self.helpAction.triggered.connect(self.help) self.iface.addPluginToVectorMenu(u'Shape Tools', self.helpAction) if processingOk: Processing.addProvider(self.provider) def unsetTool(self, tool): try: if not isinstance(tool, GeodesicMeasureTool): self.measureAction.setChecked(False) self.geodesicMeasureTool.closeDialog() except: pass def unload(self): # remove from menu self.iface.removePluginVectorMenu(u'Shape Tools', self.shapeAction) self.iface.removePluginVectorMenu(u'Shape Tools', self.xyLineAction) self.iface.removePluginVectorMenu(u'Shape Tools', self.geodesicDensifyAction) self.iface.removePluginVectorMenu(u'Shape Tools', self.measureAction) self.iface.removePluginVectorMenu(u'Shape Tools', self.settingsAction) self.iface.removePluginVectorMenu(u'Shape Tools', self.helpAction) # Remove from toolbar self.iface.removeToolBarIcon(self.shapeAction) self.iface.removeToolBarIcon(self.xyLineAction) self.iface.removeToolBarIcon(self.geodesicDensifyAction) self.iface.removeToolBarIcon(self.measureAction) # remove the toolbar del self.toolbar if processingOk: Processing.removeProvider(self.provider) def shapeTool(self): if self.shapeDialog is None: self.shapeDialog = Vector2ShapeWidget(self.iface, self.iface.mainWindow()) self.shapeDialog.show() def xyLineTool(self): if self.xyLineDialog is None: self.xyLineDialog = XYToLineWidget(self.iface, self.iface.mainWindow()) self.xyLineDialog.show() def geodesicDensifyTool(self): if self.geodesicDensifyDialog is None: self.geodesicDensifyDialog = GeodesicDensifyWidget(self.iface, self.iface.mainWindow()) self.geodesicDensifyDialog.show() def measureTool(self): self.measureAction.setChecked(True) self.canvas.setMapTool(self.geodesicMeasureTool) def settings(self): if self.settingsDialog is None: self.settingsDialog = SettingsWidget(self.iface, self.iface.mainWindow()) self.settingsDialog.show() def help(self): '''Display a help page''' url = QUrl.fromLocalFile(os.path.dirname(__file__) + '/index.html').toString() webbrowser.open(url, new=2)
class Plugin(object): """The QGIS interface implementation for the InaSAFE plugin. This class acts as the 'glue' between QGIS and our custom logic. It creates a toolbar and menu bar entry and launches the InaSAFE user interface if these are activated. """ def __init__(self, iface): """Class constructor. On instantiation, the plugin instance will be assigned a copy of the QGIS iface object which will allow this plugin to access and manipulate the running QGIS instance that spawned it. :param iface:Quantum GIS iface instance. This instance is automatically passed to the plugin by QGIS when it loads the plugin. :type iface: QGisAppInterface """ # Save reference to the QGIS interface self.iface = iface self.dock_widget = None self.action_import_dialog = None self.action_save_scenario = None self.action_batch_runner = None self.action_shake_converter = None self.action_minimum_needs = None self.action_global_minimum_needs = None self.action_impact_merge_dlg = None self.key_action = None self.action_options = None self.action_keywords_dialog = None self.action_keywords_wizard = None self.action_function_centric_wizard = None self.action_extent_selector = None self.translator = None self.toolbar = None self.actions = [] # list of all QActions we create for InaSAFE self.action_dock = None self.action_toggle_rubberbands = None self.message_bar_item = None # Flag indicating if toolbar should show only common icons or not self.full_toolbar = False # print self.tr('InaSAFE') # For enable/disable the keyword editor icon self.iface.currentLayerChanged.connect(self.layer_changed) # noinspection PyArgumentList def change_i18n(self, new_locale): """Change internationalisation for the plugin. Override the system locale and then see if we can get a valid translation file for whatever locale is effectively being used. :param new_locale: the new locale i.e. 'id', 'af', etc. :type new_locale: str :raises: TranslationLoadException """ os.environ['INASAFE_LANG'] = str(new_locale) LOGGER.debug('%s %s %s' % ( new_locale, QLocale.system().name(), os.environ['INASAFE_LANG'])) root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) translation_path = os.path.join( root, 'safe_qgis', 'i18n', 'inasafe_' + str(new_locale) + '.qm') if os.path.exists(translation_path): self.translator = QTranslator() result = self.translator.load(translation_path) if not result: message = 'Failed to load translation for %s' % new_locale raise TranslationLoadError(message) # noinspection PyTypeChecker,PyCallByClass QCoreApplication.installTranslator(self.translator) LOGGER.debug('%s %s' % ( translation_path, os.path.exists(translation_path))) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('Plugin', message) def add_action(self, action, add_to_toolbar=True): """Add a toolbar icon to the InaSAFE toolbar. :param action: The action that should be added to the toolbar. :type action: QAction :param add_to_toolbar: Flag indicating whether the action should also be added to the InaSAFE toolbar. Defaults to True. :type add_to_toolbar: bool """ # store in the class list of actions for easy plugin unloading self.actions.append(action) self.iface.addPluginToMenu(self.tr('InaSAFE'), action) if add_to_toolbar: self.toolbar.addAction(action) # noinspection PyPep8Naming def initGui(self): """Gui initialisation procedure (for QGIS plugin api). .. note:: Don't change the name of this method from initGui! This method is called by QGIS and should be used to set up any graphical user interface elements that should appear in QGIS by default (i.e. before the user performs any explicit action with the plugin). """ self.toolbar = self.iface.addToolBar('InaSAFE') self.toolbar.setObjectName('InaSAFEToolBar') # Import dock here as it needs to be imported AFTER i18n is set up from safe.gui.widgets.dock import Dock self.dock_widget = None # -------------------------------------- # Create action for plugin dockable window (show/hide) # -------------------------------------- # pylint: disable=W0201 icon = resources_path('img', 'icons', 'icon.svg') self.action_dock = QAction( QIcon(icon), self.tr('Toggle InaSAFE Dock'), self.iface.mainWindow()) self.action_dock.setObjectName('InaSAFEDockToggle') self.action_dock.setStatusTip(self.tr( 'Show/hide InaSAFE dock widget')) self.action_dock.setWhatsThis(self.tr( 'Show/hide InaSAFE dock widget')) self.action_dock.setCheckable(True) self.action_dock.setChecked(True) self.action_dock.triggered.connect(self.toggle_dock_visibility) self.add_action(self.action_dock) # -------------------------------------- # Create action for keywords editor # -------------------------------------- icon = resources_path('img', 'icons', 'show-keyword-editor.svg') self.action_keywords_dialog = QAction( QIcon(icon), self.tr('InaSAFE Keyword Editor'), self.iface.mainWindow()) self.action_keywords_dialog.setStatusTip(self.tr( 'Open InaSAFE keywords editor')) self.action_keywords_dialog.setWhatsThis(self.tr( 'Open InaSAFE keywords editor')) self.action_keywords_dialog.setEnabled(False) self.action_keywords_dialog.triggered.connect( self.show_keywords_editor) self.add_action( self.action_keywords_dialog, add_to_toolbar=self.full_toolbar) # -------------------------------------- # Create action for keywords creation wizard # ------------------------------------- icon = resources_path('img', 'icons', 'show-keyword-wizard.svg') self.action_keywords_wizard = QAction( QIcon(icon), self.tr('InaSAFE Keywords Creation Wizard'), self.iface.mainWindow()) self.action_keywords_wizard.setStatusTip(self.tr( 'Open InaSAFE keywords creation wizard')) self.action_keywords_wizard.setWhatsThis(self.tr( 'Open InaSAFE keywords creation wizard')) self.action_keywords_wizard.setEnabled(False) self.action_keywords_wizard.triggered.connect( self.show_keywords_wizard) self.add_action(self.action_keywords_wizard) # -------------------------------------- # Create action for IF-centric wizard # -------------------------------------- icon = resources_path('img', 'icons', 'show-wizard.svg') self.action_function_centric_wizard = QAction( QIcon(icon), self.tr('InaSAFE Impact Function Centric Wizard'), self.iface.mainWindow()) self.action_function_centric_wizard.setStatusTip(self.tr( 'Open InaSAFE impact function centric wizard')) self.action_function_centric_wizard.setWhatsThis(self.tr( 'Open InaSAFE impact function centric wizard')) self.action_function_centric_wizard.setEnabled(True) self.action_function_centric_wizard.triggered.connect( self.show_function_centric_wizard) self.add_action(self.action_function_centric_wizard) # -------------------------------------- # Create action for options dialog # -------------------------------------- icon = resources_path('img', 'icons', 'configure-inasafe.svg') self.action_options = QAction( QIcon(icon), self.tr('InaSAFE Options'), self.iface.mainWindow()) self.action_options.setStatusTip(self.tr( 'Open InaSAFE options dialog')) self.action_options.setWhatsThis(self.tr( 'Open InaSAFE options dialog')) self.action_options.triggered.connect(self.show_options) self.add_action(self.action_options, add_to_toolbar=self.full_toolbar) # --------------------------------------- # Create action for minimum needs dialog # --------------------------------------- icon = resources_path('img', 'icons', 'show-minimum-needs.svg') self.action_minimum_needs = QAction( QIcon(icon), self.tr('InaSAFE Minimum Needs Tool'), self.iface.mainWindow()) self.action_minimum_needs.setStatusTip(self.tr( 'Open InaSAFE minimum needs tool')) self.action_minimum_needs.setWhatsThis(self.tr( 'Open InaSAFE minimum needs tool')) self.action_minimum_needs.triggered.connect(self.show_minimum_needs) self.add_action( self.action_minimum_needs, add_to_toolbar=self.full_toolbar) # ---------------------------------------------- # Create action for global minimum needs dialog # ---------------------------------------------- icon = resources_path('img', 'icons', 'show-global-minimum-needs.svg') self.action_global_minimum_needs = QAction( QIcon(icon), self.tr('InaSAFE Global Minimum Needs Configuration'), self.iface.mainWindow()) self.action_global_minimum_needs.setStatusTip(self.tr( 'Open InaSAFE global minimum needs configuration')) self.action_global_minimum_needs.setWhatsThis(self.tr( 'Open InaSAFE global minimum needs configuration')) self.action_global_minimum_needs.triggered.connect( self.show_global_minimum_needs_configuration) self.add_action( self.action_global_minimum_needs, add_to_toolbar=self.full_toolbar) # --------------------------------------- # Create action for converter dialog # --------------------------------------- icon = resources_path('img', 'icons', 'show-converter-tool.svg') self.action_shake_converter = QAction( QIcon(icon), self.tr('InaSAFE Converter'), self.iface.mainWindow()) self.action_shake_converter.setStatusTip(self.tr( 'Open InaSAFE Converter')) self.action_shake_converter.setWhatsThis(self.tr( 'Open InaSAFE Converter')) self.action_shake_converter.triggered.connect( self.show_shakemap_importer) self.add_action( self.action_shake_converter, add_to_toolbar=self.full_toolbar) # --------------------------------------- # Create action for batch runner dialog # --------------------------------------- icon = resources_path('img', 'icons', 'show-batch-runner.svg') self.action_batch_runner = QAction( QIcon(icon), self.tr('InaSAFE Batch Runner'), self.iface.mainWindow()) self.action_batch_runner.setStatusTip(self.tr( 'Open InaSAFE Batch Runner')) self.action_batch_runner.setWhatsThis(self.tr( 'Open InaSAFE Batch Runner')) self.action_batch_runner.triggered.connect(self.show_batch_runner) self.add_action( self.action_batch_runner, add_to_toolbar=self.full_toolbar) # --------------------------------------- # Create action for save scenario dialog # --------------------------------------- icon = resources_path('img', 'icons', 'save-as-scenario.svg') self.action_save_scenario = QAction( QIcon(icon), self.tr('Save current scenario'), self.iface.mainWindow()) message = self.tr('Save current scenario to text file') self.action_save_scenario.setStatusTip(message) self.action_save_scenario.setWhatsThis(message) # noinspection PyUnresolvedReferences self.action_save_scenario.triggered.connect(self.save_scenario) self.add_action( self.action_save_scenario, add_to_toolbar=self.full_toolbar) # -------------------------------------- # Create action for import OSM Dialog # -------------------------------------- icon = resources_path('img', 'icons', 'show-osm-download.svg') self.action_import_dialog = QAction( QIcon(icon), self.tr('InaSAFE OpenStreetMap Downloader'), self.iface.mainWindow()) self.action_import_dialog.setStatusTip(self.tr( 'InaSAFE OpenStreetMap Downloader')) self.action_import_dialog.setWhatsThis(self.tr( 'InaSAFE OpenStreetMap Downloader')) self.action_import_dialog.triggered.connect(self.show_osm_downloader) self.add_action(self.action_import_dialog) # -------------------------------------- # Create action for impact layer merge Dialog # -------------------------------------- icon = resources_path('img', 'icons', 'show-impact-merge.svg') self.action_impact_merge_dlg = QAction( QIcon(icon), self.tr('InaSAFE Impact Layer Merge'), self.iface.mainWindow()) self.action_impact_merge_dlg.setStatusTip(self.tr( 'InaSAFE Impact Layer Merge')) self.action_impact_merge_dlg.setWhatsThis(self.tr( 'InaSAFE Impact Layer Merge')) self.action_impact_merge_dlg.triggered.connect(self.show_impact_merge) self.add_action( self.action_impact_merge_dlg, add_to_toolbar=self.full_toolbar) # -------------------------------------- # create dockwidget and tabify it with the legend # -------------------------------------- self.dock_widget = Dock(self.iface) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock_widget) myLegendTab = self.iface.mainWindow().findChild(QApplication, 'Legend') if myLegendTab: self.iface.mainWindow().tabifyDockWidget( myLegendTab, self.dock_widget) self.dock_widget.raise_() # # Hook up a slot for when the dock is hidden using its close button # or view-panels # self.dock_widget.visibilityChanged.connect(self.toggle_inasafe_action) # Also deal with the fact that on start of QGIS dock may already be # hidden. self.action_dock.setChecked(self.dock_widget.isVisible()) # pylint: disable=W0201 # --------------------------------------- # Create action for toggling rubber bands # --------------------------------------- icon = resources_path('img', 'icons', 'toggle-rubber-bands.svg') self.action_toggle_rubberbands = QAction( QIcon(icon), self.tr('Toggle scenario outlines'), self.iface.mainWindow()) message = self.tr('Toggle rubber bands showing scenarion extents.') self.action_toggle_rubberbands.setStatusTip(message) self.action_toggle_rubberbands.setWhatsThis(message) # Set initial state self.action_toggle_rubberbands.setCheckable(True) settings = QSettings() flag = bool(settings.value( 'inasafe/showRubberBands', False, type=bool)) self.action_toggle_rubberbands.setChecked(flag) # noinspection PyUnresolvedReferences self.action_toggle_rubberbands.triggered.connect( self.dock_widget.toggle_rubber_bands) self.add_action(self.action_toggle_rubberbands) # --------------------------------------- # Create action for analysis extent dialog # --------------------------------------- icon = resources_path('img', 'icons', 'set-extents-tool.svg') self.action_extent_selector = QAction( QIcon(icon), self.tr('Set the analysis area for InaSAFE'), self.iface.mainWindow()) self.action_extent_selector.setStatusTip(self.tr( 'Set the analysis area for InaSAFE')) self.action_extent_selector.setWhatsThis(self.tr( 'Set the analysis area for InaSAFE')) self.action_extent_selector.triggered.connect( self.show_extent_selector) self.add_action(self.action_extent_selector) # noinspection PyMethodMayBeStatic def clear_modules(self): """Unload inasafe functions and try to return QGIS to before InaSAFE. """ from safe.impact_functions import core core.unload_plugins() # next lets force remove any inasafe related modules modules = [] for module in sys.modules: if 'inasafe' in module: # Check if it is really one of our modules i.e. exists in the # plugin directory tokens = module.split('.') path = '' for myToken in tokens: path += os.path.sep + myToken parent = os.path.abspath(os.path.join( __file__, os.path.pardir, os.path.pardir)) full_path = os.path.join(parent, path + '.py') if os.path.exists(os.path.abspath(full_path)): LOGGER.debug('Removing: %s' % module) modules.append(module) for module in modules: del (sys.modules[module]) for module in sys.modules: if 'inasafe' in module: print module # Lets also clean up all the path additions that were made package_path = os.path.abspath(os.path.join( os.path.dirname(__file__), os.path.pardir)) LOGGER.debug('Path to remove: %s' % package_path) # We use a list comprehension to ensure duplicate entries are removed LOGGER.debug(sys.path) sys.path = [y for y in sys.path if package_path not in y] LOGGER.debug(sys.path) def unload(self): """GUI breakdown procedure (for QGIS plugin api). .. note:: Don't change the name of this method from unload! This method is called by QGIS and should be used to *remove* any graphical user interface elements that should appear in QGIS. """ # Remove the plugin menu item and icon for myAction in self.actions: self.iface.removePluginMenu(self.tr('InaSAFE'), myAction) self.iface.removeToolBarIcon(myAction) self.iface.mainWindow().removeDockWidget(self.dock_widget) self.iface.mainWindow().removeToolBar(self.toolbar) self.dock_widget.setVisible(False) self.dock_widget.destroy() self.iface.currentLayerChanged.disconnect(self.layer_changed) def toggle_inasafe_action(self, checked): """Check or un-check the toggle inaSAFE toolbar button. This slot is called when the user hides the inaSAFE panel using its close button or using view->panels. :param checked: True if the dock should be shown, otherwise False. :type checked: bool """ self.action_dock.setChecked(checked) # Run method that performs all the real work def toggle_dock_visibility(self): """Show or hide the dock widget.""" if self.dock_widget.isVisible(): self.dock_widget.setVisible(False) else: self.dock_widget.setVisible(True) self.dock_widget.raise_() def show_extent_selector(self): """Show the extent selector widget for defining analysis extents.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.extent_selector_dialog import ExtentSelectorDialog widget = ExtentSelectorDialog( self.iface, self.iface.mainWindow(), extent=self.dock_widget.extent.user_extent, crs=self.dock_widget.extent.user_extent_crs) widget.clear_extent.connect( self.dock_widget.extent.clear_user_analysis_extent) widget.extent_defined.connect( self.dock_widget.define_user_analysis_extent) # Needs to be non modal to support hide -> interact with map -> show widget.show() # non modal def show_minimum_needs(self): """Show the minimum needs dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.minimum_needs.needs_calculator_dialog import ( NeedsCalculatorDialog ) dialog = NeedsCalculatorDialog(self.iface.mainWindow()) dialog.show() # non modal def show_global_minimum_needs_configuration(self): """Show the minimum needs dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.minimum_needs.needs_manager_dialog import ( NeedsManagerDialog) dialog = NeedsManagerDialog(self.iface.mainWindow()) dialog.exec_() # modal def show_impact_merge(self): """Show the impact layer merge dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.impact_merge_dialog import ImpactMergeDialog dialog = ImpactMergeDialog(self.iface.mainWindow()) dialog.exec_() # modal def show_options(self): """Show the options dialog.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.options_dialog import OptionsDialog dialog = OptionsDialog( self.iface, self.dock_widget, self.iface.mainWindow()) dialog.exec_() # modal def show_keywords_editor(self): """Show the keywords editor.""" # import here only so that it is AFTER i18n set up from safe.gui.tools.keywords_dialog import KeywordsDialog # Next block is a fix for #776 if self.iface.activeLayer() is None: return try: keyword_io = KeywordIO() keyword_io.read_keywords(self.iface.activeLayer()) except UnsupportedProviderError: # noinspection PyUnresolvedReferences,PyCallByClass # noinspection PyTypeChecker,PyArgumentList QMessageBox.warning( None, self.tr('Unsupported layer type'), self.tr( 'The layer you have selected cannot be used for ' 'analysis because its data type is unsupported.')) return # End of fix for #776 # Fix for #793 except NoKeywordsFoundError: # we will create them from scratch in the dialog pass # End of fix for #793 # Fix for filtered-layer except InvalidParameterError, e: # noinspection PyTypeChecker,PyTypeChecker,PyArgumentList QMessageBox.warning( None, self.tr('Invalid Layer'), e.message ) return dialog = KeywordsDialog( self.iface.mainWindow(), self.iface, self.dock_widget) dialog.exec_() # modal
class PymetricsViewer(QWidget): " Pymetrics tab widget " # Limits to colorize the McCabe score LittleRiskLimit = 10 ModerateRiskLimit = 20 HighRiskLimit = 50 # Options of providing a report SingleFile = 0 DirectoryFiles = 1 ProjectFiles = 2 SingleBuffer = 3 def __init__(self, parent=None): QWidget.__init__(self, parent) self.__reportUUID = "" self.__reportFileName = "" self.__reportOption = -1 self.__reportShown = False self.__report = None # Prepare members for reuse self.__noneLabel = QLabel("\nNo results available") self.__noneLabel.setFrameShape(QFrame.StyledPanel) self.__noneLabel.setAlignment(Qt.AlignHCenter) self.__headerFont = self.__noneLabel.font() self.__headerFont.setPointSize(self.__headerFont.pointSize() + 4) self.__noneLabel.setFont(self.__headerFont) self.__noneLabel.setAutoFillBackground(True) noneLabelPalette = self.__noneLabel.palette() noneLabelPalette.setColor(QPalette.Background, GlobalData().skin.nolexerPaper) self.__noneLabel.setPalette(noneLabelPalette) self.__createLayout(parent) self.__updateButtonsStatus() return def __createLayout(self, parent): " Creates the toolbar and layout " # Buttons self.__mcCabeButton = QAction(PixmapCache().getIcon('tableview.png'), 'Switch to McCabe only table view', self) self.__mcCabeButton.setCheckable(True) self.connect(self.__mcCabeButton, SIGNAL('toggled(bool)'), self.__onMcCabe) self.printButton = QAction(PixmapCache().getIcon('printer.png'), 'Print', self) #printButton.setShortcut( 'Ctrl+' ) self.connect(self.printButton, SIGNAL('triggered()'), self.__onPrint) self.printButton.setVisible(False) self.printPreviewButton = QAction( PixmapCache().getIcon('printpreview.png'), 'Print preview', self) #printPreviewButton.setShortcut( 'Ctrl+' ) self.connect(self.printPreviewButton, SIGNAL('triggered()'), self.__onPrintPreview) self.printPreviewButton.setVisible(False) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear', self) self.connect(self.clearButton, SIGNAL('triggered()'), self.__clear) # The toolbar self.toolbar = QToolBar(self) self.toolbar.setOrientation(Qt.Vertical) self.toolbar.setMovable(False) self.toolbar.setAllowedAreas(Qt.RightToolBarArea) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.setFixedWidth(28) self.toolbar.setContentsMargins(0, 0, 0, 0) self.toolbar.addAction(self.__mcCabeButton) self.toolbar.addAction(self.printPreviewButton) self.toolbar.addAction(self.printButton) self.toolbar.addWidget(spacer) self.toolbar.addAction(self.clearButton) self.__totalResultsTree = QTreeWidget() self.__totalResultsTree.setAlternatingRowColors(True) self.__totalResultsTree.setRootIsDecorated(True) self.__totalResultsTree.setItemsExpandable(True) self.__totalResultsTree.setUniformRowHeights(True) self.__totalResultsTree.setItemDelegate(NoOutlineHeightDelegate(4)) headerLabels = ["Path / name", "Value", ""] self.__totalResultsTree.setHeaderLabels(headerLabels) self.connect(self.__totalResultsTree, SIGNAL("itemActivated(QTreeWidgetItem *, int)"), self.__allItemActivated) self.connect(self.__totalResultsTree, SIGNAL("itemExpanded(QTreeWidgetItem *)"), self.__onResultsExpanded) self.__totalResultsTree.setColumnHidden(2, True) self.__totalResultsTree.hide() self.__mcCabeTable = QTreeWidget() self.__mcCabeTable.setAlternatingRowColors(True) self.__mcCabeTable.setRootIsDecorated(False) self.__mcCabeTable.setItemsExpandable(False) self.__mcCabeTable.setSortingEnabled(True) self.__mcCabeTable.setItemDelegate(NoOutlineHeightDelegate(4)) self.__mcCabeTable.setUniformRowHeights(True) headerLabels = ["", "File name", "Object", "McCabe Complexity"] self.__mcCabeTable.setHeaderLabels(headerLabels) self.connect(self.__mcCabeTable, SIGNAL("itemActivated(QTreeWidgetItem *, int)"), self.__mcCabeActivated) self.__mcCabeTable.hide() self.__hLayout = QHBoxLayout() self.__hLayout.setContentsMargins(0, 0, 0, 0) self.__hLayout.setSpacing(0) self.__hLayout.addWidget(self.toolbar) self.__hLayout.addWidget(self.__noneLabel) self.__hLayout.addWidget(self.__totalResultsTree) self.__hLayout.addWidget(self.__mcCabeTable) self.setLayout(self.__hLayout) return def getTotalResultsWidget(self): " Provides a reference to the total results widget " return self.__totalResultsTree def getMcCabeResultsWidget(self): " Provides a reference to the McCabe results widget " return self.__mcCabeTable def __updateButtonsStatus(self): " Updates the buttons status " self.__mcCabeButton.setEnabled(self.__reportShown) self.printButton.setEnabled(self.__reportShown) self.printPreviewButton.setEnabled(self.__reportShown) self.clearButton.setEnabled(self.__reportShown) return def __onResultsExpanded(self, item): " An item has been expanded, so the column width should be adjusted " self.__totalResultsTree.header().resizeSections( QHeaderView.ResizeToContents) return def __onPrint(self): " Triggered when the print button is pressed " pass def __onPrintPreview(self): " triggered when the print preview button is pressed " pass def __onMcCabe(self, state): " Triggered when the metrics view is switched " if not self.__reportShown: return if state: self.__totalResultsTree.hide() self.__mcCabeTable.show() self.__mcCabeButton.setIcon(PixmapCache().getIcon('treeview.png')) self.__mcCabeButton.setToolTip("Switch to complete " "results tree view") else: self.__mcCabeTable.hide() self.__totalResultsTree.show() self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png')) self.__mcCabeButton.setToolTip("Switch to McCabe only table view") return def setFocus(self): " Overridden setFocus " self.__hLayout.setFocus() return def __clear(self): " Clears the content of the vertical layout " if not self.__reportShown: return self.__totalResultsTree.clear() self.__totalResultsTree.hide() self.__mcCabeTable.clear() self.__mcCabeTable.hide() self.__noneLabel.show() self.__report = None self.__reportShown = False self.__updateButtonsStatus() # self.resizeEvent() self.__mcCabeButton.setIcon(PixmapCache().getIcon('tableview.png')) self.__mcCabeButton.setToolTip("Switch to McCabe only table view") self.__mcCabeButton.setChecked(False) self.__updateTooltip() return def __updateTooltip(self): " Generates a signal with appropriate string message " if not self.__reportShown: tooltip = "No metrics available" elif self.__reportOption == self.DirectoryFiles: tooltip = "Metrics generated for directory: " + \ self.__reportFileName elif self.__reportOption == self.ProjectFiles: tooltip = "Metrics generated for the whole project" elif self.__reportOption == self.SingleFile: tooltip = "Metrics generated for file: " + self.__reportFileName elif self.__reportOption == self.SingleBuffer: tooltip = "Metrics generated for unsaved file: " + \ self.__reportFileName else: tooltip = "" self.emit(SIGNAL('updatePymetricsTooltip'), tooltip) return @staticmethod def __shouldShowFileName(table, column): " Checks if the file name is the same " size = table.topLevelItemCount() if size == 0: return False index = size - 1 firstName = table.topLevelItem(index).text(column) index -= 1 while index >= 0: if table.topLevelItem(index).text(column) != firstName: return True index -= 1 return False def showReport(self, metrics, reportOption, fileName, uuid): " Shows the pymetrics results " self.__clear() self.__noneLabel.hide() self.__report = metrics self.__reportUUID = uuid self.__reportFileName = fileName self.__reportOption = reportOption if len(metrics.report) > 1: accumulatedBasic = self.__accumulateBasicMetrics() accItem = QTreeWidgetItem(["Cumulative basic metrics"]) self.__totalResultsTree.addTopLevelItem(accItem) for key in accumulatedBasic: bmItem = [ BasicMetrics.metricsOfInterest[key], splitThousands(str(accumulatedBasic[key])) ] basicMetric = QTreeWidgetItem(bmItem) accItem.addChild(basicMetric) # Add the complete information for fileName in metrics.report: if reportOption == self.SingleBuffer: fileItem = QTreeWidgetItem(["Editor buffer"]) else: fileItem = QTreeWidgetItem([fileName]) info = GlobalData().briefModinfoCache.get(fileName) if info.docstring is not None: fileItem.setToolTip(0, info.docstring.text) else: fileItem.setToolTip(0, "") self.__totalResultsTree.addTopLevelItem(fileItem) # Messages part messages = metrics.report[fileName].messages if len(messages) > 0: messagesItem = QTreeWidgetItem(["Messages"]) fileItem.addChild(messagesItem) for message in messages: mItem = [message, "", "E"] messagesItem.addChild(QTreeWidgetItem(mItem)) # Basic metrics part basicItem = QTreeWidgetItem(["Basic metrics"]) fileItem.addChild(basicItem) basic = metrics.report[fileName].basicMetrics for key in basic.metrics: bmItem = [ BasicMetrics.metricsOfInterest[key], str(basic.metrics[key]) ] basicMetric = QTreeWidgetItem(bmItem) basicItem.addChild(basicMetric) # McCabe part mccabeItem = QTreeWidgetItem(["McCabe metrics"]) fileItem.addChild(mccabeItem) mccabe = metrics.report[fileName].mcCabeMetrics.metrics for objName in mccabe: objItem = [objName, str(mccabe[objName]), "M"] mccabeMetric = QTreeWidgetItem(objItem) mccabeItem.addChild(mccabeMetric) # COCOMO 2 part cocomo = [ "COCOMO 2", str(metrics.report[fileName].cocomo2Metrics.value) ] cocomoItem = QTreeWidgetItem(cocomo) fileItem.addChild(cocomoItem) # Resizing the table self.__totalResultsTree.header().resizeSections( QHeaderView.ResizeToContents) # Add McCabe complexity information for fileName in metrics.report: mccabe = metrics.report[fileName].mcCabeMetrics.metrics for objName in mccabe: values = ["", fileName, objName, str(mccabe[objName])] self.__mcCabeTable.addTopLevelItem(McCabeTableItem(values)) if not self.__shouldShowFileName(self.__mcCabeTable, 1): self.__mcCabeTable.setColumnHidden(1, True) # Resizing and sorting the table self.__mcCabeTable.header().setSortIndicator(3, Qt.DescendingOrder) self.__mcCabeTable.sortItems( 3, self.__mcCabeTable.header().sortIndicatorOrder()) self.__mcCabeTable.header().resizeSections( QHeaderView.ResizeToContents) # Show the complete information self.__mcCabeTable.hide() self.__totalResultsTree.show() self.__reportShown = True self.__updateButtonsStatus() self.__updateTooltip() # It helps, but why do I have flickering? QApplication.processEvents() return def __accumulateBasicMetrics(self): " Accumulates basic metrics for all the processed files " basic = {} for fileName in self.__report.report: singleBasic = self.__report.report[fileName].basicMetrics.metrics for key in singleBasic: if not key.startswith('num'): continue if key in basic: basic[key] += int(singleBasic[key]) else: basic[key] = int(singleBasic[key]) return basic def __mcCabeActivated(self, item, column): " Handles the double click (or Enter) on the mccabe table item " objName = str(item.text(2)) if self.__reportOption == self.SingleBuffer: if os.path.isabs(self.__reportFileName): fileName = self.__reportFileName else: fileName = "" else: fileName = str(item.text(1)) self.__onMcCabeObject(objName, fileName) return def __allItemActivated(self, item, column): " Handles the double click (or Enter) in the total results tree " # We process only the error messages and McCabe items hiddenColumnText = str(item.text(2)) if not hiddenColumnText in ["M", "E"]: return fileName = self.__getTreeItemFileName(item) lineNumber = 0 if hiddenColumnText == "M": # This is McCabe item objName = str(item.text(0)) self.__onMcCabeObject(objName, fileName) return elif hiddenColumnText == "E": # This is an error message message = str(item.text(0)) pos = message.find("at line") if pos == -1: logging.error("Unknown format of the message. " "Please inform the developers.") return parts = message[pos:].split() try: lineNumber = int(parts[2].replace(',', '')) except: logging.error("Unknown format of the message. " "Please inform the developers.") return if fileName == "": # This is an unsaved buffer, try to find the editor by UUID mainWindow = GlobalData().mainWindow widget = mainWindow.getWidgetByUUID(self.__reportUUID) if widget is None: logging.error("The unsaved buffer has been closed") return # The widget was found, so jump to the required editor = widget.getEditor() editor.gotoLine(lineNumber) editor.setFocus() return GlobalData().mainWindow.openFile(fileName, lineNumber) return def __getTreeItemFileName(self, item): " Identifies the tree view item file name " if self.__reportOption == self.SingleBuffer: if os.path.isabs(self.__reportFileName): return self.__reportFileName return "" # The file name is always two levels up fileItem = item.parent().parent() return str(fileItem.text(0)) def __onMcCabeObject(self, objName, fileName): " Called when the user activated McCabe item " info = None mainWindow = GlobalData().mainWindow widget = mainWindow.getWidgetByUUID(self.__reportUUID) if widget is None: if fileName == "": logging.error("The unsaved buffer has been closed") return # No widget, but we know the file name info = getBriefModuleInfoFromFile(fileName) else: # The widget was found editor = widget.getEditor() # The editor content has been modified, so re-parse the buffer info = getBriefModuleInfoFromMemory(editor.text()) parts = objName.split('.') currentIndex = 0 functionsContainer = info.functions classesContainer = info.classes line = -1 if objName == "__main__" and len(parts) == 1: # Special case - global file scope line = 1 currentIndex = 1 while currentIndex < len(parts): found = False for func in functionsContainer: if func.name == parts[currentIndex]: if currentIndex == len(parts) - 1: # Found, jump to the line line = func.line break functionsContainer = func.functions classesContainer = func.classes found = True break if line != -1: break if found: currentIndex += 1 continue for klass in classesContainer: if klass.name == parts[currentIndex]: if currentIndex == len(parts) - 1: # Found, jump to the line line = klass.line break functionsContainer = klass.functions classesContainer = klass.classes found = True if line != -1: break if found: currentIndex += 1 continue # Not found logging.error("Cannot find the " + objName) return # Here we have the line number if widget is None: GlobalData().mainWindow.openFile(fileName, line) else: editor = widget.getEditor() editor.gotoLine(line) editor.setFocus() return def onFileUpdated(self, fileName, uuid): " Called when a buffer is saved or saved as " if not self.__reportShown: return if self.__reportUUID != uuid: return # Currently shown report is for the saved buffer # File name is expected being absolute self.__reportFileName = fileName self.emit(SIGNAL('updatePymetricsTooltip'), "Metrics generated for buffer saved as " + fileName) return
class QtAction(QtToolkitObject, ProxyAction): """ A Qt implementation of an Enaml ProxyAction. """ #: A reference to the widget created by the proxy. widget = Typed(QAction) #: Cyclic notification guard. This a bitfield of multiple guards. _guard = Int(0) # FIXME Currently, the checked state of the action is lost when # switching from checkable to non-checkable and back again. #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying QAction object. """ self.widget = QAction(self.parent_widget()) def init_widget(self): """ Initialize the underlying control. """ super(QtAction, self).init_widget() d = self.declaration if d.text: self.set_text(d.text) if d.tool_tip: self.set_tool_tip(d.tool_tip) if d.status_tip: self.set_status_tip(d.status_tip) if d.icon: self.set_icon(d.icon) self.set_checkable(d.checkable) self.set_checked(d.checked) self.set_enabled(d.enabled) self.set_visible(d.visible) self.set_separator(d.separator) widget = self.widget widget.triggered.connect(self.on_triggered) widget.toggled.connect(self.on_toggled) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_triggered(self, checked): """ The signal handler for the 'triggered' signal. """ if not self._guard & CHECKED_GUARD: self.declaration.checked = checked self.declaration.triggered(checked) def on_toggled(self, checked): """ The signal handler for the 'toggled' signal. """ if not self._guard & CHECKED_GUARD: self.declaration.checked = checked self.declaration.toggled(checked) #-------------------------------------------------------------------------- # ProxyAction API #-------------------------------------------------------------------------- def set_text(self, text): """ Set the text on the underlying control. """ widget = self.widget widget.setText(text) parts = text.split('\t') if len(parts) > 1: shortcut = QKeySequence(parts[-1]) widget.setShortcut(shortcut) def set_tool_tip(self, tool_tip): """ Set the tool tip on the underlying control. """ self.widget.setToolTip(tool_tip) def set_status_tip(self, status_tip): """ Set the status tip on the underyling control. """ self.widget.setStatusTip(status_tip) def set_icon(self, icon): """ Set the icon for the action. """ if icon: qicon = get_cached_qicon(icon) else: qicon = QIcon() self.widget.setIcon(qicon) def set_checkable(self, checkable): """ Set the checkable state on the underlying control. """ self.widget.setCheckable(checkable) def set_checked(self, checked): """ Set the checked state on the underlying control. """ self._guard |= CHECKED_GUARD try: self.widget.setChecked(checked) finally: self._guard &= ~CHECKED_GUARD def set_enabled(self, enabled): """ Set the enabled state on the underlying control. """ self.widget.setEnabled(enabled) def set_visible(self, visible): """ Set the visible state on the underlying control. """ self.widget.setVisible(visible) def set_separator(self, separator): """ Set the separator state on the underlying control. """ self.widget.setSeparator(separator)
class DockToolBar(QToolBar): dockWidgetAreaChanged = pyqtSignal(QDockWidget, QToolBar) def __init__(self, manager, orientation, window): QToolBar.__init__(self, window) assert (manager) self.manager = manager self.uniqueId = 0 self.__dockToButton = {} self.__buttonToDock = {} self.__buttonToAction = {} self.toggleViewAction().setEnabled(False) self.toggleViewAction().setVisible(False) self.textAlwaysVisible = True self.setMovable(False) self.aToggleExclusive = QAction(self) self.aToggleExclusive.setCheckable(True) self.aToggleExclusive.setChecked(True) self.aToggleExclusive.setIcon(Icons.exclusive) self.aToggleExclusive.setText("%s exclusive" % self.windowTitle()) self.aToggleExclusive.toggled.connect(self.__setExclusive) self.addAction(self.aToggleExclusive) self.setIconSize(QSize(16, 16)) self.setOrientation(orientation) docks = property(lambda self: self.__dockToButton.iterkeys()) count = property(lambda self: len(self.__dockToButton)) exclusive = property( lambda self: self.aToggleExclusive.isChecked(), lambda self, value: self.aToggleExclusive.setChecked(value)) def eventFilter(self, dock, event): type_ = event.type() if isinstance(dock, QDockWidget): if type_ == QEvent.Show or type_ == QEvent.Hide: if type_ == QEvent.Show and self.exclusive: self.__hideAllDocksBut(dock) btn = self.__dockToButton[dock] btn.setChecked(type_ == QEvent.Show) self.__checkVisibility() elif type_ == QEvent.KeyPress: if event.key() == Qt.Key_Escape: dock.hide() return QToolBar.eventFilter(self, dock, event) def hasDock(self, dock): return dock in self.__dockToButton def addDock(self, dock): if not dock: raise ValueError if self.hasDock(dock): return for tb in self.manager.bars.itervalues(): if tb.hasDock(dock): tb.removeDock(dock) # create button pb = RotatableToolButton( self, self.manager.toolBarAreaToBoxLayoutDirection( self.manager.main.toolBarArea(self))) pb.setCheckable(True) pb.setFont(self.font()) pb.setText(dock.windowTitle()) pb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) pb.setIconSize(self.iconSize()) pb.setIcon(dock.windowIcon()) pb.show() action = self.addWidget(pb) da = self.manager.main.dockWidgetArea(dock) ta = self.manager.toolBarAreaToDockWidgetArea( self.manager.main.toolBarArea(self)) if da != ta: self.manager.main.addDockWidget(ta, dock, self.orientation()) if self.exclusive and self.count: self.__hideAllDocksBut(None) pb.setChecked(dock.isVisible()) self.__buttonToDock[pb] = dock self.__dockToButton[dock] = pb self.__buttonToAction[pb] = action dock.installEventFilter(self) dock.toggleViewAction().changed.connect(self.__dockChanged) dock.alerted.connect(self.__dockAlerted) dock.windowTitleChanged.connect(self.__dockTitleChanged) dock.windowIconChanged.connect(self.__dockIconChanged) dock.destroyed.connect(self.__dockDestroyed) pb.clicked.connect(self.__buttonClicked) self.__checkVisibility() def removeDock(self, dock): if not isinstance(dock, QDockWidget): raise ValueError if not self.hasDock(dock): return dock.removeEventFilter(self) dock.toggleViewAction().changed.disconnect(self.__dockChanged) dock.alerted.disconnect(self.__dockAlerted) dock.windowTitleChanged.disconnect(self.__dockTitleChanged) dock.windowIconChanged.disconnect(self.__dockIconChanged) dock.destroyed.disconnect(self.__dockDestroyed) btn = self.__dockToButton[dock] self.removeAction(self.__buttonToAction[btn]) btn.deleteLater() del self.__dockToButton[dock] del self.__buttonToDock[btn] self.__checkVisibility() def __setExclusive(self): toShow = None for dw in self.docks: if dw.visible: if toShow: toShow = None break else: toShow = dw if self.exclusive: self.__hideAllDocksBut(toShow) def __checkVisibility(self): # two actions will always be here: the widget with the buttons and the exclusive action if len(self.actions()) > 2 or self.count: self.show() else: self.hide() def __dockChanged(self): a = self.sender() d = a.parent() if not d or d.isFloating() or self.manager.dockWidgetAreaToToolBarArea( self.manager.main.dockWidgetArea( d)) == self.manager.main.toolBarArea(self): return else: self.dockWidgetAreaChanged.emit(d, self) def __dockDestroyed(self, o): i = self.id(o) if i == -1: return o.removeEventFilter(self) b = self.button(o) del self.buttons[i] b.deleteLater() del self.docks[i] self.__checkVisibility() def __buttonClicked(self, b): btn = self.sender() dock = self.__buttonToDock[btn] if not dock: return if self.exclusive: self.__hideAllDocksBut(dock) if dock.isVisible() != b: dock.setVisible(b) def __hideAllDocksBut(self, toShow=None): for dw in self.docks: if dw != toShow: dw.hide() def __dockAlerted(self, alerted): dock = self.sender() if self.hasDock(dock): pb = self.__dockToButton[dock] if alerted: pb.setStyleSheet("color: red") else: pb.setStyleSheet("") def __dockTitleChanged(self, title): dock = self.sender() if self.hasDock(dock): pb = self.__dockToButton[dock] pb.setText(title) def __dockIconChanged(self, icon): dock = self.sender() if self.hasDock(dock): pb = self.__dockToButton[dock] pb.setIcon(icon)