def create_action(parent, text, shortcut=None, icon=None, tip=None, toggled=None, triggered=None, data=None, menurole=None, context=Qt.WindowShortcut): """Create a QAction""" action = QAction(text, parent) if triggered is not None: parent.connect(action, SIGNAL("triggered()"), triggered) if toggled is not None: parent.connect(action, SIGNAL("toggled(bool)"), toggled) action.setCheckable(True) if icon is not None: if is_text_string(icon): icon = get_icon(icon) action.setIcon(icon) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if data is not None: action.setData(data) if menurole is not None: action.setMenuRole(menurole) #TODO: Hard-code all shortcuts and choose context=Qt.WidgetShortcut # (this will avoid calling shortcuts from another dockwidget # since the context thing doesn't work quite well with these widgets) action.setShortcutContext(context) return action
class Actions(actioncollection.ActionCollection): name = 'scorewiz' def createActions(self, parent=None): self.scorewiz = QAction(parent) self.scorewiz.setIcon(icons.get("tools-score-wizard")) self.scorewiz.setShortcut(QKeySequence("Ctrl+Shift+N")) self.scorewiz.setMenuRole(QAction.NoRole) def translateUI(self): self.scorewiz.setText(_("Score &Wizard..."))
def create_actions(self): new_tab_action = QAction('&New Tab', self) new_tab_action.setShortcuts(QKeySequence.AddTab) self.connect(new_tab_action, SIGNAL('triggered()'), self.new_tab) self.new_tab_action = new_tab_action close_tab_action = QAction('&Close Tab', self) close_tab_action.setShortcuts(QKeySequence.Close) self.connect(close_tab_action, SIGNAL('triggered()'), self.close_tab) self.close_tab_action = close_tab_action open_action = QAction('&Open...', self) open_action.setShortcuts(QKeySequence.Open) self.connect(open_action, SIGNAL('triggered()'), self.open_file) self.open_action = open_action save_as_action = QAction('Save &As...', self) save_as_action.setShortcuts(QKeySequence.SaveAs) self.connect(save_as_action, SIGNAL('triggered()'), self.save_as_file) self.save_as_action = save_as_action exit_action = QAction('E&xit', self) exit_action.setMenuRole(QAction.QuitRole) self.connect(exit_action, SIGNAL('triggered()'), self, SLOT('close()')) self.exit_action = exit_action next_tab_action = QAction('Next Tab', self) bindings = QKeySequence.keyBindings(QKeySequence.NextChild) if sys.platform == 'darwin': bindings.append('Meta+PgDown') bindings.append('Meta+Tab') else: bindings.append('Ctrl+PgDown') next_tab_action.setShortcuts(bindings) self.connect(next_tab_action, SIGNAL('triggered()'), self.focus_next_tab); self.addAction(next_tab_action) previous_tab_action = QAction('Previous Tab', self) bindings = QKeySequence.keyBindings(QKeySequence.PreviousChild) if sys.platform == 'darwin': bindings.append('Meta+PgUp') bindings.append('Meta+Shift+Tab') else: bindings.append('Ctrl+PgUp') previous_tab_action.setShortcuts(bindings) self.connect(previous_tab_action, SIGNAL('triggered()'), self.focus_previous_tab); self.addAction(previous_tab_action)
class PythonConsoleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) ##------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) #self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) #self.splitterObj.setSizes([0, 0]) #self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) #self.splitterEditor.addWidget(self.widgetEditor) #self.splitterObj.addWidget(self.listClassMethod) #self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() sizes = self.splitter.sizes() self.splitter.setSizes(sizes) ##----------------Restore Settings------------------------------------ self.restoreSettingsConsole() ##------------------Toolbar Editor------------------------------------- ## Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open file") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in external editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) ## Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) ## Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) ## Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCutEditorConsole.png")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) ## Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) ## Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) ## Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) ## Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) ## Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) ## Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) ## Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) ##----------------Toolbar Console------------------------------------- ## Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) ## Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) ## Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Settings") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) ## Action menu for class actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class") self.actionClass = QAction(self) self.actionClass.setCheckable(False) self.actionClass.setEnabled(True) self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png")) self.actionClass.setMenuRole(QAction.PreferencesRole) self.actionClass.setIconVisibleInMenu(True) self.actionClass.setToolTip(actionClassBt) self.actionClass.setText(actionClassBt) ## Import Processing class loadProcessingBt = QCoreApplication.translate("PythonConsole", "Import Processing class") self.loadProcessingButton = QAction(self) self.loadProcessingButton.setCheckable(False) self.loadProcessingButton.setEnabled(True) self.loadProcessingButton.setIcon(QgsApplication.getThemeIcon("console/iconProcessingConsole.png")) self.loadProcessingButton.setMenuRole(QAction.PreferencesRole) self.loadProcessingButton.setIconVisibleInMenu(True) self.loadProcessingButton.setToolTip(loadProcessingBt) self.loadProcessingButton.setText(loadProcessingBt) ## Import QtCore class loadQtCoreBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore class") self.loadQtCoreButton = QAction(self) self.loadQtCoreButton.setCheckable(False) self.loadQtCoreButton.setEnabled(True) self.loadQtCoreButton.setIcon(QgsApplication.getThemeIcon("console/iconQtCoreConsole.png")) self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole) self.loadQtCoreButton.setIconVisibleInMenu(True) self.loadQtCoreButton.setToolTip(loadQtCoreBt) self.loadQtCoreButton.setText(loadQtCoreBt) ## Import QtGui class loadQtGuiBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui class") self.loadQtGuiButton = QAction(self) self.loadQtGuiButton.setCheckable(False) self.loadQtGuiButton.setEnabled(True) self.loadQtGuiButton.setIcon(QgsApplication.getThemeIcon("console/iconQtGuiConsole.png")) self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole) self.loadQtGuiButton.setIconVisibleInMenu(True) self.loadQtGuiButton.setToolTip(loadQtGuiBt) self.loadQtGuiButton.setText(loadQtGuiBt) ## Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) ## Help action helpBt = QCoreApplication.translate("PythonConsole", "Help") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(QSize(16, 16)) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.actionClass) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(QSize(16, 16)) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) ## Menu Import Class self.classMenu = QMenu() self.classMenu.addAction(self.loadProcessingButton) self.classMenu.addAction(self.loadQtCoreButton) self.classMenu.addAction(self.loadQtGuiButton) cM = self.toolBar.widgetForAction(self.actionClass) cM.setMenu(self.classMenu) cM.setPopupMode(QToolButton.InstantPopup) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) ##------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) ## Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...") if pyqtconfig.Configuration().qt_version >= 0x40700: self.lineEditFind.setPlaceholderText(placeHolderTxt) else: self.lineEditFind.setToolTip(placeHolderTxt) self.findNextButton = QToolButton() self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png")) self.findNextButton.setIconSize(QSize(24, 24)) self.findNextButton.setAutoRaise(True) self.findPrevButton = QToolButton() self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png")) self.findPrevButton.setIconSize(QSize(24, 24)) self.findPrevButton.setAutoRaise(True) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1) self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1) self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1) self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1) self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1) self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1) ##------------ Add first Tab in Editor ------------------------------- #self.tabEditorWidget.newTabEditor(tabName='first', filename=None) ##------------ Signal ------------------------------- self.findTextButton.toggled.connect(self.findTextEditor) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.loadProcessingButton.triggered.connect(self.processing) self.loadQtCoreButton.triggered.connect(self.qtCore) self.loadQtGuiButton.triggered.connect(self.qtGui) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.connect(self.listClassMethod, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findText) self.findNextButton.clicked.connect(self._findNext) self.findPrevButton.clicked.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) def _findText(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findNext(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findPrev(self): self.tabEditorWidget.currentWidget().newEditor.findText(False) def _textFindChanged(self): if self.lineEditFind.text(): self.findNextButton.setEnabled(True) self.findPrevButton.setEnabled(True) else: self.lineEditFind.setStyleSheet('') self.findNextButton.setEnabled(False) self.findPrevButton.setEnabled(False) def onClickGoToLine(self, item, column): tabEditor = self.tabEditorWidget.currentWidget().newEditor if item.text(1) == 'syntaxError': check = tabEditor.syntaxCheck(fromContextMenu=False) if check and not tabEditor.isReadOnly(): self.tabEditorWidget.currentWidget().save() return linenr = int(item.text(1)) itemName = str(item.text(0)) charPos = itemName.find(' ') if charPos != -1: objName = itemName[0:charPos] else: objName = itemName tabEditor.goToLine(objName, linenr) def processing(self): self.shell.commandConsole('processing') def qtCore(self): self.shell.commandConsole('qtCore') def qtGui(self): self.shell.commandConsole('qtGui') def toggleEditor(self, checked): self.splitterObj.show() if checked else self.splitterObj.hide() if not self.tabEditorWidget: self.tabEditorWidget.enableToolBarEditor(checked) self.tabEditorWidget.restoreTabsOrAddNew() def toggleObjectListWidget(self, checked): self.listClassMethod.show() if checked else self.listClassMethod.hide() def findTextEditor(self, checked): self.widgetFind.show() if checked else self.widgetFind.hide() def pasteEditor(self): self.tabEditorWidget.currentWidget().newEditor.paste() def cutEditor(self): self.tabEditorWidget.currentWidget().newEditor.cut() def copyEditor(self): self.tabEditorWidget.currentWidget().newEditor.copy() def runScriptEditor(self): self.tabEditorWidget.currentWidget().newEditor.runScriptCode() def commentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True) def uncommentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False) def openScriptFileExtEditor(self): tabWidget = self.tabEditorWidget.currentWidget() path = tabWidget.path import subprocess try: subprocess.Popen([os.environ['EDITOR'], path]) except KeyError: QDesktopServices.openUrl(QUrl.fromLocalFile(path)) def openScriptFile(self): lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) openFileTr = QCoreApplication.translate("PythonConsole", "Open File") fileList = QFileDialog.getOpenFileNames( self, openFileTr, lastDirPath, "Script file (*.py)") if fileList: for pyFile in fileList: for i in range(self.tabEditorWidget.count()): tabWidget = self.tabEditorWidget.widget(i) if tabWidget.path == pyFile: self.tabEditorWidget.setCurrentWidget(tabWidget) break else: tabName = QFileInfo(pyFile).fileName() self.tabEditorWidget.newTabEditor(tabName, pyFile) lastDirPath = QFileInfo(pyFile).path() self.settings.setValue("pythonConsole/lastDirPath", pyFile) self.updateTabListScript(pyFile, action='append') def saveScriptFile(self): tabWidget = self.tabEditorWidget.currentWidget() try: tabWidget.save() except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) def saveAsScriptFile(self, index=None): tabWidget = self.tabEditorWidget.currentWidget() if not index: index = self.tabEditorWidget.currentIndex() if not tabWidget.path: fileName = self.tabEditorWidget.tabText(index) + '.py' folder = self.settings.value("pythonConsole/lastDirPath", QDir.home()) pathFileName = os.path.join(folder, fileName) fileNone = True else: pathFileName = tabWidget.path fileNone = False saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As") filename = QFileDialog.getSaveFileName(self, saveAsFileTr, pathFileName, "Script file (*.py)") if filename: try: tabWidget.save(filename) except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) if fileNone: tabWidget.path = None else: tabWidget.path = pathFileName return if not fileNone: self.updateTabListScript(pathFileName, action='remove') def openHelp(self): QgsContextHelp.run("PythonConsole") def openSettings(self): if optionsDialog(self).exec_(): self.shell.refreshSettingsShell() self.shellOut.refreshSettingsOutput() self.tabEditorWidget.refreshSettingsEditor() def callWidgetMessageBar(self, text): self.shellOut.widgetMessageBar(iface, text) def callWidgetMessageBarEditor(self, text, level, timed): self.tabEditorWidget.widgetMessageBar(iface, text, level, timed) def updateTabListScript(self, script, action=None): if action == 'remove': self.tabListScript.remove(script) elif action == 'append': if not self.tabListScript: self.tabListScript = [] if script not in self.tabListScript: self.tabListScript.append(script) else: self.tabListScript = [] self.settings.setValue("pythonConsole/tabScripts", self.tabListScript) def saveSettingsConsole(self): self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState()) self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState()) self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState()) self.shell.writeHistoryFile(True) def restoreSettingsConsole(self): storedTabScripts = self.settings.value("pythonConsole/tabScripts", []) self.tabListScript = storedTabScripts self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray())) self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray())) self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
class MainWindow(QtGui.QMainWindow): """Implements the main window for dame.""" def __init__(self, parent=None): """Initialize the window.""" QtGui.QMainWindow.__init__(self, parent) self.setupUi() def setupUi(self): """Create the basic UI.""" self.setWindowTitle("dame") # TODO: Set window icon self.create_actions() self.create_statusbar() self.mainview = MainViewer(parent=self) # # Connect an action now that mainview is set # self.mode_group.triggered.connect(self.mainview.toggleComparison) # TODO: This is the start of using tabbed windows # self.mdiArea = QtGui.QMdiArea(parent=self) # first = self.mdiArea.addSubWindow(self.scrollArea) # self.mdiArea.setViewMode(QtGui.QMdiArea.TabbedView) # self.mdiArea.setTabsMovable(True) # self.setCentralWidget(self.mdiArea) # first.setWindowTitle("foo") self.setCentralWidget(self.mainview) # Create popup windows (for zoomer and panner) self.zoom_win = QtGui.QWidget(self, Qt.Window | Qt.Tool) self.zoom_win.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.zoom_win_im = QLabel() self.zoom_win_im.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored) # self.zoom_win.resize(150,150) # self.zoom_win.show() zoomer_layout = QtGui.QGridLayout() zoomer_layout.setContentsMargins(0, 0, 0, 0) zoomer_layout.addWidget(self.zoom_win_im) self.zoom_win.setLayout(zoomer_layout) # TODO: panner # Create note dock widget self.note_widget = QtGui.QDockWidget("Notes", parent=self) self.note_text = QtGui.QTextEdit(parent=self.note_widget) self.note_widget.setWidget(self.note_text) self.note_widget.setFeatures( QtGui.QDockWidget.DockWidgetClosable | QtGui.QDockWidget.DockWidgetMovable | QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetVerticalTitleBar) self.addDockWidget(Qt.BottomDockWidgetArea, self.note_widget) self.note_widget.close() self.note_action = self.note_widget.toggleViewAction() self.note_action.setText("Display notes") self.note_action.setStatusTip("Show notes about the SIR image") # Create the menus self.create_menus() def create_statusbar(self): """Create the statusbar.""" self.statusBar().showMessage("Ready") # The individual info self.status_sing_pixinfo = QLabel() self.status_sing_coord = QLabel() self.status_left_pixinfo = QLabel() self.status_right_pixinfo = QLabel() self.status_comp_coord = QLabel() # The groups self.status_sing_layout = QtGui.QHBoxLayout() self.status_sing_layout.addWidget(self.status_sing_coord, 0, Qt.AlignRight) self.status_sing_layout.addWidget(self.status_sing_pixinfo, 1, Qt.AlignRight) self.status_comp_layout = QtGui.QHBoxLayout() self.status_comp_layout.addWidget(self.status_left_pixinfo, 0) self.status_comp_layout.addWidget(self.status_comp_coord, 1) self.status_comp_layout.addWidget(self.status_right_pixinfo, 0) self.status_sing_layout.setContentsMargins(0, 0, 0, 0) self.status_comp_layout.setContentsMargins(0, 0, 0, 0) self.status_sing = QtGui.QWidget() self.status_sing.setLayout(self.status_sing_layout) self.status_comp = QtGui.QWidget() self.status_comp.setLayout(self.status_comp_layout) # The stacked widget (to alternate between single and comparison modes) self.status_stacked = QtGui.QStackedWidget() self.status_stacked.addWidget(self.status_sing) self.status_stacked.addWidget(self.status_comp) self.status_stacked.setCurrentIndex(0) self.statusBar().addWidget(self.status_stacked) def create_actions(self): """Define the actions.""" self.about_action = QAction("&About", self) self.about_action.setStatusTip("About dame") self.about_action.setMenuRole(QAction.AboutRole) self.about_action.triggered.connect(self.show_about) self.open_action = QAction("&Open", self) self.open_action.setStatusTip("Open a SIR file") self.open_action.setShortcut(QtGui.QKeySequence.Open) self.open_action.triggered.connect(self.open_file) self.close_action = QAction("&Close", self) self.close_action.setStatusTip("Close current SIR file") self.close_action.setShortcut(QtGui.QKeySequence.Close) self.close_action.triggered.connect(self.close_file) self.exit_action = QAction("E&xit", self) self.exit_action.setMenuRole(QAction.QuitRole) self.exit_action.setStatusTip("Exit dame") self.exit_action.setShortcut(QtGui.QKeySequence("Ctrl+Q")) self.exit_action.triggered.connect(self.close) self.prop_action = QAction("SIR header", self) self.prop_action.setStatusTip("Display SIR header information") self.prop_action.triggered.connect(self.print_header) self.range_action = QAction("Image range", self) self.range_action.setStatusTip("Set image display range") self.range_action.triggered.connect(self.show_range) self.zoomer_action = QAction("Enable zoomer window", self) self.zoomer_action.setStatusTip(("Show zoomer window for " "magnified viewing")) self.zoomer_action.setCheckable(True) self.zoomer_action.triggered.connect(self.update_zoomer_opts) self.zoom_factor_label_action = QAction("Zoom factor", self) self.zoom_factor_label_action.setEnabled(False) self.zoom_factor_1_action = QAction("2x zoom", self) self.zoom_factor_2_action = QAction("4x zoom", self) self.zoom_factor_3_action = QAction("8x zoom", self) self.zoom_factor_4_action = QAction("16x zoom", self) self.zoom_factor_1_action.setStatusTip("Magnify zoom region by 2x") self.zoom_factor_2_action.setStatusTip("Magnify zoom region by 4x") self.zoom_factor_3_action.setStatusTip("Magnify zoom region by 8x") self.zoom_factor_4_action.setStatusTip("Magnify zoom region by 16x") self.zoom_factor_1_action.setCheckable(True) self.zoom_factor_2_action.setCheckable(True) self.zoom_factor_3_action.setCheckable(True) self.zoom_factor_4_action.setCheckable(True) self.zoom_size_label_action = QAction("Zoom region size", self) self.zoom_size_label_action.setEnabled(False) self.zoom_size_1_action = QAction("9x9 window", self) self.zoom_size_2_action = QAction("17x17 window", self) self.zoom_size_3_action = QAction("29x29 window", self) self.zoom_size_4_action = QAction("45x45 window", self) self.zoom_size_5_action = QAction("65x65 window", self) self.zoom_size_1_action.setStatusTip("Set zoom region to 9x9 pixels") self.zoom_size_2_action.setStatusTip("Set zoom region to 17x17 pixels") self.zoom_size_3_action.setStatusTip("Set zoom region to 29x29 pixels") self.zoom_size_4_action.setStatusTip("Set zoom region to 45x45 pixels") self.zoom_size_5_action.setStatusTip("Set zoom region to 65x65 pixels") self.zoom_size_1_action.setCheckable(True) self.zoom_size_2_action.setCheckable(True) self.zoom_size_3_action.setCheckable(True) self.zoom_size_4_action.setCheckable(True) self.zoom_size_5_action.setCheckable(True) # Group zoomer actions and connect slots self.zoom_factor_group = QtGui.QActionGroup(self) self.zoom_factor_group.addAction(self.zoom_factor_1_action) self.zoom_factor_group.addAction(self.zoom_factor_2_action) self.zoom_factor_group.addAction(self.zoom_factor_3_action) self.zoom_factor_group.addAction(self.zoom_factor_4_action) self.zoom_factor_group.triggered.connect(self.update_zoomer_opts) self.zoom_size_group = QtGui.QActionGroup(self) self.zoom_size_group.addAction(self.zoom_size_1_action) self.zoom_size_group.addAction(self.zoom_size_2_action) self.zoom_size_group.addAction(self.zoom_size_3_action) self.zoom_size_group.addAction(self.zoom_size_4_action) self.zoom_size_group.addAction(self.zoom_size_5_action) self.zoom_size_group.triggered.connect(self.update_zoomer_opts) # # Mode actions # self.mode_group = QtGui.QActionGroup(self) # self.mode_single_action = QAction("Single image", self.mode_group) # self.mode_dual_action = QAction("Two images", self.mode_group) # self.mode_single_action.setCheckable(True) # self.mode_dual_action.setCheckable(True) # self.mode_single_action.setStatusTip("Display a single image") # self.mode_dual_action.setStatusTip("Display two images for comparison") # self.mode_single_action.setChecked(True) # #self.mode_group.triggered.connect(self.mainview.toggleComparison) # Moved later # http://stackoverflow.com/questions/11643221/are-there-default-icons-in-pyqt-pyside # TODO: Add icons in a better way. See how Picard does it. QIcon.setThemeName("gnome") # TODO: temporary self.open_action.setIcon(QIcon.fromTheme("document-open")) self.close_action.setIcon(QIcon.fromTheme("window-close")) self.exit_action.setIcon(QIcon.fromTheme("application-exit")) self.about_action.setIcon(QIcon.fromTheme("help-about")) def create_menus(self): """Setup the menus.""" menu = self.menuBar().addMenu("&File") menu.addAction(self.open_action) menu.addAction(self.close_action) menu.addSeparator() # menu.addAction(self.mode_single_action) # menu.addAction(self.mode_dual_action) # menu.addSeparator() menu.addAction(self.exit_action) menu = self.menuBar().addMenu("Image") menu.addAction(self.prop_action) menu.addAction(self.range_action) menu.addAction(self.note_action) # submenu = menu.addMenu("Mode") # submenu.addAction(self.mode_single_action) # submenu.addAction(self.mode_split_action) # submenu.addAction(self.mode_fade_action) menu = self.menuBar().addMenu("Zoomer") menu.addAction(self.zoomer_action) menu.addSeparator() menu.addAction(self.zoom_factor_label_action) menu.addAction(self.zoom_factor_1_action) menu.addAction(self.zoom_factor_2_action) menu.addAction(self.zoom_factor_3_action) menu.addAction(self.zoom_factor_4_action) menu.addSeparator() menu.addAction(self.zoom_size_label_action) menu.addAction(self.zoom_size_1_action) menu.addAction(self.zoom_size_2_action) menu.addAction(self.zoom_size_3_action) menu.addAction(self.zoom_size_4_action) menu.addAction(self.zoom_size_5_action) menu = self.menuBar().addMenu("&Help") menu.addAction(self.about_action) # Deactivate menus by default self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def open_file(self): """Display open file dialog.""" filename = QtGui.QFileDialog.getOpenFileName(self, "Open SIR file", QtCore.QDir.homePath(), ("SIR files (*.sir *.ave)" ";;Any file (*)")) if py_binding == 'PySide': filename = filename[0] if filename: self.load_sir(filename) def load_sir(self, filename): """Load in the SIR file.""" if os.access(filename, os.F_OK | os.R_OK): self.statusBar().showMessage("Loading") self.mainview.load_sir(filename) self.statusBar().showMessage("Loaded", 2000) # Activate menus self.range_action.setEnabled(True) self.prop_action.setEnabled(True) self.close_action.setEnabled(True) else: logging.warning("Can't open {}".format(filename)) # TODO: Alert the user via GUI @QtCore.Slot() def close_file(self): """Close file.""" logging.info("Closing SIR file") self.mainview.close_file() self.statusBar().showMessage("SIR closed", 2000) # That was the last file, so disable stuff if len(self.mainview.sir_files) == 0: self.status_stacked.setVisible(False) self.zoom_win.hide() # Deactivate menus self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def show_about(self): """Display about popup.""" about_text = """ Dame {} Copyright 2014 Richard Lindsley Dame is a SIR file viewer""".format(version_string) QMessageBox.about(self, "About", dedent(about_text)) @QtCore.Slot() def show_range(self): """Display image range popup.""" win = RangeWindow() win.min_text.setText( str(self.mainview.sir_files[self.mainview.cur_tab]['vmin'])) win.max_text.setText( str(self.mainview.sir_files[self.mainview.cur_tab]['vmax'])) if win.exec_() == QtGui.QDialog.Accepted: win_range = win.getRange() self.mainview.sir_files[self.mainview.cur_tab]['vmin'] = \ win_range[0] self.mainview.sir_files[self.mainview.cur_tab]['vmax'] = \ win_range[1] self.mainview.update_image(self.mainview.cur_tab) self.mainview.update_view() @QtCore.Slot() def print_header(self): """Display SIR header info.""" sir_head = libsir.print_sir_head( self.mainview.sir_files[self.mainview.cur_tab]['header']) # TODO: Maybe make this a modeless dialog instead of modal? Use a dock # widget? box = QMessageBox() box.setText(dedent(sir_head)) box.setIcon(QMessageBox.Information) box.exec_() def update_zoomer(self): """Update the zoomer, both the image as well as the popup.""" cur_tab = self.mainview.cur_tab if 'pix_loc' not in self.mainview.sir_files[cur_tab]: return try: loc = self.mainview.sir_files[cur_tab]['pix_loc'] rect_w = self.mainview.sir_files[cur_tab]['zoomer_size'] winsize = rect_w * \ self.mainview.sir_files[cur_tab]['zoomer_factor'] if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'].copy(), self.mainview.sir_files['right']['pixmap'].copy()) else: pixmaps = \ (self.mainview.sir_files[cur_tab]['pixmap'].copy(),) for pixmap_i, pixmap in enumerate(pixmaps): # Upper left corner if loc.x() < rect_w / 2: rect_x = -0.5 elif loc.x() > pixmap.width() - rect_w / 2: rect_x = pixmap.width() - rect_w - 0.5 else: rect_x = loc.x() - rect_w / 2 if loc.y() < rect_w / 2: rect_y = -0.5 elif loc.y() > pixmap.height() - rect_w / 2: rect_y = pixmap.height() - rect_w - 0.5 else: rect_y = loc.y() - rect_w / 2 rect_x += 1 rect_y += 1 # Draw the image with the zoomer region outlined p = QtGui.QPainter() p.begin(pixmap) p.setPen(QtGui.QColor("#FFFFFF")) # White stroke p.drawRect(rect_x, rect_y, rect_w, rect_w) p.end() if cur_tab in ("left", "right", "cross"): self.mainview.single_image.image.setPixmap(pixmap) elif cur_tab in ("split", ): if pixmap_i == 0: self.mainview.left_image.image.setPixmap(pixmap) elif pixmap_i == 1: self.mainview.right_image.image.setPixmap(pixmap) else: logging.warning("pixmap_i is {}".format(pixmap_i)) # Update the zoomer window if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'], self.mainview.sir_files['right']['pixmap']) else: pixmaps = (self.mainview.sir_files[cur_tab]['pixmap'], ) if len(pixmaps) == 2: zoom_pixmap = QPixmap(2 * winsize, winsize) for pixmap_i, pixmap_src in enumerate(pixmaps): # extract the zoomer region pixmap = pixmap_src.copy(rect_x, rect_y, rect_w, rect_w) # scale it pixmap = pixmap.scaled(winsize, winsize, Qt.KeepAspectRatioByExpanding) # Add crosshair to zoomer window; note that the crosshair # won't be centered if the region is at the edges p = QtGui.QPainter() p.begin(pixmap) # Highlight selected pixel # p.setPen(QtGui.QColor("#000000")) # Black stroke p.setPen(QtGui.QColor("#FFFFFF")) # White stroke zoom_fac = self.mainview.sir_files[cur_tab]['zoomer_factor'] # Top left of magnified pixel mag_pix = (zoom_fac * (loc.x() - rect_x + 1) - zoom_fac / 2, zoom_fac * (loc.y() - rect_y + 1) - zoom_fac / 2) # Center of magnified pixel mag_pix_cen = (zoom_fac * (loc.x() - rect_x + 1), zoom_fac * (loc.y() - rect_y + 1)) p.drawRect(mag_pix[0], mag_pix[1], zoom_fac, zoom_fac) # Draw crosshairs p.setPen(QtGui.QColor("#FFFFFF")) # White stroke # vertical line, top p.drawLine(mag_pix_cen[0], 0, mag_pix_cen[0], mag_pix[1] - 1) # vertical line, bottom p.drawLine(mag_pix_cen[0], mag_pix[1] + zoom_fac, mag_pix_cen[0], winsize - 0) # horizontal line, left p.drawLine(0, mag_pix_cen[1], mag_pix[0] - 1, mag_pix_cen[1]) # horizontal line, right p.drawLine(mag_pix[0] + zoom_fac, mag_pix_cen[1], winsize - 0, mag_pix_cen[1]) p.end() if len(pixmaps) == 1: self.zoom_win_im.setPixmap(pixmap) else: p = QtGui.QPainter(zoom_pixmap) p.drawPixmap(pixmap_i * winsize, 0, pixmap) self.zoom_win_im.setPixmap(zoom_pixmap) self.zoom_win_im.setHidden(False) self.zoom_win_im.adjustSize() except KeyError as err: logging.warning("Can't find {}".format(err)) def update_statusbar(self): """Update the status bar.""" if self.mainview.cur_tab in ("left", "right"): vmin = self.mainview.sir_files[self.mainview.cur_tab]['vmin'] vmax = self.mainview.sir_files[self.mainview.cur_tab]['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(0) self.status_sing_pixinfo.setText("min: {}, max: {}".format( vmin, vmax)) self.status_sing_coord.setVisible(False) elif self.mainview.cur_tab in ("split", "fade"): vmin_l = self.mainview.sir_files['left']['vmin'] vmax_l = self.mainview.sir_files['left']['vmax'] vmin_r = self.mainview.sir_files['right']['vmin'] vmax_r = self.mainview.sir_files['right']['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(1) self.status_left_pixinfo.setText("min: {} max: {}".format( vmin_l, vmax_l)) self.status_right_pixinfo.setText("min: {} max: {}".format( vmin_r, vmax_r)) self.status_comp_coord.setVisible(False) def update_statusbar_pos(self, x_im, y_im): """Update with position at image index x, y.""" self.statusBar().clearMessage() nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy # Convert from 0-based to 1-based indexing # (I've double-checked the values returned here using sir_util2a) y = nsy - y_im # Convert image y coord to SIR y coord x = x_im + 1 if x > 0 and y > 0 and x <= nsx and y <= nsy: # Note that sir_data is 0-based indexing, but pix2latlon is 1-based cur_sir = self.mainview.sir_files[self.mainview.cur_tab] lon, lat = libsir.pix2latlon(x, y, cur_sir['header']) if self.mainview.cur_tab in ("left", "right"): self.status_sing_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "value = {:0.4f}").format( x, y, lat, lon, cur_sir['data'][y_im, x_im]) self.status_sing_coord.setText(stat_text) elif self.mainview.cur_tab in ("split", "fade"): left_sir = self.mainview.sir_files['left'] right_sir = self.mainview.sir_files['right'] self.status_comp_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "left value = {:0.4f} " "right value = {:0.4f}").format( x, y, lat, lon, left_sir['data'][y_im, x_im], right_sir['data'][y_im, x_im]) self.status_comp_coord.setText(stat_text) def sizeHint(self): """Override the suggested size.""" return QtCore.QSize(1000, 800) # Menu events @QtCore.Slot() def update_zoomer_opts(self, draw_win=True): """Given a menu change, this sets zoomer options and updates.""" file_dict = self.mainview.sir_files[self.mainview.cur_tab] # Is zoomer enabled? file_dict['zoomer_on'] = self.zoomer_action.isChecked() # Find the zoom factor zfactor = self.zoom_factor_group.checkedAction() if zfactor is self.zoom_factor_1_action: file_dict['zoomer_factor'] = 2 elif zfactor is self.zoom_factor_2_action: file_dict['zoomer_factor'] = 4 elif zfactor is self.zoom_factor_3_action: file_dict['zoomer_factor'] = 8 elif zfactor is self.zoom_factor_4_action: file_dict['zoomer_factor'] = 16 # Find the zoom size zsize = self.zoom_size_group.checkedAction() if zsize is self.zoom_size_1_action: file_dict['zoomer_size'] = 9 elif zsize is self.zoom_size_2_action: file_dict['zoomer_size'] = 17 elif zsize is self.zoom_size_3_action: file_dict['zoomer_size'] = 29 elif zsize is self.zoom_size_4_action: file_dict['zoomer_size'] = 45 elif zsize is self.zoom_size_5_action: file_dict['zoomer_size'] = 65 if draw_win: # Compute zoomer window size and show/hide it winsize = file_dict['zoomer_size'] * file_dict['zoomer_factor'] if self.mainview.cur_tab == "split": self.zoom_win.resize(2 * winsize, winsize) self.zoom_win.setFixedSize(2 * winsize, winsize) else: self.zoom_win.resize(winsize, winsize) self.zoom_win.setFixedSize(winsize, winsize) if file_dict['zoomer_on']: self.zoom_win.show() else: self.zoom_win.hide() # Update zoomer self.update_zoomer() # Keyboard events def keyPressEvent(self, key): """Handle some keypresses.""" if len(self.mainview.sir_files) == 0: key.ignore() return if 'pix_loc' not in self.mainview.sir_files[self.mainview.cur_tab]: # Don't do anything if we don't have a coord yet key.ignore() return # Increment im_pos if valid key # Note that im_pos is 0-based, so # it ranges from 0 to nsx-1/nsy-1 inclusive im_pos = self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy delta = 5 if key.modifiers() == Qt.ShiftModifier else 1 if key.key() == Qt.Key_J: # Down if im_pos.y() + delta < nsy: im_pos.setY(im_pos.y() + delta) elif key.key() == Qt.Key_K: # Up if im_pos.y() - delta >= 0: im_pos.setY(im_pos.y() - delta) elif key.key() == Qt.Key_H: # Left if im_pos.x() - delta >= 0: im_pos.setX(im_pos.x() - delta) elif key.key() == Qt.Key_L: # Right if im_pos.x() + delta < nsx: im_pos.setX(im_pos.x() + delta) else: key.ignore() return # Update stuff with our new position self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] = im_pos self.update_zoomer() self.update_statusbar_pos(im_pos.x(), im_pos.y())
class MainWindow(QtGui.QMainWindow): """Implements the main window for dame.""" def __init__(self, parent=None): """Initialize the window.""" QtGui.QMainWindow.__init__(self, parent) self.setupUi() def setupUi(self): """Create the basic UI.""" self.setWindowTitle("dame") # TODO: Set window icon self.create_actions() self.create_statusbar() self.mainview = MainViewer(parent=self) # # Connect an action now that mainview is set # self.mode_group.triggered.connect(self.mainview.toggleComparison) # TODO: This is the start of using tabbed windows # self.mdiArea = QtGui.QMdiArea(parent=self) # first = self.mdiArea.addSubWindow(self.scrollArea) # self.mdiArea.setViewMode(QtGui.QMdiArea.TabbedView) # self.mdiArea.setTabsMovable(True) # self.setCentralWidget(self.mdiArea) # first.setWindowTitle("foo") self.setCentralWidget(self.mainview) # Create popup windows (for zoomer and panner) self.zoom_win = QtGui.QWidget(self, Qt.Window | Qt.Tool) self.zoom_win.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.zoom_win_im = QLabel() self.zoom_win_im.setSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Ignored) # self.zoom_win.resize(150,150) # self.zoom_win.show() zoomer_layout = QtGui.QGridLayout() zoomer_layout.setContentsMargins(0, 0, 0, 0) zoomer_layout.addWidget(self.zoom_win_im) self.zoom_win.setLayout(zoomer_layout) # TODO: panner # Create note dock widget self.note_widget = QtGui.QDockWidget("Notes", parent=self) self.note_text = QtGui.QTextEdit(parent=self.note_widget) self.note_widget.setWidget(self.note_text) self.note_widget.setFeatures( QtGui.QDockWidget.DockWidgetClosable | QtGui.QDockWidget.DockWidgetMovable | QtGui.QDockWidget.DockWidgetFloatable | QtGui.QDockWidget.DockWidgetVerticalTitleBar) self.addDockWidget(Qt.BottomDockWidgetArea, self.note_widget) self.note_widget.close() self.note_action = self.note_widget.toggleViewAction() self.note_action.setText("Display notes") self.note_action.setStatusTip("Show notes about the SIR image") # Create the menus self.create_menus() def create_statusbar(self): """Create the statusbar.""" self.statusBar().showMessage("Ready") # The individual info self.status_sing_pixinfo = QLabel() self.status_sing_coord = QLabel() self.status_left_pixinfo = QLabel() self.status_right_pixinfo = QLabel() self.status_comp_coord = QLabel() # The groups self.status_sing_layout = QtGui.QHBoxLayout() self.status_sing_layout.addWidget(self.status_sing_coord, 0, Qt.AlignRight) self.status_sing_layout.addWidget(self.status_sing_pixinfo, 1, Qt.AlignRight) self.status_comp_layout = QtGui.QHBoxLayout() self.status_comp_layout.addWidget(self.status_left_pixinfo, 0) self.status_comp_layout.addWidget(self.status_comp_coord, 1) self.status_comp_layout.addWidget(self.status_right_pixinfo, 0) self.status_sing_layout.setContentsMargins(0, 0, 0, 0) self.status_comp_layout.setContentsMargins(0, 0, 0, 0) self.status_sing = QtGui.QWidget() self.status_sing.setLayout(self.status_sing_layout) self.status_comp = QtGui.QWidget() self.status_comp.setLayout(self.status_comp_layout) # The stacked widget (to alternate between single and comparison modes) self.status_stacked = QtGui.QStackedWidget() self.status_stacked.addWidget(self.status_sing) self.status_stacked.addWidget(self.status_comp) self.status_stacked.setCurrentIndex(0) self.statusBar().addWidget(self.status_stacked) def create_actions(self): """Define the actions.""" self.about_action = QAction("&About", self) self.about_action.setStatusTip("About dame") self.about_action.setMenuRole(QAction.AboutRole) self.about_action.triggered.connect(self.show_about) self.open_action = QAction("&Open", self) self.open_action.setStatusTip("Open a SIR file") self.open_action.setShortcut(QtGui.QKeySequence.Open) self.open_action.triggered.connect(self.open_file) self.close_action = QAction("&Close", self) self.close_action.setStatusTip("Close current SIR file") self.close_action.setShortcut(QtGui.QKeySequence.Close) self.close_action.triggered.connect(self.close_file) self.exit_action = QAction("E&xit", self) self.exit_action.setMenuRole(QAction.QuitRole) self.exit_action.setStatusTip("Exit dame") self.exit_action.setShortcut(QtGui.QKeySequence("Ctrl+Q")) self.exit_action.triggered.connect(self.close) self.prop_action = QAction("SIR header", self) self.prop_action.setStatusTip("Display SIR header information") self.prop_action.triggered.connect(self.print_header) self.range_action = QAction("Image range", self) self.range_action.setStatusTip("Set image display range") self.range_action.triggered.connect(self.show_range) self.zoomer_action = QAction("Enable zoomer window", self) self.zoomer_action.setStatusTip(("Show zoomer window for " "magnified viewing")) self.zoomer_action.setCheckable(True) self.zoomer_action.triggered.connect(self.update_zoomer_opts) self.zoom_factor_label_action = QAction("Zoom factor", self) self.zoom_factor_label_action.setEnabled(False) self.zoom_factor_1_action = QAction("2x zoom", self) self.zoom_factor_2_action = QAction("4x zoom", self) self.zoom_factor_3_action = QAction("8x zoom", self) self.zoom_factor_4_action = QAction("16x zoom", self) self.zoom_factor_1_action.setStatusTip("Magnify zoom region by 2x") self.zoom_factor_2_action.setStatusTip("Magnify zoom region by 4x") self.zoom_factor_3_action.setStatusTip("Magnify zoom region by 8x") self.zoom_factor_4_action.setStatusTip("Magnify zoom region by 16x") self.zoom_factor_1_action.setCheckable(True) self.zoom_factor_2_action.setCheckable(True) self.zoom_factor_3_action.setCheckable(True) self.zoom_factor_4_action.setCheckable(True) self.zoom_size_label_action = QAction("Zoom region size", self) self.zoom_size_label_action.setEnabled(False) self.zoom_size_1_action = QAction("9x9 window", self) self.zoom_size_2_action = QAction("17x17 window", self) self.zoom_size_3_action = QAction("29x29 window", self) self.zoom_size_4_action = QAction("45x45 window", self) self.zoom_size_5_action = QAction("65x65 window", self) self.zoom_size_1_action.setStatusTip("Set zoom region to 9x9 pixels") self.zoom_size_2_action.setStatusTip("Set zoom region to 17x17 pixels") self.zoom_size_3_action.setStatusTip("Set zoom region to 29x29 pixels") self.zoom_size_4_action.setStatusTip("Set zoom region to 45x45 pixels") self.zoom_size_5_action.setStatusTip("Set zoom region to 65x65 pixels") self.zoom_size_1_action.setCheckable(True) self.zoom_size_2_action.setCheckable(True) self.zoom_size_3_action.setCheckable(True) self.zoom_size_4_action.setCheckable(True) self.zoom_size_5_action.setCheckable(True) # Group zoomer actions and connect slots self.zoom_factor_group = QtGui.QActionGroup(self) self.zoom_factor_group.addAction(self.zoom_factor_1_action) self.zoom_factor_group.addAction(self.zoom_factor_2_action) self.zoom_factor_group.addAction(self.zoom_factor_3_action) self.zoom_factor_group.addAction(self.zoom_factor_4_action) self.zoom_factor_group.triggered.connect(self.update_zoomer_opts) self.zoom_size_group = QtGui.QActionGroup(self) self.zoom_size_group.addAction(self.zoom_size_1_action) self.zoom_size_group.addAction(self.zoom_size_2_action) self.zoom_size_group.addAction(self.zoom_size_3_action) self.zoom_size_group.addAction(self.zoom_size_4_action) self.zoom_size_group.addAction(self.zoom_size_5_action) self.zoom_size_group.triggered.connect(self.update_zoomer_opts) # # Mode actions # self.mode_group = QtGui.QActionGroup(self) # self.mode_single_action = QAction("Single image", self.mode_group) # self.mode_dual_action = QAction("Two images", self.mode_group) # self.mode_single_action.setCheckable(True) # self.mode_dual_action.setCheckable(True) # self.mode_single_action.setStatusTip("Display a single image") # self.mode_dual_action.setStatusTip("Display two images for comparison") # self.mode_single_action.setChecked(True) # #self.mode_group.triggered.connect(self.mainview.toggleComparison) # Moved later # http://stackoverflow.com/questions/11643221/are-there-default-icons-in-pyqt-pyside # TODO: Add icons in a better way. See how Picard does it. QIcon.setThemeName("gnome") # TODO: temporary self.open_action.setIcon(QIcon.fromTheme("document-open")) self.close_action.setIcon(QIcon.fromTheme("window-close")) self.exit_action.setIcon(QIcon.fromTheme("application-exit")) self.about_action.setIcon(QIcon.fromTheme("help-about")) def create_menus(self): """Setup the menus.""" menu = self.menuBar().addMenu("&File") menu.addAction(self.open_action) menu.addAction(self.close_action) menu.addSeparator() # menu.addAction(self.mode_single_action) # menu.addAction(self.mode_dual_action) # menu.addSeparator() menu.addAction(self.exit_action) menu = self.menuBar().addMenu("Image") menu.addAction(self.prop_action) menu.addAction(self.range_action) menu.addAction(self.note_action) # submenu = menu.addMenu("Mode") # submenu.addAction(self.mode_single_action) # submenu.addAction(self.mode_split_action) # submenu.addAction(self.mode_fade_action) menu = self.menuBar().addMenu("Zoomer") menu.addAction(self.zoomer_action) menu.addSeparator() menu.addAction(self.zoom_factor_label_action) menu.addAction(self.zoom_factor_1_action) menu.addAction(self.zoom_factor_2_action) menu.addAction(self.zoom_factor_3_action) menu.addAction(self.zoom_factor_4_action) menu.addSeparator() menu.addAction(self.zoom_size_label_action) menu.addAction(self.zoom_size_1_action) menu.addAction(self.zoom_size_2_action) menu.addAction(self.zoom_size_3_action) menu.addAction(self.zoom_size_4_action) menu.addAction(self.zoom_size_5_action) menu = self.menuBar().addMenu("&Help") menu.addAction(self.about_action) # Deactivate menus by default self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def open_file(self): """Display open file dialog.""" filename = QtGui.QFileDialog.getOpenFileName(self, "Open SIR file", QtCore.QDir.homePath(), ("SIR files (*.sir *.ave)" ";;Any file (*)") ) if py_binding == 'PySide': filename = filename[0] if filename: self.load_sir(filename) def load_sir(self, filename): """Load in the SIR file.""" if os.access(filename, os.F_OK | os.R_OK): self.statusBar().showMessage("Loading") self.mainview.load_sir(filename) self.statusBar().showMessage("Loaded", 2000) # Activate menus self.range_action.setEnabled(True) self.prop_action.setEnabled(True) self.close_action.setEnabled(True) else: logging.warning("Can't open {}".format(filename)) # TODO: Alert the user via GUI @QtCore.Slot() def close_file(self): """Close file.""" logging.info("Closing SIR file") self.mainview.close_file() self.statusBar().showMessage("SIR closed", 2000) # That was the last file, so disable stuff if len(self.mainview.sir_files) == 0: self.status_stacked.setVisible(False) self.zoom_win.hide() # Deactivate menus self.range_action.setEnabled(False) self.prop_action.setEnabled(False) self.close_action.setEnabled(False) @QtCore.Slot() def show_about(self): """Display about popup.""" about_text = """ Dame {} Copyright 2014 Richard Lindsley Dame is a SIR file viewer""".format(version_string) QMessageBox.about(self, "About", dedent(about_text)) @QtCore.Slot() def show_range(self): """Display image range popup.""" win = RangeWindow() win.min_text.setText(str( self.mainview.sir_files[self.mainview.cur_tab]['vmin'])) win.max_text.setText(str( self.mainview.sir_files[self.mainview.cur_tab]['vmax'])) if win.exec_() == QtGui.QDialog.Accepted: win_range = win.getRange() self.mainview.sir_files[self.mainview.cur_tab]['vmin'] = \ win_range[0] self.mainview.sir_files[self.mainview.cur_tab]['vmax'] = \ win_range[1] self.mainview.update_image(self.mainview.cur_tab) self.mainview.update_view() @QtCore.Slot() def print_header(self): """Display SIR header info.""" sir_head = libsir.print_sir_head( self.mainview.sir_files[self.mainview.cur_tab]['header']) # TODO: Maybe make this a modeless dialog instead of modal? Use a dock # widget? box = QMessageBox() box.setText(dedent(sir_head)) box.setIcon(QMessageBox.Information) box.exec_() def update_zoomer(self): """Update the zoomer, both the image as well as the popup.""" cur_tab = self.mainview.cur_tab if 'pix_loc' not in self.mainview.sir_files[cur_tab]: return try: loc = self.mainview.sir_files[cur_tab]['pix_loc'] rect_w = self.mainview.sir_files[cur_tab]['zoomer_size'] winsize = rect_w * \ self.mainview.sir_files[cur_tab]['zoomer_factor'] if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'].copy(), self.mainview.sir_files['right']['pixmap'].copy()) else: pixmaps = \ (self.mainview.sir_files[cur_tab]['pixmap'].copy(),) for pixmap_i, pixmap in enumerate(pixmaps): # Upper left corner if loc.x() < rect_w/2: rect_x = -0.5 elif loc.x() > pixmap.width() - rect_w/2: rect_x = pixmap.width() - rect_w - 0.5 else: rect_x = loc.x() - rect_w/2 if loc.y() < rect_w/2: rect_y = -0.5 elif loc.y() > pixmap.height() - rect_w/2: rect_y = pixmap.height() - rect_w - 0.5 else: rect_y = loc.y() - rect_w/2 rect_x += 1 rect_y += 1 # Draw the image with the zoomer region outlined p = QtGui.QPainter() p.begin(pixmap) p.setPen(QtGui.QColor("#FFFFFF")) # White stroke p.drawRect(rect_x, rect_y, rect_w, rect_w) p.end() if cur_tab in ("left", "right", "cross"): self.mainview.single_image.image.setPixmap(pixmap) elif cur_tab in ("split", ): if pixmap_i == 0: self.mainview.left_image.image.setPixmap(pixmap) elif pixmap_i == 1: self.mainview.right_image.image.setPixmap(pixmap) else: logging.warning("pixmap_i is {}".format(pixmap_i)) # Update the zoomer window if cur_tab == "split": pixmaps = (self.mainview.sir_files['left']['pixmap'], self.mainview.sir_files['right']['pixmap']) else: pixmaps = (self.mainview.sir_files[cur_tab]['pixmap'],) if len(pixmaps) == 2: zoom_pixmap = QPixmap(2*winsize, winsize) for pixmap_i, pixmap_src in enumerate(pixmaps): # extract the zoomer region pixmap = pixmap_src.copy(rect_x, rect_y, rect_w, rect_w) # scale it pixmap = pixmap.scaled(winsize, winsize, Qt.KeepAspectRatioByExpanding) # Add crosshair to zoomer window; note that the crosshair # won't be centered if the region is at the edges p = QtGui.QPainter() p.begin(pixmap) # Highlight selected pixel # p.setPen(QtGui.QColor("#000000")) # Black stroke p.setPen(QtGui.QColor("#FFFFFF")) # White stroke zoom_fac = self.mainview.sir_files[cur_tab]['zoomer_factor'] # Top left of magnified pixel mag_pix = (zoom_fac * (loc.x() - rect_x + 1) - zoom_fac/2, zoom_fac * (loc.y() - rect_y + 1) - zoom_fac/2) # Center of magnified pixel mag_pix_cen = (zoom_fac * (loc.x() - rect_x + 1), zoom_fac * (loc.y() - rect_y + 1)) p.drawRect(mag_pix[0], mag_pix[1], zoom_fac, zoom_fac) # Draw crosshairs p.setPen(QtGui.QColor("#FFFFFF")) # White stroke # vertical line, top p.drawLine(mag_pix_cen[0], 0, mag_pix_cen[0], mag_pix[1]-1) # vertical line, bottom p.drawLine(mag_pix_cen[0], mag_pix[1]+zoom_fac, mag_pix_cen[0], winsize-0) # horizontal line, left p.drawLine(0, mag_pix_cen[1], mag_pix[0]-1, mag_pix_cen[1]) # horizontal line, right p.drawLine(mag_pix[0]+zoom_fac, mag_pix_cen[1], winsize-0, mag_pix_cen[1]) p.end() if len(pixmaps) == 1: self.zoom_win_im.setPixmap(pixmap) else: p = QtGui.QPainter(zoom_pixmap) p.drawPixmap(pixmap_i * winsize, 0, pixmap) self.zoom_win_im.setPixmap(zoom_pixmap) self.zoom_win_im.setHidden(False) self.zoom_win_im.adjustSize() except KeyError as err: logging.warning("Can't find {}".format(err)) def update_statusbar(self): """Update the status bar.""" if self.mainview.cur_tab in ("left", "right"): vmin = self.mainview.sir_files[self.mainview.cur_tab]['vmin'] vmax = self.mainview.sir_files[self.mainview.cur_tab]['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(0) self.status_sing_pixinfo.setText( "min: {}, max: {}".format(vmin, vmax)) self.status_sing_coord.setVisible(False) elif self.mainview.cur_tab in ("split", "fade"): vmin_l = self.mainview.sir_files['left']['vmin'] vmax_l = self.mainview.sir_files['left']['vmax'] vmin_r = self.mainview.sir_files['right']['vmin'] vmax_r = self.mainview.sir_files['right']['vmax'] self.status_stacked.setVisible(True) self.status_stacked.setCurrentIndex(1) self.status_left_pixinfo.setText( "min: {} max: {}".format(vmin_l, vmax_l)) self.status_right_pixinfo.setText( "min: {} max: {}".format(vmin_r, vmax_r)) self.status_comp_coord.setVisible(False) def update_statusbar_pos(self, x_im, y_im): """Update with position at image index x, y.""" self.statusBar().clearMessage() nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy # Convert from 0-based to 1-based indexing # (I've double-checked the values returned here using sir_util2a) y = nsy - y_im # Convert image y coord to SIR y coord x = x_im + 1 if x > 0 and y > 0 and x <= nsx and y <= nsy: # Note that sir_data is 0-based indexing, but pix2latlon is 1-based cur_sir = self.mainview.sir_files[self.mainview.cur_tab] lon, lat = libsir.pix2latlon(x, y, cur_sir['header']) if self.mainview.cur_tab in ("left", "right"): self.status_sing_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "value = {:0.4f}").format(x, y, lat, lon, cur_sir['data'][y_im, x_im]) self.status_sing_coord.setText(stat_text) elif self.mainview.cur_tab in ("split", "fade"): left_sir = self.mainview.sir_files['left'] right_sir = self.mainview.sir_files['right'] self.status_comp_coord.setVisible(True) stat_text = ("x = {}, y = {} " "lat = {:0.4f}, lon = {:0.4f} " "left value = {:0.4f} " "right value = {:0.4f}").format( x, y, lat, lon, left_sir['data'][y_im, x_im], right_sir['data'][y_im, x_im]) self.status_comp_coord.setText(stat_text) def sizeHint(self): """Override the suggested size.""" return QtCore.QSize(1000, 800) # Menu events @QtCore.Slot() def update_zoomer_opts(self, draw_win=True): """Given a menu change, this sets zoomer options and updates.""" file_dict = self.mainview.sir_files[self.mainview.cur_tab] # Is zoomer enabled? file_dict['zoomer_on'] = self.zoomer_action.isChecked() # Find the zoom factor zfactor = self.zoom_factor_group.checkedAction() if zfactor is self.zoom_factor_1_action: file_dict['zoomer_factor'] = 2 elif zfactor is self.zoom_factor_2_action: file_dict['zoomer_factor'] = 4 elif zfactor is self.zoom_factor_3_action: file_dict['zoomer_factor'] = 8 elif zfactor is self.zoom_factor_4_action: file_dict['zoomer_factor'] = 16 # Find the zoom size zsize = self.zoom_size_group.checkedAction() if zsize is self.zoom_size_1_action: file_dict['zoomer_size'] = 9 elif zsize is self.zoom_size_2_action: file_dict['zoomer_size'] = 17 elif zsize is self.zoom_size_3_action: file_dict['zoomer_size'] = 29 elif zsize is self.zoom_size_4_action: file_dict['zoomer_size'] = 45 elif zsize is self.zoom_size_5_action: file_dict['zoomer_size'] = 65 if draw_win: # Compute zoomer window size and show/hide it winsize = file_dict['zoomer_size'] * file_dict['zoomer_factor'] if self.mainview.cur_tab == "split": self.zoom_win.resize(2*winsize, winsize) self.zoom_win.setFixedSize(2*winsize, winsize) else: self.zoom_win.resize(winsize, winsize) self.zoom_win.setFixedSize(winsize, winsize) if file_dict['zoomer_on']: self.zoom_win.show() else: self.zoom_win.hide() # Update zoomer self.update_zoomer() # Keyboard events def keyPressEvent(self, key): """Handle some keypresses.""" if len(self.mainview.sir_files) == 0: key.ignore() return if 'pix_loc' not in self.mainview.sir_files[self.mainview.cur_tab]: # Don't do anything if we don't have a coord yet key.ignore() return # Increment im_pos if valid key # Note that im_pos is 0-based, so # it ranges from 0 to nsx-1/nsy-1 inclusive im_pos = self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] nsx = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsx nsy = self.mainview.sir_files[self.mainview.cur_tab]['header'].nsy delta = 5 if key.modifiers() == Qt.ShiftModifier else 1 if key.key() == Qt.Key_J: # Down if im_pos.y() + delta < nsy: im_pos.setY(im_pos.y() + delta) elif key.key() == Qt.Key_K: # Up if im_pos.y() - delta >= 0: im_pos.setY(im_pos.y() - delta) elif key.key() == Qt.Key_H: # Left if im_pos.x() - delta >= 0: im_pos.setX(im_pos.x() - delta) elif key.key() == Qt.Key_L: # Right if im_pos.x() + delta < nsx: im_pos.setX(im_pos.x() + delta) else: key.ignore() return # Update stuff with our new position self.mainview.sir_files[self.mainview.cur_tab]['pix_loc'] = im_pos self.update_zoomer() self.update_statusbar_pos(im_pos.x(), im_pos.y())
class PythonConsoleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle( QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) ##------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOut) self.splitter.addWidget(self.shell) #self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) #self.splitterObj.setSizes([0, 0]) #self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) #self.splitterEditor.addWidget(self.widgetEditor) #self.splitterObj.addWidget(self.listClassMethod) #self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() sizes = self.splitter.sizes() self.splitter.setSizes(sizes) ##----------------Restore Settings------------------------------------ self.restoreSettingsConsole() ##------------------Toolbar Editor------------------------------------- ## Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open file") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon( QgsApplication.getThemeIcon("console/iconOpenConsole.png")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) ## Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveConsole.png")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) ## Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon( QgsApplication.getThemeIcon("console/iconSaveAsConsole.png")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) ## Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconCutEditorConsole.png")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) ## Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) ## Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) ## Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconRunScriptConsole.png")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) ## Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconCommentEditorConsole.png")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) ## Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon( QgsApplication.getThemeIcon( "console/iconUncommentEditorConsole.png")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) ## Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled( self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon( QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) ## Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon( QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) ##----------------Toolbar Console------------------------------------- ## Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon( QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) ## Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon( QgsApplication.getThemeIcon("console/iconClearConsole.png")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) ## Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Settings") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon( QgsApplication.getThemeIcon("console/iconSettingsConsole.png")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) ## Action menu for class actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class") self.actionClass = QAction(self) self.actionClass.setCheckable(False) self.actionClass.setEnabled(True) self.actionClass.setIcon( QgsApplication.getThemeIcon("console/iconClassConsole.png")) self.actionClass.setMenuRole(QAction.PreferencesRole) self.actionClass.setIconVisibleInMenu(True) self.actionClass.setToolTip(actionClassBt) self.actionClass.setText(actionClassBt) ## Import Processing class loadProcessingBt = QCoreApplication.translate( "PythonConsole", "Import Processing class") self.loadProcessingButton = QAction(self) self.loadProcessingButton.setCheckable(False) self.loadProcessingButton.setEnabled(True) self.loadProcessingButton.setIcon( QgsApplication.getThemeIcon("console/iconProcessingConsole.png")) self.loadProcessingButton.setMenuRole(QAction.PreferencesRole) self.loadProcessingButton.setIconVisibleInMenu(True) self.loadProcessingButton.setToolTip(loadProcessingBt) self.loadProcessingButton.setText(loadProcessingBt) ## Import QtCore class loadQtCoreBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore class") self.loadQtCoreButton = QAction(self) self.loadQtCoreButton.setCheckable(False) self.loadQtCoreButton.setEnabled(True) self.loadQtCoreButton.setIcon( QgsApplication.getThemeIcon("console/iconQtCoreConsole.png")) self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole) self.loadQtCoreButton.setIconVisibleInMenu(True) self.loadQtCoreButton.setToolTip(loadQtCoreBt) self.loadQtCoreButton.setText(loadQtCoreBt) ## Import QtGui class loadQtGuiBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui class") self.loadQtGuiButton = QAction(self) self.loadQtGuiButton.setCheckable(False) self.loadQtGuiButton.setEnabled(True) self.loadQtGuiButton.setIcon( QgsApplication.getThemeIcon("console/iconQtGuiConsole.png")) self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole) self.loadQtGuiButton.setIconVisibleInMenu(True) self.loadQtGuiButton.setToolTip(loadQtGuiBt) self.loadQtGuiButton.setText(loadQtGuiBt) ## Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon( QgsApplication.getThemeIcon("console/iconRunConsole.png")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) ## Help action helpBt = QCoreApplication.translate("PythonConsole", "Help") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon( QgsApplication.getThemeIcon("console/iconHelpConsole.png")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(QSize(24, 24)) self.toolBar.setOrientation(Qt.Vertical) self.toolBar.setMovable(True) self.toolBar.setFloatable(True) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.actionClass) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() # self.toolBarEditor.setStyleSheet('QToolBar{background-color: rgb(%s, %s, %s' % tuple(bkgrcolor) + ');\ # border-right: 1px solid rgb(%s, %s, %s' % tuple(bordercl) + ');}') self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(QSize(18, 18)) self.toolBarEditor.setOrientation(Qt.Vertical) self.toolBarEditor.setMovable(True) self.toolBarEditor.setFloatable(True) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) ## Menu Import Class self.classMenu = QMenu() self.classMenu.addAction(self.loadProcessingButton) self.classMenu.addAction(self.loadQtCoreButton) self.classMenu.addAction(self.loadQtGuiButton) cM = self.toolBar.widgetForAction(self.actionClass) cM.setMenu(self.classMenu) cM.setPopupMode(QToolButton.InstantPopup) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) ##------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.widgetButtonEditor, 0, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 1, 1, 1, 1) self.toolBarLayout = QGridLayout(self.widgetButton) self.toolBarLayout.setMargin(0) self.toolBarLayout.setSpacing(0) self.toolBarLayout.addWidget(self.toolBar) self.toolBarEditorLayout = QGridLayout(self.widgetButtonEditor) self.toolBarEditorLayout.setMargin(0) self.toolBarEditorLayout.setSpacing(0) self.toolBarEditorLayout.addWidget(self.toolBarEditor) ## Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...") if pyqtconfig.Configuration().qt_version >= 0x40700: self.lineEditFind.setPlaceholderText(placeHolderTxt) else: self.lineEditFind.setToolTip(placeHolderTxt) self.findNextButton = QToolButton() self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchNextEditorConsole.png")) self.findNextButton.setIconSize(QSize(24, 24)) self.findNextButton.setAutoRaise(True) self.findPrevButton = QToolButton() self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon( QgsApplication.getThemeIcon( "console/iconSearchPrevEditorConsole.png")) self.findPrevButton.setIconSize(QSize(24, 24)) self.findPrevButton.setAutoRaise(True) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1) self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1) self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1) self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1) self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1) self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1) ##------------ Add first Tab in Editor ------------------------------- #self.tabEditorWidget.newTabEditor(tabName='first', filename=None) ##------------ Signal ------------------------------- self.findTextButton.toggled.connect(self.findTextEditor) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.loadProcessingButton.triggered.connect(self.processing) self.loadQtCoreButton.triggered.connect(self.qtCore) self.loadQtGuiButton.triggered.connect(self.qtGui) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.connect(self.listClassMethod, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findText) self.findNextButton.clicked.connect(self._findNext) self.findPrevButton.clicked.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) def _findText(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findNext(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findPrev(self): self.tabEditorWidget.currentWidget().newEditor.findText(False) def _textFindChanged(self): if self.lineEditFind.text(): self.findNextButton.setEnabled(True) self.findPrevButton.setEnabled(True) else: self.lineEditFind.setStyleSheet('') self.findNextButton.setEnabled(False) self.findPrevButton.setEnabled(False) def onClickGoToLine(self, item, column): tabEditor = self.tabEditorWidget.currentWidget().newEditor if item.text(1) == 'syntaxError': check = tabEditor.syntaxCheck(fromContextMenu=False) if check and not tabEditor.isReadOnly(): self.tabEditorWidget.currentWidget().save() return linenr = int(item.text(1)) itemName = str(item.text(0)) charPos = itemName.find(' ') if charPos != -1: objName = itemName[0:charPos] else: objName = itemName tabEditor.goToLine(objName, linenr) def processing(self): self.shell.commandConsole('processing') def qtCore(self): self.shell.commandConsole('qtCore') def qtGui(self): self.shell.commandConsole('qtGui') def toggleEditor(self, checked): self.splitterObj.show() if checked else self.splitterObj.hide() if not self.tabEditorWidget: self.tabEditorWidget.enableToolBarEditor(checked) self.tabEditorWidget.restoreTabsOrAddNew() def toggleObjectListWidget(self, checked): self.listClassMethod.show() if checked else self.listClassMethod.hide() def findTextEditor(self, checked): self.widgetFind.show() if checked else self.widgetFind.hide() def pasteEditor(self): self.tabEditorWidget.currentWidget().newEditor.paste() def cutEditor(self): self.tabEditorWidget.currentWidget().newEditor.cut() def copyEditor(self): self.tabEditorWidget.currentWidget().newEditor.copy() def runScriptEditor(self): self.tabEditorWidget.currentWidget().newEditor.runScriptCode() def commentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True) def uncommentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False) def openScriptFile(self): lastDirPath = self.settings.value("pythonConsole/lastDirPath", "") openFileTr = QCoreApplication.translate("PythonConsole", "Open File") fileList = QFileDialog.getOpenFileNames(self, openFileTr, lastDirPath, "Script file (*.py)") if fileList: for pyFile in fileList: for i in range(self.tabEditorWidget.count()): tabWidget = self.tabEditorWidget.widget(i) if tabWidget.path == pyFile: self.tabEditorWidget.setCurrentWidget(tabWidget) break else: tabName = QFileInfo(pyFile).fileName() self.tabEditorWidget.newTabEditor(tabName, pyFile) lastDirPath = QFileInfo(pyFile).path() self.settings.setValue("pythonConsole/lastDirPath", pyFile) self.updateTabListScript(pyFile, action='append') def saveScriptFile(self): tabWidget = self.tabEditorWidget.currentWidget() try: tabWidget.save() except (IOError, OSError), error: msgText = QCoreApplication.translate( 'PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format( tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False)
class ActionCollection(actioncollection.ActionCollection): name = "main" def createActions(self, parent=None): self.file_new = QAction(parent) self.file_open = QAction(parent) self.file_open_recent = QAction(parent) self.file_insert_file = QAction(parent) self.file_open_current_directory = QAction(parent) self.file_open_command_prompt = QAction(parent) self.file_save = QAction(parent) self.file_save_as = QAction(parent) self.file_save_copy_as = QAction(parent) self.file_save_all = QAction(parent) self.file_reload = QAction(parent) self.file_reload_all = QAction(parent) self.file_external_changes = QAction(parent) self.file_print_source = QAction(parent) self.file_close = QAction(parent) self.file_close_other = QAction(parent) self.file_close_all = QAction(parent) self.file_quit = QAction(parent) self.file_restart = QAction(parent) self.export_colored_html = QAction(parent) self.edit_undo = QAction(parent) self.edit_redo = QAction(parent) self.edit_cut = QAction(parent) self.edit_copy = QAction(parent) self.edit_copy_colored_html = QAction(parent) self.edit_paste = QAction(parent) self.edit_select_all = QAction(parent) self.edit_select_current_toplevel = QAction(parent) self.edit_select_none = QAction(parent) self.edit_select_full_lines_up = QAction(parent) self.edit_select_full_lines_down = QAction(parent) self.edit_find = QAction(parent) self.edit_find_next = QAction(parent) self.edit_find_previous = QAction(parent) self.edit_replace = QAction(parent) self.edit_preferences = QAction(parent) self.view_next_document = QAction(parent) self.view_previous_document = QAction(parent) self.view_wrap_lines = QAction(parent, checkable=True) self.view_scroll_up = QAction(parent) self.view_scroll_down = QAction(parent) self.window_new = QAction(parent) self.window_fullscreen = QAction(parent) self.window_fullscreen.setCheckable(True) self.help_manual = QAction(parent) self.help_whatsthis = QWhatsThis.createAction(parent) self.help_about = QAction(parent) self.help_bugreport = QAction(parent) # icons self.file_new.setIcon(icons.get('document-new')) self.file_open.setIcon(icons.get('document-open')) self.file_open_recent.setIcon(icons.get('document-open-recent')) self.file_open_current_directory.setIcon(icons.get('folder-open')) self.file_open_command_prompt.setIcon(icons.get('utilities-terminal')) self.file_save.setIcon(icons.get('document-save')) self.file_save_as.setIcon(icons.get('document-save-as')) self.file_save_copy_as.setIcon(icons.get('document-save-as')) self.file_save_all.setIcon(icons.get('document-save-all')) self.file_reload.setIcon(icons.get('reload')) self.file_reload_all.setIcon(icons.get('reload-all')) self.file_print_source.setIcon(icons.get('document-print')) self.file_close.setIcon(icons.get('document-close')) self.file_quit.setIcon(icons.get('application-exit')) self.edit_undo.setIcon(icons.get('edit-undo')) self.edit_redo.setIcon(icons.get('edit-redo')) self.edit_cut.setIcon(icons.get('edit-cut')) self.edit_copy.setIcon(icons.get('edit-copy')) self.edit_paste.setIcon(icons.get('edit-paste')) self.edit_select_all.setIcon(icons.get('edit-select-all')) self.edit_select_current_toplevel.setIcon(icons.get('edit-select')) self.edit_find.setIcon(icons.get('edit-find')) self.edit_find_next.setIcon(icons.get('go-down-search')) self.edit_find_previous.setIcon(icons.get('go-up-search')) self.edit_replace.setIcon(icons.get('edit-find-replace')) self.edit_preferences.setIcon(icons.get('preferences-system')) self.view_next_document.setIcon(icons.get('go-next')) self.view_previous_document.setIcon(icons.get('go-previous')) self.window_new.setIcon(icons.get('window-new')) self.window_fullscreen.setIcon(icons.get('view-fullscreen')) self.help_manual.setIcon(icons.get('help-contents')) self.help_whatsthis.setIcon(icons.get('help-contextual')) self.help_bugreport.setIcon(icons.get('tools-report-bug')) self.help_about.setIcon(icons.get('help-about')) # shortcuts self.file_new.setShortcuts(QKeySequence.New) self.file_open.setShortcuts(QKeySequence.Open) self.file_save.setShortcuts(QKeySequence.Save) self.file_save_as.setShortcuts(QKeySequence.SaveAs) self.file_close.setShortcuts(QKeySequence.Close) self.file_quit.setShortcuts(QKeySequence.Quit) self.edit_undo.setShortcuts(QKeySequence.Undo) self.edit_redo.setShortcuts(QKeySequence.Redo) self.edit_cut.setShortcuts(QKeySequence.Cut) self.edit_copy.setShortcuts(QKeySequence.Copy) self.edit_paste.setShortcuts(QKeySequence.Paste) self.edit_select_all.setShortcuts(QKeySequence.SelectAll) self.edit_select_current_toplevel.setShortcut(QKeySequence(Qt.SHIFT+Qt.CTRL+Qt.Key_B)) self.edit_select_none.setShortcut(QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_A)) self.edit_select_full_lines_up.setShortcut(QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_Up)) self.edit_select_full_lines_down.setShortcut(QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_Down)) self.edit_find.setShortcuts(QKeySequence.Find) self.edit_find_next.setShortcuts(QKeySequence.FindNext) self.edit_find_previous.setShortcuts(QKeySequence.FindPrevious) self.edit_replace.setShortcuts(QKeySequence.Replace) self.edit_preferences.setShortcuts(QKeySequence.Preferences) self.view_next_document.setShortcuts(QKeySequence.Forward) self.view_previous_document.setShortcuts(QKeySequence.Back) self.view_scroll_up.setShortcut(Qt.CTRL + Qt.Key_Up) self.view_scroll_down.setShortcut(Qt.CTRL + Qt.Key_Down) self.window_fullscreen.setShortcuts([QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_F), QKeySequence(Qt.Key_F11)]) self.help_manual.setShortcuts(QKeySequence.HelpContents) # Mac OS X-specific roles? if sys.platform.startswith('darwin'): import macosx if macosx.use_osx_menu_roles(): self.file_quit.setMenuRole(QAction.QuitRole) self.edit_preferences.setMenuRole(QAction.PreferencesRole) self.help_about.setMenuRole(QAction.AboutRole) else: self.file_quit.setMenuRole(QAction.NoRole) self.edit_preferences.setMenuRole(QAction.NoRole) self.help_about.setMenuRole(QAction.NoRole) def translateUI(self): self.file_new.setText(_("action: new document", "&New")) self.file_open.setText(_("&Open...")) self.file_open_recent.setText(_("Open &Recent")) self.file_insert_file.setText(_("Insert from &File...")) self.file_open_current_directory.setText(_("Open Current Directory")) self.file_open_command_prompt.setText(_("Open Command Prompt")) self.file_save.setText(_("&Save")) self.file_save_as.setText(_("Save &As...")) self.file_save_copy_as.setText(_("Save Copy or Selection As...")) self.file_save_all.setText(_("Save All")) self.file_reload.setText(_("Re&load")) self.file_reload_all.setText(_("Reload All")) self.file_external_changes.setText(_("Check for External Changes...")) self.file_external_changes.setToolTip(_( "Opens a window to check whether open documents were changed or " "deleted by other programs.")) self.file_print_source.setText(_("Print Source...")) self.file_close.setText(_("&Close")) self.file_close_other.setText(_("Close Other Documents")) self.file_close_all.setText(_("Close All Documents and Session")) self.file_close_all.setToolTip(_("Closes all documents and leaves the current session.")) self.file_quit.setText(_("&Quit")) self.file_restart.setText(_("Restart {appname}").format(appname=appinfo.appname)) self.export_colored_html.setText(_("Export Source as Colored &HTML...")) self.edit_undo.setText(_("&Undo")) self.edit_redo.setText(_("Re&do")) self.edit_cut.setText(_("Cu&t")) self.edit_copy.setText(_("&Copy")) self.edit_copy_colored_html.setText(_("Copy as Colored &HTML")) self.edit_paste.setText(_("&Paste")) self.edit_select_all.setText(_("Select &All")) self.edit_select_current_toplevel.setText(_("Select &Block")) self.edit_select_none.setText(_("Select &None")) self.edit_select_full_lines_up.setText(_("Select Whole Lines Up")) self.edit_select_full_lines_down.setText(_("Select Whole Lines Down")) self.edit_find.setText(_("&Find...")) self.edit_find_next.setText(_("Find Ne&xt")) self.edit_find_previous.setText(_("Find Pre&vious")) self.edit_replace.setText(_("&Replace...")) self.edit_preferences.setText(_("Pr&eferences...")) self.view_next_document.setText(_("&Next Document")) self.view_previous_document.setText(_("&Previous Document")) self.view_wrap_lines.setText(_("Wrap &Lines")) self.view_scroll_up.setText(_("Scroll Up")) self.view_scroll_down.setText(_("Scroll Down")) self.window_new.setText(_("New &Window")) self.window_fullscreen.setText(_("&Fullscreen")) self.help_manual.setText(_("&User Guide")) self.help_whatsthis.setText(_("&What's This?")) self.help_bugreport.setText(_("Report a &Bug...")) self.help_about.setText(_("&About {appname}...").format(appname=appinfo.appname))
class ActionCollection(actioncollection.ActionCollection): name = "main" def createActions(self, parent=None): self.file_new = QAction(parent) self.file_open = QAction(parent) self.file_open_recent = QAction(parent) self.file_insert_file = QAction(parent) self.file_open_current_directory = QAction(parent) self.file_open_command_prompt = QAction(parent) self.file_save = QAction(parent) self.file_save_as = QAction(parent) self.file_save_copy_as = QAction(parent) self.file_save_all = QAction(parent) self.file_reload = QAction(parent) self.file_reload_all = QAction(parent) self.file_external_changes = QAction(parent) self.file_print_source = QAction(parent) self.file_close = QAction(parent) self.file_close_other = QAction(parent) self.file_close_all = QAction(parent) self.file_quit = QAction(parent) self.file_restart = QAction(parent) self.export_colored_html = QAction(parent) self.edit_undo = QAction(parent) self.edit_redo = QAction(parent) self.edit_cut = QAction(parent) self.edit_copy = QAction(parent) self.edit_copy_colored_html = QAction(parent) self.edit_paste = QAction(parent) self.edit_select_all = QAction(parent) self.edit_select_current_toplevel = QAction(parent) self.edit_select_none = QAction(parent) self.edit_select_full_lines_up = QAction(parent) self.edit_select_full_lines_down = QAction(parent) self.edit_find = QAction(parent) self.edit_find_next = QAction(parent) self.edit_find_previous = QAction(parent) self.edit_replace = QAction(parent) self.edit_preferences = QAction(parent) self.view_next_document = QAction(parent) self.view_previous_document = QAction(parent) self.view_wrap_lines = QAction(parent, checkable=True) self.view_scroll_up = QAction(parent) self.view_scroll_down = QAction(parent) self.window_new = QAction(parent) self.window_fullscreen = QAction(parent) self.window_fullscreen.setCheckable(True) self.help_manual = QAction(parent) self.help_whatsthis = QWhatsThis.createAction(parent) self.help_about = QAction(parent) self.help_bugreport = QAction(parent) # icons self.file_new.setIcon(icons.get('document-new')) self.file_open.setIcon(icons.get('document-open')) self.file_open_recent.setIcon(icons.get('document-open-recent')) self.file_open_current_directory.setIcon(icons.get('folder-open')) self.file_open_command_prompt.setIcon(icons.get('utilities-terminal')) self.file_save.setIcon(icons.get('document-save')) self.file_save_as.setIcon(icons.get('document-save-as')) self.file_save_copy_as.setIcon(icons.get('document-save-as')) self.file_save_all.setIcon(icons.get('document-save-all')) self.file_reload.setIcon(icons.get('reload')) self.file_reload_all.setIcon(icons.get('reload-all')) self.file_print_source.setIcon(icons.get('document-print')) self.file_close.setIcon(icons.get('document-close')) self.file_quit.setIcon(icons.get('application-exit')) self.edit_undo.setIcon(icons.get('edit-undo')) self.edit_redo.setIcon(icons.get('edit-redo')) self.edit_cut.setIcon(icons.get('edit-cut')) self.edit_copy.setIcon(icons.get('edit-copy')) self.edit_paste.setIcon(icons.get('edit-paste')) self.edit_select_all.setIcon(icons.get('edit-select-all')) self.edit_select_current_toplevel.setIcon(icons.get('edit-select')) self.edit_find.setIcon(icons.get('edit-find')) self.edit_find_next.setIcon(icons.get('go-down-search')) self.edit_find_previous.setIcon(icons.get('go-up-search')) self.edit_replace.setIcon(icons.get('edit-find-replace')) self.edit_preferences.setIcon(icons.get('preferences-system')) self.view_next_document.setIcon(icons.get('go-next')) self.view_previous_document.setIcon(icons.get('go-previous')) self.window_new.setIcon(icons.get('window-new')) self.window_fullscreen.setIcon(icons.get('view-fullscreen')) self.help_manual.setIcon(icons.get('help-contents')) self.help_whatsthis.setIcon(icons.get('help-contextual')) self.help_bugreport.setIcon(icons.get('tools-report-bug')) self.help_about.setIcon(icons.get('help-about')) # shortcuts self.file_new.setShortcuts(QKeySequence.New) self.file_open.setShortcuts(QKeySequence.Open) self.file_save.setShortcuts(QKeySequence.Save) self.file_save_as.setShortcuts(QKeySequence.SaveAs) self.file_close.setShortcuts(QKeySequence.Close) self.file_quit.setShortcuts(QKeySequence.Quit) self.edit_undo.setShortcuts(QKeySequence.Undo) self.edit_redo.setShortcuts(QKeySequence.Redo) self.edit_cut.setShortcuts(QKeySequence.Cut) self.edit_copy.setShortcuts(QKeySequence.Copy) self.edit_paste.setShortcuts(QKeySequence.Paste) self.edit_select_all.setShortcuts(QKeySequence.SelectAll) self.edit_select_current_toplevel.setShortcut( QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_B)) self.edit_select_none.setShortcut( QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_A)) self.edit_select_full_lines_up.setShortcut( QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_Up)) self.edit_select_full_lines_down.setShortcut( QKeySequence(Qt.SHIFT + Qt.CTRL + Qt.Key_Down)) self.edit_find.setShortcuts(QKeySequence.Find) self.edit_find_next.setShortcuts(QKeySequence.FindNext) self.edit_find_previous.setShortcuts(QKeySequence.FindPrevious) self.edit_replace.setShortcuts(QKeySequence.Replace) self.edit_preferences.setShortcuts(QKeySequence.Preferences) self.view_next_document.setShortcuts(QKeySequence.Forward) self.view_previous_document.setShortcuts(QKeySequence.Back) self.view_scroll_up.setShortcut(Qt.CTRL + Qt.Key_Up) self.view_scroll_down.setShortcut(Qt.CTRL + Qt.Key_Down) self.window_fullscreen.setShortcuts([ QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_F), QKeySequence(Qt.Key_F11) ]) self.help_manual.setShortcuts(QKeySequence.HelpContents) # Mac OS X-specific roles? if sys.platform.startswith('darwin'): import macosx if macosx.use_osx_menu_roles(): self.file_quit.setMenuRole(QAction.QuitRole) self.edit_preferences.setMenuRole(QAction.PreferencesRole) self.help_about.setMenuRole(QAction.AboutRole) else: self.file_quit.setMenuRole(QAction.NoRole) self.edit_preferences.setMenuRole(QAction.NoRole) self.help_about.setMenuRole(QAction.NoRole) def translateUI(self): self.file_new.setText(_("action: new document", "&New")) self.file_open.setText(_("&Open...")) self.file_open_recent.setText(_("Open &Recent")) self.file_insert_file.setText(_("Insert from &File...")) self.file_open_current_directory.setText(_("Open Current Directory")) self.file_open_command_prompt.setText(_("Open Command Prompt")) self.file_save.setText(_("&Save")) self.file_save_as.setText(_("Save &As...")) self.file_save_copy_as.setText(_("Save Copy or Selection As...")) self.file_save_all.setText(_("Save All")) self.file_reload.setText(_("Re&load")) self.file_reload_all.setText(_("Reload All")) self.file_external_changes.setText(_("Check for External Changes...")) self.file_external_changes.setToolTip( _("Opens a window to check whether open documents were changed or " "deleted by other programs.")) self.file_print_source.setText(_("Print Source...")) self.file_close.setText(_("&Close")) self.file_close_other.setText(_("Close Other Documents")) self.file_close_all.setText(_("Close All Documents and Session")) self.file_close_all.setToolTip( _("Closes all documents and leaves the current session.")) self.file_quit.setText(_("&Quit")) self.file_restart.setText( _("Restart {appname}").format(appname=appinfo.appname)) self.export_colored_html.setText( _("Export Source as Colored &HTML...")) self.edit_undo.setText(_("&Undo")) self.edit_redo.setText(_("Re&do")) self.edit_cut.setText(_("Cu&t")) self.edit_copy.setText(_("&Copy")) self.edit_copy_colored_html.setText(_("Copy as Colored &HTML")) self.edit_paste.setText(_("&Paste")) self.edit_select_all.setText(_("Select &All")) self.edit_select_current_toplevel.setText(_("Select &Block")) self.edit_select_none.setText(_("Select &None")) self.edit_select_full_lines_up.setText(_("Select Whole Lines Up")) self.edit_select_full_lines_down.setText(_("Select Whole Lines Down")) self.edit_find.setText(_("&Find...")) self.edit_find_next.setText(_("Find Ne&xt")) self.edit_find_previous.setText(_("Find Pre&vious")) self.edit_replace.setText(_("&Replace...")) self.edit_preferences.setText(_("Pr&eferences...")) self.view_next_document.setText(_("&Next Document")) self.view_previous_document.setText(_("&Previous Document")) self.view_wrap_lines.setText(_("Wrap &Lines")) self.view_scroll_up.setText(_("Scroll Up")) self.view_scroll_down.setText(_("Scroll Down")) self.window_new.setText(_("New &Window")) self.window_fullscreen.setText(_("&Fullscreen")) self.help_manual.setText(_("&User Guide")) self.help_whatsthis.setText(_("&What's This?")) self.help_bugreport.setText(_("Report a &Bug...")) self.help_about.setText( _("&About {appname}...").format(appname=appinfo.appname))