class modulesManager(QWidget): def __init__(self, parent): QWidget.__init__(self, parent) self.name = "moduleManager" self.stacked = stackedWidget(self) self.initWidget() self.initShape() def initWidget(self): self.toolbox = tabBox(self) def initShape(self): self.mainvbox = QVBoxLayout() self.splitter = QSplitter() self.splitter.setOrientation(Qt.Vertical) self.splitter.addWidget(self.toolbox) self.splitter.addWidget(self.stacked) self.mainvbox.addWidget(self.splitter) self.setLayout(self.mainvbox) cw = self.toolbox.currentWidget() cw.setCurrentItem(cw.item(0)) cw.emit(SIGNAL("itemPressed(QListWidgetItem *)"), cw.item(0)) def execute(self): args = self.stacked.currentWidget().validateModule() self.stacked.currentWidget().launchTask(args)
def test_dock(self): reg = global_registry() reg = QtWidgetRegistry(reg, parent=self.app) toolbox = WidgetToolBox() toolbox.setObjectName("widgets-toolbox") toolbox.setModel(reg.model()) text = QTextEdit() splitter = QSplitter() splitter.setOrientation(Qt.Vertical) splitter.addWidget(toolbox) splitter.addWidget(text) dock = CollapsibleDockWidget() dock.setExpandedWidget(splitter) toolbar = QToolBar() toolbar.addAction("1") toolbar.setOrientation(Qt.Vertical) toolbar.setMovable(False) toolbar.setFloatable(False) dock.setCollapsedWidget(toolbar) dock.show() self.app.exec_()
def _create_terminal(self): assert self._terminal is None, \ "should only call _create_terminal once" self._terminal_button = QToolButton(None) self._terminal_button.setToolTip("Toggle command line") self._ui.layerWidget.button_row.addWidget(self._terminal_button) self._terminal_button.setArrowType(Qt.DownArrow) try: from .widgets.terminal import glue_terminal widget = glue_terminal(data_collection=self._data, dc=self._data, hub=self._hub, **vars(env)) self._terminal_button.clicked.connect(self._toggle_terminal) except Exception as e: # pylint: disable=W0703 import traceback self._terminal_exception = traceback.format_exc() self._setup_terminal_error_dialog(e) return splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(self._ui.centralwidget) splitter.addWidget(widget) splitter.setStretchFactor(0, 5) splitter.setStretchFactor(1, 1) self.setCentralWidget(splitter) self._terminal = widget self._hide_terminal()
def createWidget(self): """ Create the widget """ self.diagramScene = QGraphicsScene(self) self.view = QGraphicsView(self.diagramScene) self.view.setRenderHint(QPainter.Antialiasing) # set the main layout layout = QVBoxLayout() self.logEdit = QTextEdit() self.logEdit.setReadOnly(True) hSplitter2 = QSplitter(self) hSplitter2.setOrientation(Qt.Vertical) hSplitter2.addWidget(self.view) hSplitter2.addWidget(self.logEdit) hSplitter2.setStretchFactor(0, 1) layout.addWidget(hSplitter2) self.setLayout(layout)
class CanvasToolDock(QWidget): """Canvas dock widget with widget toolbox, quick help and canvas actions. """ def __init__(self, parent=None, **kwargs): QWidget.__init__(self, parent, **kwargs) self.__setupUi() def __setupUi(self): layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) self.toolbox = WidgetToolBox() self.help = QuickHelpWidget(objectName="quick-help") self.__splitter = QSplitter() self.__splitter.setOrientation(Qt.Vertical) self.__splitter.addWidget(self.toolbox) self.__splitter.addWidget(self.help) self.toolbar = DynamicResizeToolBar() self.toolbar.setMovable(False) self.toolbar.setFloatable(False) self.toolbar.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) layout.addWidget(self.__splitter, 10) layout.addWidget(self.toolbar) self.setLayout(layout) self.__splitterResizer = SplitterResizer() self.__splitterResizer.setSplitterAndWidget(self.__splitter, self.help) def setQuickHelpVisible(self, state): """Set the quick help box visibility status. """ self.__splitterResizer.setExpanded(state) def quickHelpVisible(self): return self.__splitterResizer.expanded() def setQuickHelpAnimationEnabled(self, enabled): """Enable/disable the quick help animation. """ self.__splitterResizer.setAnimationEnabled(enabled) def toogleQuickHelpAction(self): """Return a checkable QAction for help show/hide. """ return self.__splitterResizer.toogleExpandedAction()
def initUI(self): layout = QVBoxLayout(self) #Input part input_label = QLabel(inputlabeltext, self) input_label.setWordWrap(True) input_field = QLineEdit("MOM: Oh, good!", self) input_search = QPushButton("Search!", self) splitview = QSplitter(self) splitview.setOrientation(Qt.Vertical) splitview.setChildrenCollapsible(False) #Results list results_label = QLabel(resultslabeltext, self) results_label.setWordWrap(True) results_list = QTreeWidget() results_list.setColumnCount(3) #pointer, refs to pointer, text results_list.header().resizeSection(0, 100) results_list.header().resizeSection(1, 40) results_list.setFocusPolicy(Qt.NoFocus) #results_list.setMaximumSize(QSize(16777215, 100)) stringeditor = self.scripteditcontroller.getview() #Pack all into the layout layout.addWidget(input_label) layout.addWidget(input_field) layout.addWidget(input_search) layout.addWidget(results_label) #layout.addWidget(results_list) #layout.addWidget(stringeditor) splitview.addWidget(results_list) splitview.addWidget(stringeditor) splitview.setSizes([100, 500]) layout.addWidget(splitview) #Connect to actions input_search.clicked.connect(self.searchClick) results_list.itemSelectionChanged.connect(self.resultSelected) #Keeps some elements for later use self.input_field = input_field self.results_list = results_list self.stringeditor = stringeditor #Show the widget self.move(300, 150) self.setWindowTitle('Pokemon GBA String Editor') self.show()
class Window(QWidget): def __init__(self): super().__init__() self.setMinimumSize(1024, 600) self.setWindowTitle("QWebview-plus for Kiwoom") self.view = KiwoomWebViewPlus() self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) layout = QVBoxLayout(self) layout.setMargin(0) layout.addWidget(self.splitter) self.splitter.addWidget(self.view) self.splitter.addWidget(self.view.webInspector)
def __init_widgets__(self): """ Initialise the widgets of the window. """ # The Address/Attachment portion of the window self.attach_model = MessageAttachmentModel() attach_list = QListView() attach_list.setModel(self.attach_model) tab_bar_pxm = QPixmap('res/msg_tabbar_r.png') self.tab_bar = QTabWidget() self.tab_bar.setTabPosition(2) self.tab_bar.setIconSize(QSize(16, 16)) self.tab_bar.addTab(QWidget(), QIcon(tab_bar_pxm.copy(0, 0, 16, 16)), '') self.tab_bar.addTab(attach_list, QIcon(tab_bar_pxm.copy(0, 16, 16, 16)), '') # The Composition Properties portion of the window self.subject_line = QLineEdit() self.subject_line.setPlaceholderText('Subject') QObject.connect(self.subject_line, SIGNAL('textEdited(QString)'), self.update_title) priority_label = QLabel('Priority:') priority_dropdown = QComboBox(self) priority_dropdown.addItems( ['Highest', 'High', 'Normal', 'Low', 'Lowest']) subject_prio_layout = QHBoxLayout() subject_prio_layout.addWidget(self.subject_line) # subject_prio_layout.addStretch(1) subject_prio_layout.addWidget(priority_label) subject_prio_layout.addWidget(priority_dropdown) # The actual Composition portion of the window self.message = MessageTextEdit(self) # The bottom pane bottom_pane_layout = QVBoxLayout() bottom_pane_layout.addLayout(subject_prio_layout) bottom_pane_layout.addWidget(self.message) bottom_pane = QWidget() bottom_pane.setLayout(bottom_pane_layout) # Central widget is the splitter splitter = QSplitter() splitter.setOrientation(2) splitter.addWidget(self.tab_bar) splitter.addWidget(bottom_pane) self.setCentralWidget(splitter)
def setObject(self, mobj): element = moose.element(mobj) try: view = self.view_dict[element] except KeyError: view = ObjectEditView(element) self.view_dict[element] = view view.model().objectNameChanged.connect(self.emitObjectNameChanged) view.colorDialog.colorSelected.connect( lambda color: self.colorChanged.emit(element, color)) textEdit = QTextEdit() view.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) textEdit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) base = QSplitter() base.setOrientation(PyQt4.QtCore.Qt.Vertical) layout = QVBoxLayout() layout.addWidget(view) #, 0, 0) lineedit = QtGui.QLineEdit("Notes:") lineedit.setReadOnly(True) layout.addWidget(lineedit) if (isinstance(mobj, moose.PoolBase) or isinstance(mobj, moose.ReacBase) or isinstance(mobj, moose.EnzBase)): info = moose.Annotator(mobj.path + '/info') textEdit.setText(QtCore.QString(info.getField('notes'))) textEdit.textChanged.connect( lambda: info.setField('notes', str(textEdit.toPlainText()))) layout.addWidget(textEdit) #,1,0) # self.setRowHeight(notesIndex, self.rowHeight(notesIndex) * 3) base.setLayout(layout) # base.setSizes( [ view.height() # , base.height() - view.height() # ] # ) # print("a =>", view.height()) # print("b =>", base.height()) # layout.setStretch(0,3) # layout.setStretch(1,1) # layout.setContentsMargins(QMargins(0,0,0,0)) self.setWidget(base) self.setWindowTitle('Edit: %s' % (element.path)) view.update()
def setObject(self, mobj): element = moose.element(mobj) try: view = self.view_dict[element] except KeyError: view = ObjectEditView(element) self.view_dict[element] = view view.model().objectNameChanged.connect(self.emitObjectNameChanged) view.colorDialog.colorSelected.connect(lambda color: self.colorChanged.emit(element, color)) textEdit = QTextEdit() view.setSizePolicy( QSizePolicy.Ignored , QSizePolicy.Ignored ) textEdit.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) base = QSplitter() base.setOrientation(PyQt4.QtCore.Qt.Vertical) layout = QVBoxLayout() layout.addWidget(view)#, 0, 0) if ( isinstance(mobj, moose.PoolBase) or isinstance(mobj,moose.ReacBase) or isinstance(mobj,moose.EnzBase) ) : info = moose.Annotator(mobj.path +'/info') textEdit.setText(QtCore.QString(info.getField('notes'))) textEdit.textChanged.connect(lambda : info.setField('notes', str(textEdit.toPlainText()))) layout.addWidget(textEdit)#,1,0) # self.setRowHeight(notesIndex, self.rowHeight(notesIndex) * 3) base.setLayout(layout) # base.setSizes( [ view.height() # , base.height() - view.height() # ] # ) # print("a =>", view.height()) # print("b =>", base.height()) # layout.setStretch(0,3) # layout.setStretch(1,1) # layout.setContentsMargins(QMargins(0,0,0,0)) self.setWidget(base) self.setWindowTitle('Edit: %s' % (element.path)) view.update()
def createWidgets(self): """ QtWidgets creation _______________________ | | | PyEditor | |_______________________| |________QSplitter______| | | | PyEditor | |_______________________| """ self.srcWidget = EditorWidget( self.TEST_DEF_EDITOR, "Test Definition:", self, wrappingText=QtHelper.str2bool( Settings.instance().readValue(key='Editor/code-wrapping'))) self.execWidget = EditorWidget( self.TEST_EXEC_EDITOR, "Test Execution:", self, wrappingText=QtHelper.str2bool( Settings.instance().readValue(key='Editor/code-wrapping')), toolbar=False) self.srcEditor = self.srcWidget.editor self.execEditor = self.execWidget.editor layout = QVBoxLayout() hSplitter = QSplitter(self) hSplitter.setOrientation(Qt.Vertical) hSplitter.addWidget(self.srcWidget) hSplitter.addWidget(self.execWidget) hSplitter.setContentsMargins(0, 0, 0, 0) hSplitter.setStretchFactor(0, 1) layout.addWidget(hSplitter) layout.setContentsMargins(2, 0, 0, 0) self.setLayout(layout)
class NetWorthView(AccountSheetView): def _setup(self): self._setupUi() self.sheet = self.nwsheet = NetWorthSheet(self.model.bsheet, view=self.treeView) self.graph = self.nwgraph = Chart(self.model.nwgraph, view=self.graphView) self.piechart = Chart(self.model.pie, view=self.pieChart) def _setupUi(self): self.resize(558, 447) self.mainLayout = QVBoxLayout(self) self.mainLayout.setSpacing(0) self.mainLayout.setMargin(0) self.splitterView = QSplitter() self.splitterView.setChildrenCollapsible(False) self.splitterView.setOrientation(Qt.Vertical) self.subSplitterView = QSplitter() self.subSplitterView.setChildrenCollapsible(False) self.treeView = TreeView(self) self.treeView.setAcceptDrops(True) self.treeView.setFrameShape(QFrame.NoFrame) self.treeView.setFrameShadow(QFrame.Plain) self.treeView.setEditTriggers(QAbstractItemView.EditKeyPressed|QAbstractItemView.SelectedClicked) self.treeView.setDragEnabled(True) self.treeView.setDragDropMode(QAbstractItemView.InternalMove) self.treeView.setUniformRowHeights(True) self.treeView.setAllColumnsShowFocus(True) self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection) self.treeView.header().setStretchLastSection(False) self.subSplitterView.addWidget(self.treeView) self.pieChart = PieChartView(self) self.pieChart.setMinimumSize(300, 0) self.subSplitterView.addWidget(self.pieChart) self.splitterView.addWidget(self.subSplitterView) self.graphView = LineGraphView(self) self.graphView.setMinimumSize(0, 200) self.splitterView.addWidget(self.graphView) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.subSplitterView.setStretchFactor(0, 1) self.subSplitterView.setStretchFactor(1, 0) self.mainLayout.addWidget(self.splitterView)
def g_display(self): QWidget.__init__(self) layout = QHBoxLayout(self) splitter = QSplitter() layout.addWidget(splitter) splitter.setOrientation(Qt.Horizontal) if self.node is not None: processus_manager = ModuleProcessusManager() evt = processus_manager.get('evt') if not self.preview: self.evtWidget = evt.getAllEvtFiles() if self.evtWidget: splitter.addWidget(self.evtWidget) splitter.setStretchFactor(1, 2) else: self.evtWidget = evt.previewWidget(long(self.node.this)) if self.evtWidget: splitter.addWidget(self.evtWidget)
def setup_layout(self): outer_layout = QVBoxLayout() outer_layout.addWidget(self.menu_bar) outer_layout.setStretch(0, 1) h_splitter = QSplitter(self) h_splitter.setOrientation(Qt.Horizontal) # FIRST COLUMN of h_splitter is chromatogram + peakmap: ############################ v_splitter1 = QSplitter(self) v_splitter1.setOrientation(Qt.Vertical) v_splitter1.addWidget(self.eic_plotter) v_splitter1.addWidget(self.peakmap_plotter) self.peakmap_plotter.setMinimumSize(250, 200) v_splitter1.setStretchFactor(0, 1) v_splitter1.setStretchFactor(1, 3) h_splitter.addWidget(v_splitter1) h_splitter.setStretchFactor(0, 2) # SECOND COLUMN of h_splittier holds controlx boxes + mz plot ####################### v_splitter2 = QSplitter(self) v_splitter2.setOrientation(Qt.Vertical) v_splitter2.addWidget(self.image_scaling_widget) v_splitter2.addWidget(self.spectra_selector_widget) v_splitter2.addWidget(self.view_range_widget) v_splitter2.addWidget(self.history_list) v_splitter2.addWidget(self.mz_plotter) v_splitter2.setStretchFactor(0, 0) v_splitter2.setStretchFactor(1, 0) v_splitter2.setStretchFactor(2, 0) v_splitter2.setStretchFactor(3, 0) v_splitter2.setStretchFactor(4, 1) h_splitter.addWidget(v_splitter2) h_splitter.setStretchFactor(1, 1) # THIRD COLUMN of h_splittier holds control table + buttons ########################## if self.table: frame = QFrame(self) layout = QVBoxLayout(frame) frame.setLayout(layout) layout.addWidget(self.table_widget) button_row_layout = QHBoxLayout(frame) button_row_layout.addWidget(self.select_all_peaks) button_row_layout.addWidget(self.unselect_all_peaks) button_row_layout.addWidget(self.done_button) layout.addLayout(button_row_layout) h_splitter.addWidget(frame) h_splitter.setStretchFactor(2, 2) outer_layout.addWidget(h_splitter) self.setLayout(outer_layout) outer_layout.setStretch(1, 99)
def splitViewSpace(self, viewspace, orientation): """Split the given view. If orientation == Qt.Horizontal, adds a new view to the right. If orientation == Qt.Vertical, adds a new view to the bottom. """ active = viewspace is self.activeViewSpace() splitter = viewspace.parentWidget() newspace = ViewSpace(self) if splitter.count() == 1: splitter.setOrientation(orientation) size = splitter.sizes()[0] splitter.addWidget(newspace) splitter.setSizes([size / 2, size / 2]) elif splitter.orientation() == orientation: index = splitter.indexOf(viewspace) splitter.insertWidget(index + 1, newspace) else: index = splitter.indexOf(viewspace) newsplitter = QSplitter() newsplitter.setOrientation(orientation) sizes = splitter.sizes() splitter.insertWidget(index, newsplitter) newsplitter.addWidget(viewspace) splitter.setSizes(sizes) size = newsplitter.sizes()[0] newsplitter.addWidget(newspace) newsplitter.setSizes([size / 2, size / 2]) self._viewSpaces.insert(0, newspace) newspace.showDocument(viewspace.document()) if active: newspace.activeView().setFocus() self.actionCollection.window_close_view.setEnabled(self.canCloseViewSpace()) self.actionCollection.window_close_others.setEnabled(self.canCloseViewSpace())
class NetCDF3Browser(QWidget): """netCDF-Browser""" def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate('NetCDF3', 'Open...')) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate('NetCDF3', 'Open a netCDF3 file')) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL('pressed()'), self.loadFile) self.dropButton = QToolButton(self.toolBar) self.dropButton.setText(QCoreApplication.translate('NetCDF3', 'Close All')) self.dropButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.clear))) self.dropButton.setToolTip(QCoreApplication.translate('NetCDF3', 'Drop all open netCDF3 files')) self.toolBarLayout.addWidget(self.dropButton) self.connect(self.dropButton, SIGNAL('pressed()'), self.dropFiles) self.dropButton.setEnabled(False) self.toolBarLayout.addStretch(100) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 90) self.splitter.setStretchFactor(1, 10) self.model = NetCDF3Model() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) ftActions = SimuVis4.Globals.fileTypeActions ftActions.addAction(self.loadFile, ('application/x-netcdf',), QCoreApplication.translate('NetCDF3', 'Open in netCDF3 browser'), 10) def loadFile(self, fn=None): if not fn: fn = QFileDialog.getOpenFileName(self, QCoreApplication.translate('NetCDF3', "Select netCDF3 file to open"), SimuVis4.Globals.defaultFolder) if not fn.isEmpty(): fn = unicode(fn) SimuVis4.Globals.defaultFolder, tmp = os.path.split(fn) else: return self.model.addNcFile(fn) SimuVis4.Globals.dataBrowser.toolBox.setCurrentWidget(self) def dropFiles(self): # FIXME: ... pass def itemAction(self, mi,): # FIXME: use a MIME-Handler here i = self.model.itemFromIndex(mi) t, nc = i.ncItem QMessageBox.information(self, QCoreApplication.translate('NetCDF3', 'netCDF3: Item clicked'), QCoreApplication.translate('NetCDF3', 'You clicked an item in the netCDF3-browser')) def showItem(self, mi, pr): i = self.model.itemFromIndex(mi) t, nc = i.ncItem txt = "" name = str(i.data().toString()) if t == 'F': p, f = os.path.split(name) txt = "<i>File </i><b>%s</b><br> in %s" % (f, p) elif t == 'A': txt = "<i>Attribute </i><b>%s:</b><br>%s" % (name, escape(unicode(nc))) elif t == 'D': txt = "<i>Dimension </i><b>%s:</b><br>%s" % (name, str(nc)) elif t == 'V': txt = "<i>Variable </i><b>%s:</b><br>Typecode: %s<br>Dimensions: %s<br>Shape: %s" % \ (name, nc.typecode(), '*'.join(d for d in nc.dimensions), nc.shape) else: return self.textBrowser.setText(txt)
class MikiWindow(QMainWindow): def __init__(self, settings, parent=None): super(MikiWindow, self).__init__(parent) self.setObjectName("mikiWindow") self.settings = settings self.notePath = settings.notePath ################ Setup core components ################ self.notesTree = MikiTree(self) self.quickNoteNav = QLineEdit() self.notesTab = QWidget() self.completer = SlashPleter() self.completer.setModel(self.notesTree.model()) self.quickNoteNav.setCompleter(self.completer) self.notesTree.setObjectName("notesTree") self.initTree(self.notePath, self.notesTree) self.notesTree.sortItems(0, Qt.AscendingOrder) self.ix = None self.setupWhoosh() self.viewedList = QToolBar(self.tr('Recently Viewed'), self) self.viewedList.setIconSize(QSize(16, 16)) self.viewedList.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.viewedListActions = [] self.noteSplitter = QSplitter(Qt.Horizontal) self.dockIndex = QDockWidget("Index") self.dockSearch = QDockWidget("Search") self.searchEdit = QLineEdit() self.searchView = MikiSearch(self) self.searchTab = QWidget() self.dockToc = QDockWidget("TOC") self.tocTree = TocTree() self.dockAttachment = QDockWidget("Attachment") self.attachmentView = AttachmentView(self) self.notesEdit = MikiEdit(self) self.notesEdit.setObjectName("notesEdit") MikiHighlighter(self.notesEdit) self.notesView = MikiView(self) self.findBar = QToolBar(self.tr('Find'), self) self.findBar.setFixedHeight(30) self.findEdit = QLineEdit(self.findBar) self.checkBox = QCheckBox(self.tr('Match case'), self.findBar) self.statusBar = QStatusBar(self) self.statusLabel = QLabel(self) self.altPressed = False ################ Setup actions ################ self.actions = dict() self.setupActions() ################ Setup mainwindow ################ self.setupMainWindow() # show changelogs after upgrade mikidown if self.settings.version < __version__: self.changelogHelp() self.settings.qsettings.setValue("version", __version__) def setupActions(self): # Global Actions actTabIndex = self.act(self.tr('Switch to Index Tab'), lambda: self.raiseDock(self.dockIndex), 'Ctrl+Shift+I') actTabSearch = self.act(self.tr('Switch to Search Tab'), lambda: self.raiseDock(self.dockSearch), 'Ctrl+Shift+F') self.addAction(actTabIndex) self.addAction(actTabSearch) ################ Menu Actions ################ # actions in menuFile actionNewPage = self.act(self.tr('&New Page...'), self.notesTree.newPage, QKeySequence.New) self.actions.update(newPage=actionNewPage) actionNewSubpage = self.act(self.tr('New Sub&page...'), self.notesTree.newSubpage, 'Ctrl+Shift+N') self.actions.update(newSubpage=actionNewSubpage) actionImportPage = self.act(self.tr('&Import Page...'), self.importPage) self.actions.update(importPage=actionImportPage) actionNBSettings = self.act(self.tr('Notebook Set&tings...'), self.notebookSettings) self.actions.update(NBSettings=actionNBSettings) actionMDSettings = self.act(self.tr('&Mikidown Settings...'), self.mikidownSettings) self.actions.update(MDSettings=actionMDSettings) actionOpenNotebook = self.act(self.tr('&Open Notebook...'), self.openNotebook, QKeySequence.Open) self.actions.update(openNotebook=actionOpenNotebook) actionReIndex = self.act(self.tr('Re-index'), self.reIndex) self.actions.update(reIndex=actionReIndex) actionSave = self.act(self.tr('&Save'), self.saveCurrentNote, QKeySequence.Save) actionSave.setEnabled(False) self.actions.update(save=actionSave) actionSaveAs = self.act(self.tr('Save &As...'), self.saveNoteAs, QKeySequence.SaveAs) self.actions.update(saveAs=actionSaveAs) actionHtml = self.act(self.tr('to &HTML'), self.notesEdit.saveAsHtml) self.actions.update(html=actionHtml) actionPrint = self.act(self.tr('&Print'), self.printNote, QKeySequence.Print) self.actions.update(print_=actionPrint) actionRenamePage = self.act(self.tr('&Rename Page...'), self.notesTree.renamePage, 'F2') self.actions.update(renamePage=actionRenamePage) actionDelPage = self.act(self.tr('&Delete Page'), self.notesTree.delPageWrapper, QKeySequence.Delete) self.actions.update(delPage=actionDelPage) actionQuit = self.act(self.tr('&Quit'), self.close, QKeySequence.Quit) actionQuit.setMenuRole(QAction.QuitRole) self.actions.update(quit=actionQuit) # actions in menuEdit actionUndo = self.act(self.tr('&Undo'), lambda: self.notesEdit.undo(), QKeySequence.Undo) actionUndo.setEnabled(False) self.notesEdit.undoAvailable.connect(actionUndo.setEnabled) self.actions.update(undo=actionUndo) actionRedo = self.act(self.tr('&Redo'), lambda: self.notesEdit.redo(), QKeySequence.Redo) actionRedo.setEnabled(False) self.notesEdit.redoAvailable.connect(actionRedo.setEnabled) self.actions.update(redo=actionRedo) actionFindText = self.act(self.tr('&Find Text'), self.findBar.setVisible, QKeySequence.Find, True) self.actions.update(findText=actionFindText) actionFind = self.act(self.tr('Next'), self.findText, QKeySequence.FindNext) self.actions.update(find=actionFind) actionFindPrev = self.act(self.tr('Previous'), lambda: self.findText(back=True), QKeySequence.FindPrevious) self.actions.update(findPrev=actionFindPrev) actionSortLines = self.act(self.tr('&Sort Lines'), self.sortLines) self.actions.update(sortLines=actionSortLines) actionQuickNav = self.act(self.tr("&Quick Open Note"), self.quickNoteNav.setFocus, 'Ctrl+G') self.addAction(actionQuickNav) actionInsertImage = self.act(self.tr('&Insert Attachment'), self.notesEdit.insertAttachmentWrapper, 'Ctrl+I') actionInsertImage.setEnabled(False) self.actions.update(insertImage=actionInsertImage) # actions in menuView actionEdit = self.act(self.tr('Edit'), self.edit, 'Ctrl+E', True, QIcon(':/icons/edit.svg'), 'Edit mode (Ctrl+E)') self.actions.update(edit=actionEdit) actionSplit = self.act(self.tr('Split'), self.liveView, 'Ctrl+R', True, QIcon(':/icons/split.svg'), 'Split mode (Ctrl+R)') self.actions.update(split=actionSplit) actionFlipEditAndView = self.act(self.tr('Flip Edit and View'), self.flipEditAndView) actionFlipEditAndView.setEnabled(False) self.actions.update(flipEditAndView=actionFlipEditAndView) #actionLeftAndRight = self.act( # self.tr('Split into Left and Right'), trig=self.leftAndRight) #actionUpAndDown = self.act( # self.tr('Split into Up and Down'), trig=self.upAndDown) # self.actionLeftAndRight.setEnabled(False) # self.actionUpAndDown.setEnabled(False) # actions in menuHelp actionReadme = self.act(self.tr('README'), self.readmeHelp) self.actions.update(readme=actionReadme) actionChangelog = self.act(self.tr('Changelog'), self.changelogHelp) self.actions.update(changelog=actionChangelog) actionAboutQt = self.act(self.tr('About Qt'), qApp.aboutQt) self.actions.update(aboutQt=actionAboutQt) def setupMainWindow(self): self.resize(800, 600) screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move(( screen.width()-size.width())/2, (screen.height()-size.height())/2) self.setWindowTitle( '{} - {}'.format(self.settings.notebookName, __appname__)) self.viewedList.setFixedHeight(25) self.noteSplitter.addWidget(self.notesEdit) self.noteSplitter.addWidget(self.notesView) mainSplitter = QSplitter(Qt.Vertical) mainSplitter.setChildrenCollapsible(False) mainSplitter.addWidget(self.viewedList) mainSplitter.addWidget(self.noteSplitter) mainSplitter.addWidget(self.findBar) self.setCentralWidget(mainSplitter) self.searchEdit.returnPressed.connect(self.searchNote) self.quickNoteNav.returnPressed.connect(self.openFuncWrapper) searchLayout = QVBoxLayout() searchLayout.addWidget(self.searchEdit) searchLayout.addWidget(self.searchView) self.searchTab.setLayout(searchLayout) self.tocTree.header().close() indexLayout = QVBoxLayout(self.notesTab) indexLayout.addWidget(self.quickNoteNav) indexLayout.addWidget(self.notesTree) self.dockIndex.setObjectName("Index") self.dockIndex.setWidget(self.notesTab) self.dockSearch.setObjectName("Search") self.dockSearch.setWidget(self.searchTab) self.dockToc.setObjectName("TOC") self.dockToc.setWidget(self.tocTree) self.dockAttachment.setObjectName("Attachment") self.dockAttachment.setWidget(self.attachmentView) self.setDockOptions(QMainWindow.VerticalTabs) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockIndex) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockSearch) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockToc) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockAttachment) self.tabifyDockWidget(self.dockIndex, self.dockSearch) self.tabifyDockWidget(self.dockSearch, self.dockToc) self.tabifyDockWidget(self.dockToc, self.dockAttachment) self.setTabPosition(Qt.LeftDockWidgetArea, QTabWidget.North) self.dockIndex.raise_() # Put dockIndex on top of the tab stack menuBar = QMenuBar(self) self.setMenuBar(menuBar) menuFile = menuBar.addMenu(self.tr('&File')) menuEdit = menuBar.addMenu(self.tr('&Edit')) menuView = menuBar.addMenu(self.tr('&View')) menuHelp = menuBar.addMenu(self.tr('&Help')) # menuFile menuFile.addAction(self.actions['newPage']) menuFile.addAction(self.actions['newSubpage']) menuFile.addAction(self.actions['NBSettings']) menuFile.addAction(self.actions['MDSettings']) menuFile.addAction(self.actions['importPage']) menuFile.addAction(self.actions['openNotebook']) menuFile.addAction(self.actions['reIndex']) menuFile.addSeparator() menuFile.addAction(self.actions['save']) menuFile.addAction(self.actions['saveAs']) menuFile.addAction(self.actions['print_']) menuExport = menuFile.addMenu(self.tr('&Export')) menuExport.addAction(self.actions['html']) menuFile.addSeparator() menuFile.addAction(self.actions['renamePage']) menuFile.addAction(self.actions['delPage']) menuFile.addSeparator() menuFile.addAction(self.actions['quit']) # menuEdit menuEdit.addAction(self.actions['undo']) menuEdit.addAction(self.actions['redo']) menuEdit.addAction(self.actions['findText']) menuEdit.addSeparator() menuEdit.addAction(self.actions['sortLines']) menuEdit.addAction(self.actions['insertImage']) # menuView menuView.addAction(self.actions['edit']) menuView.addAction(self.actions['split']) menuView.addAction(self.actions['flipEditAndView']) menuShowHide = menuView.addMenu(self.tr('Show/Hide')) menuShowHide.addAction(self.dockIndex.toggleViewAction()) menuShowHide.addAction(self.dockSearch.toggleViewAction()) menuShowHide.addAction(self.dockToc.toggleViewAction()) menuShowHide.addAction(self.dockAttachment.toggleViewAction()) #menuMode = menuView.addMenu(self.tr('Mode')) #menuMode.addAction(self.actionLeftAndRight) #menuMode.addAction(self.actionUpAndDown) # menuHelp menuHelp.addAction(self.actions['readme']) menuHelp.addAction(self.actions['changelog']) menuHelp.addAction(self.actions['aboutQt']) toolBar = QToolBar(self.tr("toolbar"), self) toolBar.setObjectName("toolbar") # needed in saveState() toolBar.setIconSize(QSize(16, 16)) toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.addToolBar(Qt.TopToolBarArea, toolBar) toolBar.addAction(self.actions['edit']) toolBar.addAction(self.actions['split']) self.findEdit.returnPressed.connect(self.findText) self.findBar.addWidget(self.findEdit) self.findBar.addWidget(self.checkBox) self.findBar.addAction(self.actions['findPrev']) self.findBar.addAction(self.actions['find']) self.findBar.setVisible(False) self.findBar.visibilityChanged.connect(self.findBarVisibilityChanged) self.setStatusBar(self.statusBar) self.statusBar.addWidget(self.statusLabel, 1) self.notesTree.currentItemChanged.connect( self.currentItemChangedWrapper) self.tocTree.itemClicked.connect(self.tocNavigate) self.notesEdit.textChanged.connect(self.noteEditted) self.notesEdit.document( ).modificationChanged.connect(self.modificationChanged) self.updateRecentViewedNotes() notes = self.settings.recentViewedNotes() if len(notes) != 0: item = self.notesTree.pageToItem(notes[0]) self.notesTree.setCurrentItem(item) def openFuncWrapper(self): self.openFunction(self.quickNoteNav.text())() def setupWhoosh(self): # Initialize whoosh index, make sure notePath/.indexdir exists indexdir = self.settings.indexdir try: self.ix = open_dir(indexdir) except: QDir().mkpath(indexdir) self.ix = create_in(indexdir, self.settings.schema) # Fork a process to update index, which benefit responsiveness. p = Thread(target=self.whoosh_index, args=()) p.start() def restore(self): """ Restore saved geometry and state. Set the status of side panels in View Menu correspondently. """ if self.settings.geometry: self.restoreGeometry(self.settings.geometry) if self.settings.windowstate: self.restoreState(self.settings.windowstate) def initTree(self, notePath, parent): ''' When there exist foo.md, foo.mkd, foo.markdown, only one item will be shown in notesTree. ''' if not QDir(notePath).exists(): return notebookDir = QDir(notePath) notesList = notebookDir.entryInfoList(['*.md', '*.mkd', '*.markdown'], QDir.NoFilter, QDir.Name|QDir.IgnoreCase) nl = [note.completeBaseName() for note in notesList] noduplicate = list(set(nl)) for name in noduplicate: item = QTreeWidgetItem(parent, [name]) path = notePath + '/' + name self.initTree(path, item) def updateToc(self): ''' TOC is updated in `updateView` tocTree fields: [hdrText, hdrPosition, hdrAnchor] ''' root = self.notesTree.currentPage() self.tocTree.clear() item = QTreeWidgetItem(self.tocTree, [root, '0']) curLevel = 0 for (level, h, p, a) in parseHeaders(self.notesEdit.toPlainText()): val = [h, str(p), a] if level == curLevel: item = QTreeWidgetItem(item.parent(), val) elif level < curLevel: item = QTreeWidgetItem(item.parent().parent(), val) curLevel = level else: item = QTreeWidgetItem(item, val) curLevel = level self.tocTree.expandAll() def updateAttachmentView(self): # Update attachmentView to show corresponding attachments. item = self.notesTree.currentItem() index = self.attachmentView.model.index( self.notesTree.itemToAttachmentDir(item)) self.attachmentView.setRootIndex(index) def openFile(self, filename): fh = QFile(filename) try: if not fh.open(QIODevice.ReadOnly): raise IOError(fh.errorString()) except IOError as e: QMessageBox.warning(self, 'Read Error', 'Failed to open %s: %s' % (filename, e)) finally: if fh is not None: noteBody = QTextStream(fh).readAll() fh.close() self.notesEdit.setPlainText(noteBody) self.notesView.scrollPosition = QPoint(0, 0) # self.actionSave.setEnabled(False) self.notesEdit.document().setModified(False) self.notesView.updateView() self.setCurrentNote() self.updateRecentViewedNotes() #self.statusLabel.setText(noteFullName) def currentItemChangedWrapper(self, current, previous): if current is None: return #if previous != None and self.notesTree.pageExists(previous): prev = self.notesTree.itemToPage(previous) if self.notesTree.pageExists(prev): self.saveNote(previous) currentFile = self.notesTree.itemToFile(current) self.openFile(currentFile) # Update attachmentView to show corresponding attachments. index = self.attachmentView.model.index( self.notesTree.itemToAttachmentDir(current)) self.attachmentView.setRootIndex(index) def tocNavigate(self, current): ''' works for notesEdit now ''' if current is None: return pos = int(current.text(1)) link = "file://" + self.notePath + "/#" + current.text(2) # Move cursor to END first will ensure # header is positioned at the top of visual area. self.notesEdit.moveCursor(QTextCursor.End) cur = self.notesEdit.textCursor() cur.setPosition(pos, QTextCursor.MoveAnchor) self.notesEdit.setTextCursor(cur) self.notesView.load(QUrl(link)) def switchNote(self, num): if num < len(self.viewedListActions): self.viewedListActions[num].trigger() def saveCurrentNote(self): item = self.notesTree.currentItem() self.saveNote(item) def saveNote(self, item): if self.notesEdit.document().isModified(): self.notesEdit.document().setModified(False) else: return self.notesEdit.save(item) def saveNoteAs(self): self.saveCurrentNote() fileName = QFileDialog.getSaveFileName(self, self.tr('Save as'), '', '(*.md *.mkd *.markdown);;'+self.tr('All files(*)')) if fileName == '': return if not QFileInfo(fileName).suffix(): fileName += '.md' fh = QFile(fileName) fh.open(QIODevice.WriteOnly) savestream = QTextStream(fh) savestream << self.notesEdit.toPlainText() fh.close() def printNote(self): printer = QPrinter(QPrinter.HighResolution) printer.setCreator(__appname__ + ' ' + __version__) printer.setDocName(self.notesTree.currentItem().text(0)) printdialog = QPrintDialog(printer, self) if printdialog.exec() == QDialog.Accepted: self.notesView.print_(printer) def noteEditted(self): """ Continuously get fired while editing""" self.updateToc() self.notesView.updateLiveView() def modificationChanged(self, changed): """ Fired one time: modified or not """ self.actions['save'].setEnabled(changed) name = self.notesTree.currentPage() self.statusBar.clearMessage() if changed: self.statusLabel.setText(name + '*') else: self.statusLabel.setText(name) def importPage(self): filename = QFileDialog.getOpenFileName( self, self.tr('Import file'), '', '(*.md *.mkd *.markdown *.txt);;'+self.tr('All files(*)')) if filename == '': return self.importPageCore(filename) def importPageCore(self, filename): fh = QFile(filename) fh.open(QIODevice.ReadOnly) fileBody = QTextStream(fh).readAll() fh.close() page = QFileInfo(filename).completeBaseName() fh = QFile(self.notesTree.pageToFile(page)) if fh.exists(): QMessageBox.warning(self, 'Import Error', 'Page already exists: %s' % page) dialog = LineEditDialog(self.notePath, self) if dialog.exec_(): page = dialog.editor.text() fh.close() fh = QFile(self.notesTree.pageToFile(page)) else: return fh.open(QIODevice.WriteOnly) savestream = QTextStream(fh) savestream << fileBody fh.close() item = QTreeWidgetItem(self.notesTree, [page]) self.notesTree.sortItems(0, Qt.AscendingOrder) self.notesTree.setCurrentItem(item) def openNotebook(self): dialog = NotebookListDialog(self) if dialog.exec_(): pass def notebookSettings(self): dialog = NotebookSettingsDialog(self) if dialog.exec_(): pass def mikidownSettings(self): dialog = MikidownCfgDialog(self) if dialog.exec_(): pass def reIndex(self): """ Whoosh index breaks for unknown reasons (sometimes) """ shutil.rmtree(self.settings.indexdir) self.setupWhoosh() def act(self, name, trig, shortcut=None, checkable=False, icon=None, tooltip=None): """ A wrapper to several QAction methods """ if icon: action = QAction(icon, name, self) else: action = QAction(name, self) if shortcut: action.setShortcut(QKeySequence(shortcut)) action.setCheckable(checkable) if tooltip: action.setToolTip(tooltip) action.triggered.connect(trig) return action def edit(self, viewmode): """ Switch between EDIT and VIEW mode. """ if self.actions['split'].isChecked(): self.actions['split'].setChecked(False) self.notesView.setVisible(not viewmode) self.notesEdit.setVisible(viewmode) # Gives the keyboard input focus to notesEdit/notesView. # Without this, keyboard input may change note text even when # notesEdit is invisible. if viewmode: self.notesEdit.setFocus() else: self.notesView.setFocus() self.saveCurrentNote() self.actions['insertImage'].setEnabled(viewmode) #self.actionLeftAndRight.setEnabled(True) #self.actionUpAndDown.setEnabled(True) # Render the note text as it is. self.notesView.updateView() def liveView(self, viewmode): """ Switch between VIEW and LIVE VIEW mode. """ self.actions['split'].setChecked(viewmode) sizes = self.noteSplitter.sizes() if self.actions['edit'].isChecked(): self.actions['edit'].setChecked(False) self.notesView.setVisible(viewmode) splitSize = [sizes[0]*0.45, sizes[0]*0.55] else: self.notesEdit.setVisible(viewmode) splitSize = [sizes[1]*0.45, sizes[1]*0.55] # setFocus for the same reason as in edit(self, viewmode) if viewmode: self.notesEdit.setFocus() else: self.notesView.setFocus() self.actions['flipEditAndView'].setEnabled(viewmode) #self.actionUpAndDown.setEnabled(viewmode) self.actions['insertImage'].setEnabled(viewmode) self.noteSplitter.setSizes(splitSize) self.saveCurrentNote() # Render the note text as it is. self.notesView.updateView() def findBarVisibilityChanged(self, visible): self.actions['findText'].setChecked(visible) if visible: self.findEdit.setFocus(Qt.ShortcutFocusReason) def findText(self, back=False): flags = 0 if back: flags = QTextDocument.FindBackward if self.checkBox.isChecked(): flags = flags | QTextDocument.FindCaseSensitively text = self.findEdit.text() if not self.findMain(text, flags): if text in self.notesEdit.toPlainText(): cursor = self.notesEdit.textCursor() if back: cursor.movePosition(QTextCursor.End) else: cursor.movePosition(QTextCursor.Start) self.notesEdit.setTextCursor(cursor) self.findMain(text, flags) # self.notesView.findText(text, flags) def findMain(self, text, flags): viewFlags = QWebPage.FindFlags( flags) | QWebPage.FindWrapsAroundDocument if flags: self.notesView.findText(text, viewFlags) return self.notesEdit.find(text, flags) else: self.notesView.findText(text) return self.notesEdit.find(text) def sortLines(self): ''' sort selected lines TODO: second sort reverse the order ''' cursor = self.notesEdit.textCursor() start = cursor.selectionStart() end = cursor.selectionEnd() cursor.setPosition(start) cursor.movePosition(QTextCursor.StartOfLine) cursor.setPosition(end, mode=QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, mode=QTextCursor.KeepAnchor) text = cursor.selectedText() lines = text.split('\u2029') # '\u2029' is the line break sortedLines = sorted(lines) cursor.insertText('\n'.join(sortedLines)) def notesEditInFocus(self, e): if e.gotFocus: self.actions['insertImage'].setEnabled(True) # if e.lostFocus: # self.actionInsertImage.setEnabled(False) # QWidget.focusInEvent(self,f) def searchNote(self): """ Sorting criteria: "title > path > content" Search matches are organized into html source. """ pattern = self.searchEdit.text() if not pattern: return results = [] print("Searching using", pattern) with self.ix.searcher() as searcher: matches = [] for f in ["title", "path", "content"]: queryp = QueryParser(f, self.ix.schema) queryp.add_plugin(RegexPlugin()) # r"pattern" is the desired regex term format query = queryp.parse('r"' + pattern + '"') ms = searcher.search(query, limit=None) # default limit is 10! for m in ms: if not m in matches: matches.append(m) for r in matches: title = r['title'] path = r['path'] term = r.highlights("content") results.append([title, path, term]) html = "" for title, path, hi in results: html += ("<p><a href='" + path + "'>" + title + "</a><br/><span class='path'>" + path + "</span><br/>" + hi + "</p>") self.searchView.setHtml(html) print("Finished searching", pattern) def whoosh_index(self): it = QTreeWidgetItemIterator( self.notesTree, QTreeWidgetItemIterator.All) print("Starting complete indexing.") writer = self.ix.writer() while it.value(): treeItem = it.value() name = self.notesTree.itemToPage(treeItem) path = os.path.join(self.notesTree.pageToFile(name)).replace(os.sep, '/') print(path) fileobj = open(path, 'r') content = fileobj.read() fileobj.close() writer.add_document( path=name, title=parseTitle(content, name), content=content) it += 1 writer.commit() print("Finished completely reindexing.") def listItemChanged(self, row): if row != -1: item = self.searchList.currentItem().data(Qt.UserRole) self.notesTree.setCurrentItem(item) flags = QWebPage.HighlightAllOccurrences self.notesView.findText(self.searchEdit.text(), flags) def setCurrentNote(self): item = self.notesTree.currentItem() name = self.notesTree.itemToPage(item) # Current note is inserted to head of list. notes = self.settings.recentViewedNotes() for f in notes: if f == name: notes.remove(f) notes.insert(0, name) recent_notes_n = Mikibook.settings.value('recentNotesNumber',type=int, defaultValue=20) if len(notes) > recent_notes_n: del notes[recent_notes_n:] self.settings.updateRecentViewedNotes(notes) def updateRecentViewedNotes(self): """ Switching notes will trigger this. When Alt pressed, show note number. """ self.viewedList.clear() self.viewedListActions = [] # Check notes exists. viewedNotes = self.settings.recentViewedNotes() existedNotes = [] i = 0 for f in viewedNotes: if self.notesTree.pageExists(f): existedNotes.append(f) names = f.split('/') if self.altPressed and i in range(1, 10): action = self.act(names[-1], self.openFunction(f), 'Alt+'+str(i), True, ViewedNoteIcon(i), 'Alt+'+str(i)) else: action = self.act(names[-1], self.openFunction(f), None, True) self.viewedListActions.append(action) i += 1 if not self.altPressed: self.settings.updateRecentViewedNotes(existedNotes) for action in self.viewedListActions: self.viewedList.addAction(action) if len(self.viewedListActions): self.viewedListActions[0].setChecked(True) def openFunction(self, name): item = self.notesTree.pageToItem(name) return lambda: self.notesTree.setCurrentItem(item) def raiseDock(self, widget): if not widget.isVisible(): widget.show() if widget == self.dockSearch: self.searchEdit.setFocus() widget.raise_() def flipEditAndView(self): index = self.noteSplitter.indexOf(self.notesEdit) if index == 0: self.noteSplitter.insertWidget(1, self.notesEdit) else: self.noteSplitter.insertWidget(0, self.notesEdit) def leftAndRight(self): self.liveView(True) self.noteSplitter.setOrientation(Qt.Horizontal) #self.actionLeftAndRight.setEnabled(False) #self.actionUpAndDown.setEnabled(True) def upAndDown(self): self.liveView(True) self.noteSplitter.setOrientation(Qt.Vertical) #self.actionUpAndDown.setEnabled(False) #self.actionLeftAndRight.setEnabled(True) def readmeHelp(self): readmeFile = '/usr/share/mikidown/README.mkd' if not os.path.exists(readmeFile): readmeFile = os.path.join( os.path.dirname(os.path.dirname(__file__)), 'README.mkd').replace(os.sep, '/') self.importPageCore(readmeFile) def changelogHelp(self): changeLog = "/usr/share/mikidown/Changelog.md" if not os.path.exists(changeLog): changeLog = os.path.join( os.path.dirname(os.path.dirname(__file__)), 'Changelog.md').replace(os.sep, '/') self.importPageCore(changeLog) def keyPressEvent(self, event): """ When Alt pressed, note number will be shown in viewedList. """ if event.key() == Qt.Key_Alt: self.altPressed = True self.updateRecentViewedNotes() else: QMainWindow.keyPressEvent(self, event) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Alt: self.altPressed = False self.updateRecentViewedNotes() else: QMainWindow.keyPressEvent(self, event) def closeEvent(self, event): """ saveGeometry: Saves the current geometry and state for top-level widgets saveState: Restores the state of this mainwindow's toolbars and dockwidgets """ self.saveCurrentNote() self.settings.saveGeometry(self.saveGeometry()) self.settings.saveWindowState(self.saveState()) event.accept()
class MikiWindow(QMainWindow): def __init__(self, settings, parent=None): super(MikiWindow, self).__init__(parent) self.setObjectName("mikiWindow") self.settings = settings self.notePath = settings.notePath lockPath = os.path.join(settings.notebookPath, '.mikidown_lock') if not os.path.exists(lockPath): self.lockPathFH = os.open(lockPath, os.O_CREAT | os.O_EXCL | os.O_RDWR) ################ Setup core components ################ self.notesTree = MikiTree(self) self.quickNoteNav = QLineEdit() self.notesTab = QWidget() self.completer = SlashPleter() self.completer.setModel(self.notesTree.model()) self.quickNoteNav.setCompleter(self.completer) self.notesTree.setObjectName("notesTree") self.initTree(self.notePath, self.notesTree) self.notesTree.sortItems(0, Qt.AscendingOrder) self.ix = None self.setupWhoosh() self.viewedList = QToolBar(self.tr('Recently Viewed'), self) self.viewedList.setIconSize(QSize(16, 16)) self.viewedList.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.viewedListActions = [] self.noteSplitter = QSplitter(Qt.Horizontal) self.dockIndex = QDockWidget(self.tr("Index")) self.dockSearch = QDockWidget(self.tr("Search")) self.searchEdit = QLineEdit() self.searchView = MikiSearch(self) self.searchTab = QWidget() self.dockToc = QDockWidget(self.tr("TOC")) self.tocTree = TocTree() self.dockAttachment = QDockWidget(self.tr("Attachment")) self.attachmentView = AttachmentView(self) self.notesEdit = MikiEdit(self) self.notesEdit.setObjectName(self.tr("notesEdit")) self.loadHighlighter() self.notesView = MikiView(self) self.findBar = QToolBar(self.tr('Find'), self) self.findBar.setFixedHeight(30) self.findEdit = QLineEdit(self.findBar) self.checkBox = QCheckBox(self.tr('Match case'), self.findBar) self.statusBar = QStatusBar(self) self.statusLabel = QLabel(self) self.altPressed = False ################ Setup actions ################ self.actions = dict() self.setupActions() ################ Setup mainwindow ################ self.setupMainWindow() # show changelogs after upgrade mikidown if self.settings.version < __version__ or Mikibook.settings.value( "version", defaultValue="0") < __version__: self.changelogHelp() self.settings.qsettings.setValue("version", __version__) Mikibook.settings.setValue("version", __version__) def loadHighlighter(self): fnt = Mikibook.settings.value('editorFont', defaultValue=None) fntsize = Mikibook.settings.value('editorFontSize', type=int, defaultValue=12) header_scales_font = Mikibook.settings.value('headerScaleFont', type=bool, defaultValue=True) if fnt is not None: self.notesEdit.setFontFamily(fnt) self.notesEdit.setFontPointSize(fntsize) h = MikiHighlighter(parent=self.notesEdit, scale_font_sizes=header_scales_font) tw = Mikibook.settings.value('tabWidth', type=int, defaultValue=4) qfm = QFontMetrics(h.patterns[0][1].font()) self.notesEdit.setTabStopWidth(tw * qfm.width(' ')) def setupActions(self): # Global Actions actTabIndex = self.act(self.tr('Switch to Index Tab'), lambda: self.raiseDock(self.dockIndex), self.tr('Ctrl+Shift+I')) actTabSearch = self.act(self.tr('Switch to Search Tab'), lambda: self.raiseDock(self.dockSearch), self.tr('Ctrl+Shift+F')) self.addAction(actTabIndex) self.addAction(actTabSearch) ################ Menu Actions ################ # actions in menuFile actionNewPage = self.act(self.tr('&New Page...'), self.notesTree.newPage, QKeySequence.New) self.actions.update(newPage=actionNewPage) actionNewSubpage = self.act(self.tr('New Sub&page...'), self.notesTree.newSubpage, self.tr('Ctrl+Shift+N')) self.actions.update(newSubpage=actionNewSubpage) actionImportPage = self.act(self.tr('&Import Page...'), self.importPage) self.actions.update(importPage=actionImportPage) actionNBSettings = self.act(self.tr('Notebook Set&tings...'), self.notebookSettings) self.actions.update(NBSettings=actionNBSettings) actionMDSettings = self.act(self.tr('&Mikidown Settings...'), self.mikidownSettings) self.actions.update(MDSettings=actionMDSettings) actionOpenNotebook = self.act(self.tr('&Open Notebook...'), self.openNotebook, QKeySequence.Open) self.actions.update(openNotebook=actionOpenNotebook) actionReIndex = self.act(self.tr('Re-index'), self.reIndex) self.actions.update(reIndex=actionReIndex) actionSave = self.act(self.tr('&Save'), self.saveCurrentNote, QKeySequence.Save) actionSave.setEnabled(False) self.actions.update(save=actionSave) actionSaveAs = self.act(self.tr('Save &As...'), self.saveNoteAs, QKeySequence.SaveAs) self.actions.update(saveAs=actionSaveAs) actionHtml = self.act(self.tr('to &HTML'), self.notesEdit.saveAsHtml) self.actions.update(html=actionHtml) actionPrint = self.act(self.tr('&Print'), self.printNote, QKeySequence.Print) self.actions.update(print_=actionPrint) actionRenamePage = self.act(self.tr('&Rename Page...'), self.notesTree.renamePage, 'F2') self.actions.update(renamePage=actionRenamePage) actionDelPage = self.act(self.tr('&Delete Page'), self.notesTree.delPageWrapper, QKeySequence.Delete) self.actions.update(delPage=actionDelPage) actionQuit = self.act(self.tr('&Quit'), self.close, QKeySequence.Quit) actionQuit.setMenuRole(QAction.QuitRole) self.actions.update(quit=actionQuit) # actions in menuEdit actionUndo = self.act(self.tr('&Undo'), lambda: self.notesEdit.undo(), QKeySequence.Undo) actionUndo.setEnabled(False) self.notesEdit.undoAvailable.connect(actionUndo.setEnabled) self.actions.update(undo=actionUndo) actionRedo = self.act(self.tr('&Redo'), lambda: self.notesEdit.redo(), QKeySequence.Redo) actionRedo.setEnabled(False) self.notesEdit.redoAvailable.connect(actionRedo.setEnabled) self.actions.update(redo=actionRedo) actionFindText = self.act(self.tr('&Find Text'), self.findBar.setVisible, QKeySequence.Find, True) self.actions.update(findText=actionFindText) actionFindRepl = self.act(self.tr('Find and Replace'), FindReplaceDialog(self.notesEdit).open, QKeySequence.Replace) self.actions.update(findRepl=actionFindRepl) actionFind = self.act(self.tr('Next'), self.findText, QKeySequence.FindNext) self.actions.update(find=actionFind) actionFindPrev = self.act(self.tr('Previous'), lambda: self.findText(back=True), QKeySequence.FindPrevious) self.actions.update(findPrev=actionFindPrev) actionSortLines = self.act(self.tr('&Sort Lines'), self.sortLines) self.actions.update(sortLines=actionSortLines) actionQuickNav = self.act(self.tr("&Quick Open Note"), self.quickNoteNav.setFocus, self.tr('Ctrl+G')) self.addAction(actionQuickNav) actionInsertImage = self.act(self.tr('&Insert Attachment'), self.notesEdit.insertAttachmentWrapper, self.tr('Ctrl+I')) actionInsertImage.setEnabled(False) self.actions.update(insertImage=actionInsertImage) # actions in menuView QIcon.setThemeName( Mikibook.settings.value('iconTheme', QIcon.themeName())) #print(QIcon.themeName()) actionEdit = self.act(self.tr('Edit'), self.edit, self.tr('Ctrl+E'), True, QIcon.fromTheme('document-edit'), self.tr('Edit mode (Ctrl+E)')) self.actions.update(edit=actionEdit) actionSplit = self.act(self.tr('Split'), self.liveView, self.tr('Ctrl+R'), True, QIcon.fromTheme('view-split-left-right'), self.tr('Split mode (Ctrl+R)')) self.actions.update(split=actionSplit) actionFlipEditAndView = self.act(self.tr('Flip Edit and View'), self.flipEditAndView) actionFlipEditAndView.setEnabled(False) self.actions.update(flipEditAndView=actionFlipEditAndView) #actionLeftAndRight = self.act( # self.tr('Split into Left and Right'), trig=self.leftAndRight) #actionUpAndDown = self.act( # self.tr('Split into Up and Down'), trig=self.upAndDown) # self.actionLeftAndRight.setEnabled(False) # self.actionUpAndDown.setEnabled(False) # actions in menuHelp actionReadme = self.act(self.tr('README'), self.readmeHelp) self.actions.update(readme=actionReadme) actionChangelog = self.act(self.tr('Changelog'), self.changelogHelp) self.actions.update(changelog=actionChangelog) actionAboutQt = self.act(self.tr('About Qt'), qApp.aboutQt) self.actions.update(aboutQt=actionAboutQt) def setupMainWindow(self): self.resize(800, 600) screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) self.setWindowTitle('{} - {}'.format(self.settings.notebookName, __appname__)) self.viewedList.setFixedHeight(25) self.noteSplitter.addWidget(self.notesEdit) self.noteSplitter.addWidget(self.notesView) mainSplitter = QSplitter(Qt.Vertical) mainSplitter.setChildrenCollapsible(False) mainSplitter.addWidget(self.viewedList) mainSplitter.addWidget(self.noteSplitter) mainSplitter.addWidget(self.findBar) self.setCentralWidget(mainSplitter) self.searchEdit.returnPressed.connect(self.searchNote) self.quickNoteNav.returnPressed.connect(self.openFuncWrapper) searchLayout = QVBoxLayout() searchLayout.addWidget(self.searchEdit) searchLayout.addWidget(self.searchView) self.searchTab.setLayout(searchLayout) indexLayout = QVBoxLayout(self.notesTab) indexLayout.addWidget(self.quickNoteNav) indexLayout.addWidget(self.notesTree) self.dockIndex.setObjectName("Index") self.dockIndex.setWidget(self.notesTab) self.dockSearch.setObjectName("Search") self.dockSearch.setWidget(self.searchTab) self.dockToc.setObjectName("TOC") self.dockToc.setWidget(self.tocTree) self.dockAttachment.setObjectName("Attachment") self.dockAttachment.setWidget(self.attachmentView) self.setDockOptions(QMainWindow.VerticalTabs) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockIndex) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockSearch) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockToc) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockAttachment) self.tabifyDockWidget(self.dockIndex, self.dockSearch) self.tabifyDockWidget(self.dockSearch, self.dockToc) self.tabifyDockWidget(self.dockToc, self.dockAttachment) self.setTabPosition(Qt.LeftDockWidgetArea, QTabWidget.North) self.dockIndex.raise_() # Put dockIndex on top of the tab stack menuBar = QMenuBar(self) self.setMenuBar(menuBar) menuFile = menuBar.addMenu(self.tr('&File')) menuEdit = menuBar.addMenu(self.tr('&Edit')) menuView = menuBar.addMenu(self.tr('&View')) menuHelp = menuBar.addMenu(self.tr('&Help')) # menuFile menuFile.addAction(self.actions['newPage']) menuFile.addAction(self.actions['newSubpage']) menuFile.addAction(self.actions['NBSettings']) menuFile.addAction(self.actions['MDSettings']) menuFile.addAction(self.actions['importPage']) menuFile.addAction(self.actions['openNotebook']) menuFile.addAction(self.actions['reIndex']) menuFile.addSeparator() menuFile.addAction(self.actions['save']) menuFile.addAction(self.actions['saveAs']) menuFile.addAction(self.actions['print_']) menuExport = menuFile.addMenu(self.tr('&Export')) menuExport.addAction(self.actions['html']) menuFile.addSeparator() menuFile.addAction(self.actions['renamePage']) menuFile.addAction(self.actions['delPage']) menuFile.addSeparator() menuFile.addAction(self.actions['quit']) # menuEdit menuEdit.addAction(self.actions['undo']) menuEdit.addAction(self.actions['redo']) menuEdit.addAction(self.actions['findText']) menuEdit.addAction(self.actions['findRepl']) menuEdit.addSeparator() menuEdit.addAction(self.actions['sortLines']) menuEdit.addAction(self.actions['insertImage']) # menuView menuView.addAction(self.actions['edit']) menuView.addAction(self.actions['split']) menuView.addAction(self.actions['flipEditAndView']) menuShowHide = menuView.addMenu(self.tr('Show/Hide')) menuShowHide.addAction(self.dockIndex.toggleViewAction()) menuShowHide.addAction(self.dockSearch.toggleViewAction()) menuShowHide.addAction(self.dockToc.toggleViewAction()) menuShowHide.addAction(self.dockAttachment.toggleViewAction()) #menuMode = menuView.addMenu(self.tr('Mode')) #menuMode.addAction(self.actionLeftAndRight) #menuMode.addAction(self.actionUpAndDown) # menuHelp menuHelp.addAction(self.actions['readme']) menuHelp.addAction(self.actions['changelog']) menuHelp.addAction(self.actions['aboutQt']) toolBar = QToolBar(self.tr("toolbar"), self) toolBar.setObjectName("toolbar") # needed in saveState() #toolBar.setIconSize(QSize(16, 16)) toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.addToolBar(Qt.TopToolBarArea, toolBar) toolBar.addAction(self.actions['edit']) toolBar.addAction(self.actions['split']) self.findEdit.returnPressed.connect(self.findText) self.findBar.addWidget(self.findEdit) self.findBar.addWidget(self.checkBox) self.findBar.addAction(self.actions['findPrev']) self.findBar.addAction(self.actions['find']) self.findBar.setVisible(False) self.findBar.visibilityChanged.connect(self.findBarVisibilityChanged) self.setStatusBar(self.statusBar) self.statusBar.addWidget(self.statusLabel, 1) self.notesTree.currentItemChanged.connect( self.currentItemChangedWrapper) self.notesTree.nvwCallback = self.newNoteDisplay self.notesTree.nvwtCallback = self.newPlainTextNoteDisplay self.tocTree.itemClicked.connect(self.tocNavigate) self.notesEdit.textChanged.connect(self.noteEditted) self.notesEdit.document().modificationChanged.connect( self.modificationChanged) self.updateRecentViewedNotes() notes = self.settings.recentViewedNotes() if len(notes) != 0: item = self.notesTree.pageToItem(notes[0]) self.notesTree.setCurrentItem(item) def newNoteDisplay(self, item, anchor=None): msn = MikiSepNote(self.settings, item.text(0), self.notesTree.itemToFile(item), plain_text=False, parent=self) if anchor: msn.note_view.page().mainFrame().scrollToAnchor(anchor) msn.show() def newPlainTextNoteDisplay(self, item, anchor=None): msn = MikiSepNote(self.settings, item.text(0), self.notesTree.itemToFile(item), plain_text=True, parent=self) if anchor: item = msn.findItemByAnchor(anchor)[0] msn.tocNavigate(item) msn.show() def openFuncWrapper(self): self.openFunction(self.quickNoteNav.text())() def setupWhoosh(self): # Initialize whoosh index, make sure notePath/.indexdir exists indexdir = self.settings.indexdir try: self.ix = open_dir(indexdir) except: QDir().mkpath(indexdir) self.ix = create_in(indexdir, self.settings.schema) # Fork a process to update index, which benefit responsiveness. p = Thread(target=self.whoosh_index, args=()) p.start() def restore(self): """ Restore saved geometry and state. Set the status of side panels in View Menu correspondently. """ if self.settings.geometry: self.restoreGeometry(self.settings.geometry) if self.settings.windowstate: self.restoreState(self.settings.windowstate) def initTree(self, notePath, parent): ''' When there exist foo.md, foo.mkd, foo.markdown, only one item will be shown in notesTree. ''' if not QDir(notePath).exists(): return notebookDir = QDir(notePath) notesList = notebookDir.entryInfoList(['*.md', '*.mkd', '*.markdown'], QDir.NoFilter, QDir.Name | QDir.IgnoreCase) nl = [note.completeBaseName() for note in notesList] noduplicate = list(set(nl)) for name in noduplicate: item = QTreeWidgetItem(parent, [name]) path = notePath + '/' + name self.initTree(path, item) def updateToc(self): ''' TOC is updated in `updateView` tocTree fields: [hdrText, hdrPosition, hdrAnchor] ''' root = self.notesTree.currentPage() strip_math_for_header_parsing = False strip_fence_for_header_parsing = False if 'asciimathml' in self.settings.extensions: strip_math_for_header_parsing = True if 'fenced_code' in self.settings.extensions or 'extra' in self.settings.extensions: strip_fence_for_header_parsing = True self.tocTree.updateToc( root, parseHeaders(self.notesEdit.toPlainText(), strip_fenced_block=strip_fence_for_header_parsing, strip_ascii_math=strip_math_for_header_parsing)) def updateAttachmentView(self): # Update attachmentView to show corresponding attachments. item = self.notesTree.currentItem() index = self.attachmentView.model.index( self.notesTree.itemToAttachmentDir(item)) self.attachmentView.setRootIndex(index) def openFile(self, filename): fh = QFile(filename) try: if not fh.open(QIODevice.ReadOnly): raise IOError(fh.errorString()) except IOError as e: QMessageBox.warning( self, self.tr('Read Error'), self.tr('Failed to open %s: %s') % (filename, e)) finally: if fh is not None: noteBody = QTextStream(fh).readAll() fh.close() self.notesEdit.setPlainText(noteBody) self.notesView.scrollPosition = QPoint(0, 0) # self.actionSave.setEnabled(False) self.notesEdit.document().setModified(False) self.notesView.updateView() self.setCurrentNote() self.updateRecentViewedNotes() #self.statusLabel.setText(noteFullName) def currentItemChangedWrapper(self, current, previous): if current is None: return #if previous != None and self.notesTree.pageExists(previous): prev = self.notesTree.itemToPage(previous) if self.notesTree.pageExists(prev): self.saveNote(previous) currentFile = self.notesTree.itemToFile(current) self.openFile(currentFile) # Update attachmentView to show corresponding attachments. index = self.attachmentView.model.index( self.notesTree.itemToAttachmentDir(current)) self.attachmentView.setRootIndex(index) def tocNavigate(self, current): ''' works for notesEdit now ''' if current is None: return pos = int(current.text(1)) link = "file://" + self.notePath + "/#" + current.text(2) # Move cursor to END first will ensure # header is positioned at the top of visual area. self.notesEdit.moveCursor(QTextCursor.End) cur = self.notesEdit.textCursor() cur.setPosition(pos, QTextCursor.MoveAnchor) self.notesEdit.setTextCursor(cur) self.notesView.load(QUrl(link)) def switchNote(self, num): if num < len(self.viewedListActions): self.viewedListActions[num].trigger() def saveCurrentNote(self): item = self.notesTree.currentItem() self.saveNote(item) def saveNote(self, item): if self.notesEdit.document().isModified(): self.notesEdit.document().setModified(False) else: return self.notesEdit.save(item) def saveNoteAs(self): self.saveCurrentNote() fileName = QFileDialog.getSaveFileName( self, self.tr('Save as'), '', '(*.md *.mkd *.markdown);;' + self.tr('All files(*)')) if fileName == '': return if not QFileInfo(fileName).suffix(): fileName += '.md' fh = QFile(fileName) fh.open(QIODevice.WriteOnly) savestream = QTextStream(fh) savestream << self.notesEdit.toPlainText() fh.close() def printNote(self): printer = QPrinter(QPrinter.HighResolution) printer.setCreator(__appname__ + ' ' + __version__) printer.setDocName(self.notesTree.currentItem().text(0)) printdialog = QPrintDialog(printer, self) if printdialog.exec() == QDialog.Accepted: self.notesView.print_(printer) def noteEditted(self): """ Continuously get fired while editing""" self.updateToc() self.notesView.updateLiveView() def modificationChanged(self, changed): """ Fired one time: modified or not """ self.actions['save'].setEnabled(changed) name = self.notesTree.currentPage() self.statusBar.clearMessage() if changed: self.statusLabel.setText(name + '*') else: self.statusLabel.setText(name) def importPage(self): filename = QFileDialog.getOpenFileName( self, self.tr('Import file'), '', '(*.md *.mkd *.markdown *.txt);;' + self.tr('All files(*)')) if filename == '': return self.importPageCore(filename) def importPageCore(self, filename): fh = QFile(filename) fh.open(QIODevice.ReadOnly) fileBody = QTextStream(fh).readAll() fh.close() page = QFileInfo(filename).completeBaseName() fh = QFile(self.notesTree.pageToFile(page)) if fh.exists(): QMessageBox.warning(self, self.tr("Import Error"), self.tr("Page already exists: %s") % page) dialog = LineEditDialog(self.notePath, self) if dialog.exec_(): page = dialog.editor.text() fh.close() fh = QFile(self.notesTree.pageToFile(page)) else: return fh.open(QIODevice.WriteOnly) savestream = QTextStream(fh) savestream << fileBody fh.close() item = QTreeWidgetItem(self.notesTree, [page]) self.notesTree.sortItems(0, Qt.AscendingOrder) self.notesTree.setCurrentItem(item) def openNotebook(self): dialog = NotebookListDialog(self) if dialog.exec_(): pass def notebookSettings(self): dialog = NotebookSettingsDialog(self) if dialog.exec_(): pass def mikidownSettings(self): dialog = MikidownCfgDialog(self) if dialog.exec_(): pass def reIndex(self): """ Whoosh index breaks for unknown reasons (sometimes) """ shutil.rmtree(self.settings.indexdir) self.setupWhoosh() def act(self, name, trig, shortcut=None, checkable=False, icon=None, tooltip=None): """ A wrapper to several QAction methods """ if icon: action = QAction(icon, name, self) else: action = QAction(name, self) if shortcut: action.setShortcut(QKeySequence(shortcut)) action.setCheckable(checkable) if tooltip: action.setToolTip(tooltip) action.triggered.connect(trig) return action def edit(self, viewmode): """ Switch between EDIT and VIEW mode. """ if self.actions['split'].isChecked(): self.actions['split'].setChecked(False) self.notesView.setVisible(not viewmode) self.notesEdit.setVisible(viewmode) # Gives the keyboard input focus to notesEdit/notesView. # Without this, keyboard input may change note text even when # notesEdit is invisible. if viewmode: self.notesEdit.setFocus() else: self.notesView.setFocus() self.saveCurrentNote() self.actions['insertImage'].setEnabled(viewmode) #self.actionLeftAndRight.setEnabled(True) #self.actionUpAndDown.setEnabled(True) # Render the note text as it is. self.notesView.updateView() def liveView(self, viewmode): """ Switch between VIEW and LIVE VIEW mode. """ self.actions['split'].setChecked(viewmode) sizes = self.noteSplitter.sizes() if self.actions['edit'].isChecked(): self.actions['edit'].setChecked(False) self.notesView.setVisible(viewmode) splitSize = [sizes[0] * 0.45, sizes[0] * 0.55] else: self.notesEdit.setVisible(viewmode) splitSize = [sizes[1] * 0.45, sizes[1] * 0.55] # setFocus for the same reason as in edit(self, viewmode) if viewmode: self.notesEdit.setFocus() else: self.notesView.setFocus() self.actions['flipEditAndView'].setEnabled(viewmode) #self.actionUpAndDown.setEnabled(viewmode) self.actions['insertImage'].setEnabled(viewmode) self.noteSplitter.setSizes(splitSize) self.saveCurrentNote() # Render the note text as it is. self.notesView.updateView() def findBarVisibilityChanged(self, visible): self.actions['findText'].setChecked(visible) if visible: self.findEdit.setFocus(Qt.ShortcutFocusReason) def findText(self, back=False): flags = 0 if back: flags = QTextDocument.FindBackward if self.checkBox.isChecked(): flags = flags | QTextDocument.FindCaseSensitively text = self.findEdit.text() if not self.findMain(text, flags): if text in self.notesEdit.toPlainText(): cursor = self.notesEdit.textCursor() if back: cursor.movePosition(QTextCursor.End) else: cursor.movePosition(QTextCursor.Start) self.notesEdit.setTextCursor(cursor) self.findMain(text, flags) # self.notesView.findText(text, flags) def findMain(self, text, flags): viewFlags = QWebPage.FindFlags( flags) | QWebPage.FindWrapsAroundDocument if flags: self.notesView.findText(text, viewFlags) return self.notesEdit.find(text, flags) else: self.notesView.findText(text) return self.notesEdit.find(text) def sortLines(self): ''' sort selected lines TODO: second sort reverse the order ''' cursor = self.notesEdit.textCursor() start = cursor.selectionStart() end = cursor.selectionEnd() cursor.setPosition(start) cursor.movePosition(QTextCursor.StartOfLine) cursor.setPosition(end, mode=QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, mode=QTextCursor.KeepAnchor) text = cursor.selectedText() lines = text.split('\u2029') # '\u2029' is the line break sortedLines = sorted(lines) cursor.insertText('\n'.join(sortedLines)) def notesEditInFocus(self, e): if e.gotFocus: self.actions['insertImage'].setEnabled(True) # if e.lostFocus: # self.actionInsertImage.setEnabled(False) # QWidget.focusInEvent(self,f) def searchNote(self): """ Sorting criteria: "title > path > content" Search matches are organized into html source. """ pattern = self.searchEdit.text() if not pattern: return results = [] print("Searching using", pattern) with self.ix.searcher() as searcher: matches = [] queryp = QueryParser("content", self.ix.schema) #allow escaped qutoes when regex searching queryp.add_plugin( RegexPlugin(expr=r'r"(?P<text>[^"\\]*(\\.[^"\\]*)*)"')) # ~~r"pattern" is the desired regex term format~~ Don't autoforce regexing query = queryp.parse(pattern) #print("durp durp", query) ms = searcher.search(query, limit=None) # default limit is 10! for m in ms: #if not m in matches: matches.append(m) for r in matches: title = r['title'] path = r['path'] term = r.highlights("content") results.append([title, path, term]) html = "" for title, path, hi in results: html += ("<p><a href='" + path + "'>" + title + "</a><br/><span class='path'>" + path + "</span><br/>" + hi + "</p>") self.searchView.setHtml(html) print("Finished searching", pattern) def whoosh_index(self): it = QTreeWidgetItemIterator(self.notesTree, QTreeWidgetItemIterator.All) print("Starting complete indexing.") #writer = self.ix.writer() writer = AsyncWriter(self.ix) while it.value(): treeItem = it.value() name = self.notesTree.itemToPage(treeItem) path = os.path.join(self.notesTree.pageToFile(name)).replace( os.sep, '/') print(path) fileobj = open(path, 'r', encoding='utf-8') content = fileobj.read() fileobj.close() if METADATA_CHECKER.match( content) and 'meta' in self.settings.extensions: no_metadata_content = METADATA_CHECKER.sub("", content, count=1).lstrip() self.settings.md.reset().convert(content) writer.update_document( path=name, title=parseTitle(content, name), content=no_metadata_content, tags=','.join(self.settings.md.Meta.get('tags', [])).strip()) else: writer.add_document(path=name, title=parseTitle(content, name), content=content, tags='') it += 1 writer.commit() print("Finished completely reindexing.") def listItemChanged(self, row): if row != -1: item = self.searchList.currentItem().data(Qt.UserRole) self.notesTree.setCurrentItem(item) flags = QWebPage.HighlightAllOccurrences self.notesView.findText(self.searchEdit.text(), flags) def setCurrentNote(self): item = self.notesTree.currentItem() name = self.notesTree.itemToPage(item) # Current note is inserted to head of list. notes = self.settings.recentViewedNotes() for f in notes: if f == name: notes.remove(f) notes.insert(0, name) recent_notes_n = Mikibook.settings.value('recentNotesNumber', type=int, defaultValue=20) if len(notes) > recent_notes_n: del notes[recent_notes_n:] self.settings.updateRecentViewedNotes(notes) def updateRecentViewedNotes(self): """ Switching notes will trigger this. When Alt pressed, show note number. """ self.viewedList.clear() self.viewedListActions = [] # Check notes exists. viewedNotes = self.settings.recentViewedNotes() existedNotes = [] i = 0 for f in viewedNotes: if self.notesTree.pageExists(f): existedNotes.append(f) names = f.split('/') if self.altPressed and i in range(1, 10): action = self.act(names[-1], self.openFunction(f), 'Alt+' + str(i), True, ViewedNoteIcon(i), 'Alt+' + str(i)) else: action = self.act(names[-1], self.openFunction(f), None, True) self.viewedListActions.append(action) i += 1 if not self.altPressed: self.settings.updateRecentViewedNotes(existedNotes) for action in self.viewedListActions: self.viewedList.addAction(action) if len(self.viewedListActions): self.viewedListActions[0].setChecked(True) def openFunction(self, name): item = self.notesTree.pageToItem(name) return lambda: self.notesTree.setCurrentItem(item) def raiseDock(self, widget): if not widget.isVisible(): widget.show() if widget == self.dockSearch: self.searchEdit.setFocus() widget.raise_() def flipEditAndView(self): index = self.noteSplitter.indexOf(self.notesEdit) if index == 0: self.noteSplitter.insertWidget(1, self.notesEdit) else: self.noteSplitter.insertWidget(0, self.notesEdit) def leftAndRight(self): self.liveView(True) self.noteSplitter.setOrientation(Qt.Horizontal) #self.actionLeftAndRight.setEnabled(False) #self.actionUpAndDown.setEnabled(True) def upAndDown(self): self.liveView(True) self.noteSplitter.setOrientation(Qt.Vertical) #self.actionUpAndDown.setEnabled(False) #self.actionLeftAndRight.setEnabled(True) def readmeHelp(self): readmeFile = '/usr/share/mikidown/README.mkd' if not os.path.exists(readmeFile): readmeFile = os.path.join( os.path.dirname(os.path.dirname(__file__)), 'README.mkd').replace(os.sep, '/') self.importPageCore(readmeFile) def changelogHelp(self): changeLog = "/usr/share/mikidown/Changelog.md" if not os.path.exists(changeLog): changeLog = os.path.join( os.path.dirname(os.path.dirname(__file__)), 'Changelog.md').replace(os.sep, '/') self.importPageCore(changeLog) def keyPressEvent(self, event): """ When Alt pressed, note number will be shown in viewedList. """ if event.key() == Qt.Key_Alt: self.altPressed = True self.updateRecentViewedNotes() else: QMainWindow.keyPressEvent(self, event) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Alt: self.altPressed = False self.updateRecentViewedNotes() else: QMainWindow.keyPressEvent(self, event) def closeEvent(self, event): """ saveGeometry: Saves the current geometry and state for top-level widgets saveState: Restores the state of this mainwindow's toolbars and dockwidgets """ self.saveCurrentNote() self.ix.close() self.notesEdit.ix.close() if hasattr(self.notesTree, 'ix'): self.notesTree.ix.close() self.settings.saveGeometry(self.saveGeometry()) self.settings.saveWindowState(self.saveState()) event.accept() os.close(self.lockPathFH) lockPath = os.path.join(self.settings.notebookPath, '.mikidown_lock') os.remove(lockPath)
class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate("DataStorageBrowser", "Open...")) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Open a datastorage database")) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL("pressed()"), self.loadDatabase) self.expandButton = QToolButton(self.toolBar) self.expandButton.setText("Expand/Collapse") self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col))) self.expandButton.setToolTip( QCoreApplication.translate("DataStorageBrowser", "Expand or collapse the whole tree") ) self.toolBarLayout.addWidget(self.expandButton) self.connect(self.expandButton, SIGNAL("pressed()"), self.expandCollapseAll) self.searchInput = MyLineEdit(self.toolBar) self.searchInput.setText(QCoreApplication.translate("DataStorageBrowser", "Enter search text here")) self.searchInput.setToolTip( QCoreApplication.translate( "DataStorageBrowser", "Enter search text using wildcards here, press ENTER again to go to next match!" ) ) self.toolBarLayout.addWidget(self.searchInput, 100) self.connect(self.searchInput, SIGNAL("returnPressed()"), self.searchItem) self.helpButton = QToolButton(self.toolBar) self.helpButton.setText(QCoreApplication.translate("DataStorageBrowser", "Help")) self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help))) self.helpButton.setToolTip(QCoreApplication.translate("DataStorageBrowser", "Show help for DataStorageBrowser")) self.toolBarLayout.addWidget(self.helpButton) self.connect(self.helpButton, SIGNAL("pressed()"), self.showHelp) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None self.searchText = "" self.searchResults = [] self.collExpand = SimuVis4.Misc.Switcher() self.statusBar = SimuVis4.Globals.mainWin.statusBar() def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory( self, QCoreApplication.translate("DataStorageBrowser", "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder, ) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.collapseAll() self.treeView.expandToDepth(SimuVis4.Globals.config.getint("datastoragebrowser", "expand_tree_depth")) self.treeView.resizeColumnToContents(0) def showHelp(self): SimuVis4.HelpBrowser.showHelp("/plugin/DataStorageBrowser/index.html") def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == "R": txt = rootInfo.substitute( name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n) ) + formatMetaData(n) elif t == "P": txt = projectInfo.substitute( name=n.name, path=escape(n.parent.name), title=escape(n.title), groups=len(n) ) + formatMetaData(n) elif t == "G": txt = groupInfo.substitute( name=n.name, path="/".join(n.path.split("/")[:-1]), title=escape(n.title), sensors=len(n), charts=len(n.getCharts()), start=formatTime(n.timegrid.start), stop=formatTime(n.timegrid.stop), step=n.timegrid.step, timezone=n.timegrid.timezone, ) + formatMetaData(n) elif t == "S": txt = sensorInfo.substitute( name=n.name, path="/".join(n.path.split("/")[:-1]), title=escape(n.title), start=formatTime(n.timegrid.start), stop=formatTime(n.timegrid.stop), step=n.timegrid.step, length=n.datalen(), timezone=n.timegrid.timezone, ) + formatMetaData(n) elif t == "C": txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path) self.textBrowser.setText(txt) msg = ": ".join(str(self.model.itemFromIndex(mi).data().toString()).split("|")[1:]) self.statusBar.showMessage(msg, 5000) def searchItem(self): """execute the search and highlight the (next) result""" txt = str(self.searchInput.text()) if txt != self.searchText: self.searchText = txt tmp = self.model.findItems( txt, Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive ) self.searchList = [i.index() for i in tmp] if self.searchList: mi = self.searchList.pop() self.treeView.setCurrentIndex(mi) self.treeView.expand(mi) self.treeView.scrollTo(mi) else: QMessageBox.information( self, QCoreApplication.translate("DataStorageBrowser", "No (more) matches!"), QCoreApplication.translate( "DataStorageBrowser", "No (more) matches found! Change you search text and try again!" ), ) self.searchText = "" def expandCollapseAll(self): if self.collExpand(): self.treeView.collapseAll() else: self.treeView.expandAll() def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == "S": if qwtPlotWindowActive(): self.addToQwtPlot(n) else: self.showQwtPlot(n) elif t == "C": self.showChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t == "R": m.addAction(QCoreApplication.translate("DataStorageBrowser", "Close"), self.closeDatabase) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Reload"), self.reloadDatabase) elif t == "P": m.addAction(QCoreApplication.translate("DataStorageBrowser", "New sensorgroup"), self.newSensorGroup) elif t == "G": nCharts = len(n.getCharts()) if nCharts > 0: txt = str(QCoreApplication.translate("DataStorageBrowser", "Show all charts (%d)")) % nCharts m.addAction(txt, self.showAllCharts) m.addAction( QCoreApplication.translate("DataStorageBrowser", "Save all charts as images"), self.saveAllChartImages, ) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add chart"), self.newChart) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add/update data"), self.importFiles) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Export data"), self.exportSensors) elif t == "S": m.addAction(QCoreApplication.translate("DataStorageBrowser", "New plot (Qwt)"), self.showQwtPlot) if qwtPlotWindowActive(): m.addAction(QCoreApplication.translate("DataStorageBrowser", "Add to plot (Qwt)"), self.addToQwtPlot) elif t == "C": m.addAction(QCoreApplication.translate("DataStorageBrowser", "Show"), self.showChart) m.addAction(QCoreApplication.translate("DataStorageBrowser", "Delete"), self.deleteItem) if t in "RPGS": m.addSeparator() m.addAction(QCoreApplication.translate("DataStorageBrowser", "Edit metadata"), self.editMetadata) a = m.exec_(self.treeView.mapToGlobal(pos)) def newSensorGroup(self, mi=None): if mi is None: mi = self.selectedMI newSensorGroup(self.model, mi) def showChart(self, ch=None): if ch is None: ch = self.selectedNode showChartWindow(ch, maximized=showChartMaximized) def importFiles(self, mi=None): if mi is None: mi = self.selectedMI importFiles(self.model, mi) def showAllCharts(self, sg=None): if sg is None: sg = self.selectedNode showAllChartWindows(sg, maximized=showChartMaximized) def saveAllChartImages(self, sg=None): if sg is None: sg = self.selectedNode saveAllChartImages(sg) def exportSensors(self, sg=None): if sg is None: sg = self.selectedNode exportSensors(sg) def showQwtPlot(self, se=None): if se is None: se = self.selectedNode showQwtPlotWindow(se, maximized=showChartMaximized) def addToQwtPlot(self, se=None): if se is None: se = self.selectedNode addToQwtPlotWindow(se) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def closeDatabase(self, mi=None): if mi is None: mi = self.selectedMI self.model.closeDatabase(mi) def reloadDatabase(self, mi=None): if mi is None: mi = self.selectedMI dbPath = self.model.dsFolder(mi) self.model.closeDatabase(mi) self.loadDatabase(dbPath) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi, self) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)
class __CentralWidget(QWidget): ############################################################################### # CentralWidget SIGNALS ############################################################################### """ splitterCentralRotated() """ ############################################################################### def __init__(self, parent=None): QWidget.__init__(self, parent) self.parent = parent # This variables are used to save the splitter sizes before hide self._splitterMainSizes = None self._splitterAreaSizes = None self.lateralPanel = None hbox = QHBoxLayout(self) hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) # Create Splitters to divide the UI in: MainPanel, Explorer, Misc self._splitterArea = QSplitter(Qt.Horizontal) self._splitterMain = QSplitter(Qt.Vertical) # Create scrollbar for follow mode self.scrollBar = QScrollBar(Qt.Vertical, self) self.scrollBar.setFixedWidth(20) self.scrollBar.setToolTip("Follow Mode: Scroll the Editors together") self.scrollBar.hide() self.connect(self.scrollBar, SIGNAL("valueChanged(int)"), self.move_follow_scrolls) # Add to Main Layout hbox.addWidget(self.scrollBar) hbox.addWidget(self._splitterArea) def insert_central_container(self, container): self.mainContainer = container self._splitterMain.insertWidget(0, container) def insert_lateral_container(self, container): self.lateralPanel = LateralPanel(container) self._splitterArea.insertWidget(0, self.lateralPanel) def insert_bottom_container(self, container): self.misc = container self._splitterMain.insertWidget(1, container) def showEvent(self, event): # Show Event QWidget.showEvent(self, event) # Avoid recalculate the panel sizes if they are already loaded if self._splitterArea.count() == 2: return # Rearrange widgets on Window self._splitterArea.insertWidget(0, self._splitterMain) qsettings = QSettings() # Lists of sizes as list of QVariant- heightList = [QVariant, QVariant] heightList = list(qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3])) widthList = list(qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6])) self._splitterMainSizes = [int(heightList[0]), int(heightList[1])] self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])] if not event.spontaneous(): self.change_misc_visibility() if bin(settings.UI_LAYOUT)[-1] == "1": self.splitter_central_rotate() if bin(settings.UI_LAYOUT >> 1)[-1] == "1": self.splitter_misc_rotate() if bin(settings.UI_LAYOUT >> 2)[-1] == "1": self.splitter_central_orientation() # Set the sizes to splitters self._splitterMain.setSizes(self._splitterMainSizes) self._splitterArea.setSizes(self._splitterAreaSizes) def change_misc_visibility(self): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() self.misc.hide() widget = self.mainContainer.get_actual_widget() if widget: widget.setFocus() else: self.misc.show() self.misc.gain_focus() def change_main_visibility(self): if self.mainContainer.isVisible(): self.mainContainer.hide() else: self.mainContainer.show() def change_explorer_visibility(self, force_hide=False): if self.lateralPanel.isVisible() or force_hide: self._splitterAreaSizes = self._splitterArea.sizes() self.lateralPanel.hide() else: self.lateralPanel.show() def splitter_central_rotate(self): w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1) self._splitterArea.insertWidget(0, w2) self._splitterArea.insertWidget(1, w1) self.emit(SIGNAL("splitterCentralRotated()")) def splitter_central_orientation(self): if self._splitterArea.orientation() == Qt.Horizontal: self._splitterArea.setOrientation(Qt.Vertical) else: self._splitterArea.setOrientation(Qt.Horizontal) def splitter_misc_rotate(self): w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1) self._splitterMain.insertWidget(0, w2) self._splitterMain.insertWidget(1, w1) def splitter_misc_orientation(self): if self._splitterMain.orientation() == Qt.Horizontal: self._splitterMain.setOrientation(Qt.Vertical) else: self._splitterMain.setOrientation(Qt.Horizontal) def get_area_sizes(self): if self.lateralPanel.isVisible(): self._splitterAreaSizes = self._splitterArea.sizes() return self._splitterAreaSizes def get_main_sizes(self): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() return self._splitterMainSizes def enable_follow_mode_scrollbar(self, val): if val: editorWidget = self.mainContainer.get_actual_editor() maxScroll = editorWidget.verticalScrollBar().maximum() position = editorWidget.verticalScrollBar().value() self.scrollBar.setMaximum(maxScroll) self.scrollBar.setValue(position) self.scrollBar.setVisible(val) def move_follow_scrolls(self, val): widget = self.mainContainer._tabMain.currentWidget() diff = widget._sidebarWidget.highest_line - val s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar() s2 = self.mainContainer._tabSecondary.currentWidget().verticalScrollBar() s1.setValue(val) s2.setValue(val + diff)
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 MainWindow(QWidget, MainWindowGeneric): def __init__(self, parent): QWidget.__init__(self) MainWindowGeneric.__init__(self) self._parent = parent self._vbox = QVBoxLayout(self) #Splitters self.splitterMain = QSplitter() self.splitterCentral = QSplitter(Qt.Vertical) #Properties Panel self._properties = PropertiesWidget(self) #Central self._central = CentralWidget(self) self.show_start_page() self.splitterCentral.addWidget(self._central) #Display Container self.container = DisplayContainer(self) self._hide_container() self.splitterCentral.addWidget(self.container) height = [(self.height() / 3) * 2, self.height() / 3] self.splitterCentral.setSizes([height[0], height[1]]) #Size Central Splitter self.splitterMain.addWidget(self.splitterCentral) self.splitterMain.addWidget(self._properties) width = [(self.width() / 6) * 5, self.width() / 6] self.splitterMain.setSizes([width[0], width[1]]) self._vbox.addWidget(self.splitterMain) #flag for reload_file self._reloading = False #Shortcuts shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self) shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self) shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self) shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self) shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self) shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self) shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self) shortPrint = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_I), self) shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self) shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self) shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self) shortTitleComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_T), self) shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self) shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self) shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self) shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self) shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self) shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self) shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self) shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self) shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self) shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self) shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self) shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self) shortFollowMode = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F10), self) shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self) shortShowProjectsTree = QShortcut(QKeySequence(Qt.ALT + Qt.Key_1), self) shortShowSymbolsTree = QShortcut(QKeySequence(Qt.ALT + Qt.Key_2), self) #Signal -> Slot self.connect(shortCloseTab, SIGNAL("activated()"), self.close_actual_tab) self.connect(shortNew, SIGNAL("activated()"), self.new_editor) self.connect(shortNewProject, SIGNAL("activated()"), self.new_project) self.connect(shortOpen, SIGNAL("activated()"), self.open_file) self.connect(shortOpenProject, SIGNAL("activated()"), self.open_project_folder) self.connect(shortSave, SIGNAL("activated()"), self.save) self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project) self.connect(shortPrint, SIGNAL("activated()"), self._print_file) self.connect(shortComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().comment()) self.connect(shortIndentLess, SIGNAL("activated()"), lambda: self._central.obtain_editor().indent_less()) self.connect(shortHorizontalLine, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_horizontal_line()) self.connect(shortTitleComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_title_comment()) self.connect(shortRedo, SIGNAL("activated()"), lambda: self._central.obtain_editor().redo()) self.connect(shortHideContainer, SIGNAL("activated()"), self._hide_container) self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor) self.connect(shortHideExplorer, SIGNAL("activated()"), self._hide_explorer) self.connect(shortRunFile, SIGNAL("activated()"), self._run_code) self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program) self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all) self.connect(shortFind, SIGNAL("activated()"), self._open_find) self.connect(shortFindReplace, SIGNAL("activated()"), self._open_find_replace) self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc) self.connect(shortSplitHorizontal, SIGNAL("activated()"), lambda: self.split_tab(True)) self.connect(shortSplitVertical, SIGNAL("activated()"), lambda: self.split_tab(False)) self.connect(shortFollowMode, SIGNAL("activated()"), self._view_follow_mode) self.connect(shortReloadFile, SIGNAL("activated()"), lambda: self.reload_file()) self.connect(shortShowProjectsTree, SIGNAL("activated()"), self.show_projects_tree) self.connect(shortShowSymbolsTree, SIGNAL("activated()"), self.show_symbols_tree) def change_window_title(self, title): self._parent.setWindowTitle('NINJA-IDE - ' + title) def _open_find(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.focus_find(self._central.obtain_editor()) def _open_find_replace(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.replace_visibility(True) self._parent._status.focus_find(self._central.obtain_editor()) def _print_file(self): self.printer = QPrinter(QPrinter.HighResolution) self.printer.setPageSize(QPrinter.A4) if self._central.obtain_editor().path: fileName = manage_files.get_basename(self._central.obtain_editor().path) fileName = fileName[:fileName.rfind('.')] + '.pdf' else: fileName = 'newDocument.pdf' self.printer.setOutputFileName(fileName) dialog = QPrintDialog(self.printer, self) if dialog.exec_(): self.printer.setDocName(manage_files.get_basename(self._central.obtain_editor().path)) self._central.obtain_editor().document().print_(self.printer) def _hide_container(self): if self.containerIsVisible: self.container.hide() self.containerIsVisible = False self._central.obtain_editor().setFocus() else: self.container.show() self.containerIsVisible = True self.container.gain_focus() def _hide_editor(self): if self._central.isVisible(): self._central.hide() else: self._central.show() def _hide_explorer(self): if self._properties.isVisible(): self._properties.hide() else: self._properties.show() def _splitter_central_orientation(self): if self.splitterCentral.orientation() == Qt.Horizontal: self.splitterCentral.setOrientation(Qt.Vertical) else: self.splitterCentral.setOrientation(Qt.Horizontal) def get_splitter_central_orientation(self): return self.splitterCentral.orientation() def _splitter_main_orientation(self): if self.splitterMain.orientation() == Qt.Horizontal: self.splitterMain.setOrientation(Qt.Vertical) else: self.splitterMain.setOrientation(Qt.Horizontal) def get_splitter_main_orientation(self): return self.splitterMain.orientation() def _splitter_main_rotate(self): w = self.splitterMain.widget(0) w1 = self.splitterMain.widget(1) if type(w) is PropertiesWidget: w.setTabPosition(QTabWidget.East) else: w1.setTabPosition(QTabWidget.West) self.splitterMain.insertWidget(0, w1) self.splitterMain.insertWidget(1, w) def get_splitter_main_position(self): w = self.splitterMain.widget(0) return w.__class__ def _splitter_central_rotate(self): w = self.splitterCentral.widget(0) w1 = self.splitterCentral.widget(1) self.splitterCentral.insertWidget(0, w1) self.splitterCentral.insertWidget(1, w) def get_splitter_central_position(self): w = self.splitterCentral.widget(0) return w.__class__ def get_splitter_position_0(self): return type(self.splitterCentral.widget(0)) def get_splitter_main_position_0(self): return type(self.splitterMain.widget(0)) def reload_panels_position(self): self.settings = QSettings('NINJA-IDE', 'Kunai') self.settings.beginGroup('Preferences') self.settings.beginGroup('Interface') #first with the splitterCentral c = self.splitterCentral.widget(0) c1 = self.splitterCentral.widget(1) if (type(c) == CentralWidget): self.splitterCentral.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], c) self.splitterCentral.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], c1) else: self.splitterCentral.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], c1) self.splitterCentral.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], c) #now with the splitterMain m = self.splitterMain.widget(0) m1 = self.splitterMain.widget(1) if (type(m) == QSplitter): self.splitterMain.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], m) self.splitterMain.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], m1) else: self.splitterMain.insertWidget(self.settings.value('central_tab_position', 0).toInt()[0], m1) self.splitterMain.insertWidget(self.settings.value('container_tab_position', 1).toInt()[0], m) def get_open_projects(self): return self._properties._treeProjects.get_open_projects() def _run_code(self): if self.save(): self.container.show() self.containerIsVisible = True editor = self._central.obtain_editor() ext = self.get_file_extension(editor.path) if ext == 'html': height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(editor.path) elif ext == 'py': height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(editor.path) else: self.execute_file(editor.path, ext) def _run_program(self, actual=None): self.container.show() self.containerIsVisible = True if actual is None: actual = self._properties._treeProjects.actualProject if actual is None: return mainFile = actual.mainFile if mainFile == '': self._properties._treeProjects.open_project_properties() self.containerIsVisible = False self.container.hide() return path = manage_files.create_abs_path(actual.path, mainFile) self._central.save_project_files(actual.path) lang = actual.lang() type_ = actual.projectType if lang == 'html': height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(path) elif lang == 'py': height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(path, actual.pythonPath) else: self.execute_program(path, lang, type_) def _stop_program(self): self.container.kill_application() def _hide_all(self): if self._properties.isVisible(): self._properties.hide() self.container.hide() self._parent._toolbar.hide() else: if self.containerIsVisible: self.container.show() self._properties.show() self._parent._toolbar.show() def show_start_page(self): startPage = Browser(resources.start_page_url, None, self) self.add_tab(startPage, 'Start Page') def show_report_bugs(self): bugsPage = Browser(resources.bugs_page) self.add_tab(bugsPage, 'Report Bugs!') def show_plugins_doc(self): bugsPage = Browser(resources.plugins_doc) self.add_tab(bugsPage, 'How to Write NINJA-IDE plugins') def _show_python_doc(self): process = runner.start_pydoc() docPage = Browser(process[1], process[0]) self.add_tab(docPage, 'Python Documentation') def new_editor(self, lang='py'): if not self._reloading: editor = factory_editor(lang, self._central.actual_tab()) self.add_tab(editor, 'New Document') def add_tab(self, component, title): self._central.actual_tab().add_tab(component, title) def split_tab(self, option): if option: self._central.show_split(Qt.Horizontal) else: self._central.show_split(Qt.Vertical) def _view_follow_mode(self): self._central._show_follow_mode() def new_project(self): project = WizardNewProject(self) project.show() def show_preferences(self): prefs = PreferencesWindow(self) prefs.show() def open_document(self, fileName, project=None): try: if not self._central.actual_tab().is_open(fileName): self._central.actual_tab().notOpening = False editor = factory_editor(fileName, self._central.actual_tab(), project) content = self.read_file_content(fileName) editor.setPlainText(content) editor.path = fileName editor.ask_if_externally_modified = True #self.add_tab(editor, self.get_file_name(fileName)) if not editor.has_write_permission(): fileName += ' (Read-Only)' self.add_tab(editor, self.get_file_name(fileName)) self.change_window_title(fileName) editor.find_errors_and_check_style() else: self._central.actual_tab().move_to_open(fileName) except Exception, reason: print reason QMessageBox.information(self, 'Incorrect File', 'The file couldn\'t be open') self._central.actual_tab().notOpening = True
class MainWindow(QWidget, MainWindowGeneric): def __init__(self, parent): QWidget.__init__(self) MainWindowGeneric.__init__(self) self._parent = parent self.settings = QSettings('NINJA-IDE', 'Kunai') self.settings.beginGroup('Preferences') self.settings.beginGroup('Interface') self._vbox = QVBoxLayout(self) #Splitters self.splitterMain = QSplitter() self.splitterCentral = QSplitter(Qt.Vertical) #Properties Panel self._properties = PropertiesWidget(self) #Central self._central = CentralWidget(self) self.show_start_page() self.splitterCentral.insertWidget( self.settings.value('central_tab_position', 0).toInt()[0], self._central) #Display Container self.container = DisplayContainer(self) self._hide_container() self.splitterCentral.insertWidget( self.settings.value('container_tab_position', 1).toInt()[0], self.container) height = [(self.height() / 3) * 2, self.height() / 3] self.splitterCentral.setSizes([height[self.settings.value('central_tab_position', 0).toInt()[0]], height[self\ .settings.value('container_tab_position', 1).toInt()[0]]]) #Size Central Splitter self.splitterMain.insertWidget( self.settings.value('main_tab_position', 0).toInt()[0], self.splitterCentral) self.splitterMain.insertWidget( self.settings.value('properties_tab_position', 1).toInt()[0], self._properties) width = [(self.width() / 6) * 5, self.width() / 6] self.splitterMain.setSizes([width[self.settings.value('main_tab_position', 0).toInt()[0]],\ width[self.settings.value('properties_tab_position', 1).toInt()[0]]]) self._vbox.addWidget(self.splitterMain) self.settings.endGroup() #End General Preferences self.settings.endGroup() #flag for reload_file self._reloading = False #Shortcuts shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self) shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self) shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self) shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self) shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self) shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self) shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self) shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self) shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self) shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self) shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self) shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self) shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self) shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self) shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self) shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self) shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self) shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self) shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self) shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self) shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self) shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self) shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self) #Signal -> Slot self.connect(shortCloseTab, SIGNAL("activated()"), self.close_actual_tab) self.connect(shortNew, SIGNAL("activated()"), self.new_editor) self.connect(shortNewProject, SIGNAL("activated()"), self.new_project) self.connect(shortOpen, SIGNAL("activated()"), self.open_file) self.connect(shortOpenProject, SIGNAL("activated()"), self.open_project_folder) self.connect(shortSave, SIGNAL("activated()"), self.save) self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project) self.connect(shortComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().comment()) self.connect(shortIndentLess, SIGNAL("activated()"), lambda: self._central.obtain_editor().indent_less()) self.connect( shortHorizontalLine, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_horizontal_line()) self.connect(shortRedo, SIGNAL("activated()"), lambda: self._central.obtain_editor().redo()) self.connect(shortHideContainer, SIGNAL("activated()"), self._hide_container) self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor) self.connect(shortHideExplorer, SIGNAL("activated()"), self._hide_explorer) self.connect(shortRunFile, SIGNAL("activated()"), self._run_code) self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program) self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all) self.connect(shortFind, SIGNAL("activated()"), self._open_find) self.connect(shortFindReplace, SIGNAL("activated()"), self._open_find_replace) self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc) self.connect(shortSplitHorizontal, SIGNAL("activated()"), lambda: self.split_tab(True)) self.connect(shortSplitVertical, SIGNAL("activated()"), lambda: self.split_tab(False)) self.connect(shortReloadFile, SIGNAL("activated()"), lambda: self.reload_file()) def change_window_title(self, title): self._parent.setWindowTitle('NINJA-IDE - ' + title) def _open_find(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.focus_find(self._central.obtain_editor()) def _open_find_replace(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.replace_visibility(True) self._parent._status.focus_find(self._central.obtain_editor()) def _hide_container(self): if self.containerIsVisible: self.container.hide() self.containerIsVisible = False self._central.obtain_editor().setFocus() else: self.container.show() self.containerIsVisible = True self.container.gain_focus() def _hide_editor(self): if self._central.isVisible(): self._central.hide() else: self._central.show() def _hide_explorer(self): if self._properties.isVisible(): self._properties.hide() else: self._properties.show() def _splitter_central_orientation(self): if self.splitterCentral.orientation() == Qt.Horizontal: self.splitterCentral.setOrientation(Qt.Vertical) else: self.splitterCentral.setOrientation(Qt.Horizontal) def get_splitter_central_orientation(self): return self.splitterCentral.orientation() def _splitter_main_orientation(self): if self.splitterMain.orientation() == Qt.Horizontal: self.splitterMain.setOrientation(Qt.Vertical) else: self.splitterMain.setOrientation(Qt.Horizontal) def get_splitter_main_orientation(self): return self.splitterMain.orientation() def _splitter_main_rotate(self): w = self.splitterMain.widget(0) w1 = self.splitterMain.widget(1) self.splitterMain.insertWidget(0, w1) self.splitterMain.insertWidget(1, w) def get_splitter_main_position(self): w = self.splitterMain.widget(0) return w.__class__ def _splitter_central_rotate(self): w = self.splitterCentral.widget(0) w1 = self.splitterCentral.widget(1) self.splitterCentral.insertWidget(0, w1) self.splitterCentral.insertWidget(1, w) def get_splitter_central_position(self): w = self.splitterCentral.widget(0) return w.__class__ def get_splitter_position_0(self): return type(self.splitterCentral.widget(0)) def get_splitter_main_position_0(self): return type(self.splitterMain.widget(0)) def reload_panels_position(self): self.settings = QSettings('NINJA-IDE', 'Kunai') self.settings.beginGroup('Preferences') self.settings.beginGroup('Interface') #first with the splitterCentral c = self.splitterCentral.widget(0) c1 = self.splitterCentral.widget(1) if (type(c) == CentralWidget): self.splitterCentral.insertWidget( self.settings.value('central_tab_position', 0).toInt()[0], c) self.splitterCentral.insertWidget( self.settings.value('container_tab_position', 1).toInt()[0], c1) else: self.splitterCentral.insertWidget( self.settings.value('central_tab_position', 0).toInt()[0], c1) self.splitterCentral.insertWidget( self.settings.value('container_tab_position', 1).toInt()[0], c) #now with the splitterMain m = self.splitterMain.widget(0) m1 = self.splitterMain.widget(1) if (type(m) == QSplitter): self.splitterMain.insertWidget( self.settings.value('central_tab_position', 0).toInt()[0], m) self.splitterMain.insertWidget( self.settings.value('container_tab_position', 1).toInt()[0], m1) else: self.splitterMain.insertWidget( self.settings.value('central_tab_position', 0).toInt()[0], m1) self.splitterMain.insertWidget( self.settings.value('container_tab_position', 1).toInt()[0], m) def get_open_projects(self): return self._properties._treeProjects.get_open_projects() def _run_code(self): if self.save(): self.container.show() self.containerIsVisible = True editor = self._central.obtain_editor() ext = self.get_file_extension(editor.path) if ext == 'html': height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(editor.path) elif ext == 'py': height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(editor.path) else: self.execute_file(editor.path, ext) def _run_program(self, actual=None): self.container.show() self.containerIsVisible = True if actual is None: actual = self._properties._treeProjects.actualProject if actual is None: return mainFile = actual.mainFile if mainFile == '': self._properties._treeProjects.open_project_properties() self.containerIsVisible = False self.container.hide() return path = manage_files.create_abs_path(actual.path, mainFile) self._central.save_project_files(actual.path) lang = actual.lang() type_ = actual.projectType if lang == 'html': height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(path) elif lang == 'py': height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(path) else: self.execute_program(path, lang, type_) def _stop_program(self): self.container.kill_application() def _hide_all(self): if self._properties.isVisible(): self._properties.hide() self.container.hide() self._parent._toolbar.hide() else: if self.containerIsVisible: self.container.show() self._properties.show() self._parent._toolbar.show() def show_start_page(self): startPage = Browser(resources.start_page_url) self.add_tab(startPage, 'Start Page') def show_report_bugs(self): bugsPage = Browser(resources.bugs_page) self.add_tab(bugsPage, 'Report Bugs!') def _show_python_doc(self): process = runner.start_pydoc() docPage = Browser(process[1], process[0]) self.add_tab(docPage, 'Python Documentation') def new_editor(self, lang='py'): if not self._reloading: editor = factory_editor(lang, self._central.actual_tab()) self.add_tab(editor, 'New Document') def add_tab(self, component, title): self._central.actual_tab().add_tab(component, title) def split_tab(self, option): if option: self._central.show_split(Qt.Horizontal) else: self._central.show_split(Qt.Vertical) def new_project(self): project = WizardNewProject(self) project.show() def show_preferences(self): prefs = PreferencesWindow(self) prefs.show() def open_document(self, fileName, project=None): try: if not self._central.actual_tab().is_open(fileName): self._central.actual_tab().notOpening = False editor = factory_editor(fileName, self._central.actual_tab(), project) content = self.read_file_content(fileName) editor.setPlainText(content) editor.path = fileName editor.ask_if_externally_modified = True #self.add_tab(editor, self.get_file_name(fileName)) if not editor.has_write_permission(): fileName += ' (Read-Only)' self.add_tab(editor, self.get_file_name(fileName)) self.change_window_title(fileName) else: self._central.actual_tab().move_to_open(fileName) except Exception, reason: print reason QMessageBox.information(self, 'Incorrect File', 'The file couldn\'t be open') self._central.actual_tab().notOpening = True
def createWidgets(self): """ QtWidgets creation ___________ _________________ | | | | | | | | | | | | | TestsItem | | TextualLogView | | | | | | | | | |___________| |_________________| """ layout = QHBoxLayout() self.logsItem = TestsView.TestsView(parent=self, local=self.local) self.resumeView = ResumeView.TextualView(parent=self) if QtHelper.str2bool( Settings.instance().readValue(key='TestRun/hide-resume-view')): self.hideResumeView() self.graphView = GraphView.FlowChartView(parent=self) self.logsView = TextualView.TextualView2(parent=self) self.hexLogsView = DetailedView.DetailedView(parent=self) self.displayTab = QTabWidget() hSplitter = QSplitter(self) hSplitter.setOrientation(Qt.Vertical) hSplitter.addWidget(self.resumeView) hSplitter.addWidget(self.logsView) hSplitter.addWidget(self.hexLogsView) self.displayTab.addTab(hSplitter, self.tr('Events')) self.displayTab.addTab(self.graphView, self.tr('Diagram')) defaultTab = Settings.instance().readValue( key='TestRun/default-tab-run') self.displayTab.setCurrentIndex(int(defaultTab)) self.currentEdit = QLineEdit() self.currentEdit.setReadOnly(True) self.currentEdit.setStyleSheet( "QLineEdit { background-color : #F0F0F0; color: grey; }") leftFrame = QFrame() leftLayout = QVBoxLayout() leftLayout.setContentsMargins(0, 0, 0, 0) leftFrame.setLayout(leftLayout) leftLayout.addWidget(self.currentEdit) leftLayout.addWidget(self.displayTab) v_splitter = QSplitter(self) v_splitter.addWidget(self.logsItem) v_splitter.addWidget(leftFrame) v_splitter.setStretchFactor(1, 1) layout.addWidget(v_splitter) self.setLayout(layout)
class PlotWidgetContainer(QWidget): def __init__(self, modelRoot, *args, **kwargs): super(PlotWidgetContainer, self).__init__(*args) self.modelRoot = modelRoot if len(moose.wildcardFind(modelRoot + "/##[ISA=ChemCompt]")) == 0: self.modelType = ELECTRICAL else: self.modelType = CHEMICAL self.model = moose.element(self.modelRoot) if self.modelRoot != "/": if moose.exists(modelRoot + "/data"): self.data = moose.element(self.modelRoot + "/data") else: self.data = moose.Neutral(self.modelRoot + "/data") else: self.data = moose.element("/data") self._layout = QVBoxLayout() self.graphs = QSplitter() self.graphs.setOrientation(PyQt4.QtCore.Qt.Vertical) self.graphsArea = QScrollArea() # self.graphsLayout = QGridLayout() # self.menubar = self.createMenuBar() self.rowIndex = 0 # self.setSizePolicy( QtGui.QSizePolicy.Expanding # , QtGui.QSizePolicy.Expanding # ) self.graphs.setSizePolicy( QtGui.QSizePolicy.Expanding , QtGui.QSizePolicy.Expanding ) self.setAcceptDrops(True) # self._layout.setSizeConstraint( QLayout.SetNoConstraint ) # self.graphs.setLayout(self.graphsLayout) self.graphsArea.setWidget(self.graphs) self.graphsArea.setWidgetResizable(True) self.graphWidgets = [] # self._layout.addWidget(self.menubar) self._layout.addWidget(self.graphsArea) self.setLayout(self._layout) for graph in self.data.children: self.addPlotWidget(graph = graph) if len(self.data.children) == 0: self.addPlotWidget() def deleteWidget(self, graphWidget): # print("Deleted => ", graphWidget) self.graphWidgets.remove(graphWidget) graphWidget.setParent(None) graphWidget.close() def createMenuBar(self): bar = sidebar.sidebar() bar.addAction(sidebar.add_graph_action(bar, lambda event: self.addPlotWidget() )) # bar.addAction(sidebar.delete_graph_action(bar, lambda event: self.addPlotWidget() )) # bar.addAction(sidebar.list_action(bar, self.showPlotView)) return bar def addPlotWidget(self, row = None, col = 0, graph = None): if graph == None: graph = moose.Neutral(self.data.path + "/graph_" + str(self.rowIndex)) widget = default.PlotWidget(self.model, graph, self.rowIndex, self) if self.modelType == ELECTRICAL: for axes in widget.canvas.axes.values(): # axes.autoscale(False, axis='x', tight=True) axes.set_ylim(bottom = -0.07, top= 0.03) if row == None: row = self.rowIndex self.graphs.addWidget(widget) self.rowIndex += 1 self.graphWidgets.append(widget) widget.widgetClosedSignal.connect(self.deleteWidget) widget.addGraph.connect(lambda event : self.addPlotWidget()) # widget.resize(1, 1); return widget def showPlotView(self): pass def setModelRoot(self, *args): pass def getMenus(self, *args): return [] def setDataRoot(self, *args): pass def updatePlots(self): for graphWidget in self.graphWidgets: graphWidget.updatePlots() def rescalePlots(self): for graphWidget in self.graphWidgets: graphWidget.rescalePlots() def extendXAxes(self, xlim): for graphWidget in self.graphWidgets: graphWidget.extendXAxes(xlim) def plotAllData(self): for graphWidget in self.graphWidgets: graphWidget.plotAllData()
class PeakMapExplorer(QDialog): def __init__(self, parent=None): super(PeakMapExplorer, self).__init__(parent) self.setWindowFlags(Qt.Window) self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowFlags(Qt.Window) def keyPressEvent(self, e): if e.key() != Qt.Key_Escape: super(PeakMapExplorer, self).keyPressEvent(e) def setup(self, peakmap, peakmap2=None, extra_items=None): self.setup_widgets_and_layout() self.connect_signals_and_slots() self.setup_peakmap_plotter(peakmap, peakmap2, extra_items) self.setup_processing_parameters() self.plot_peakmap() def connect_signals_and_slots(self): self.params.paramsChanged.connect(self.peakmap_plotter.set_processing_parameters) def setup_processing_parameters(self): self.params.setup_initial_values(gamma_min=0.05, gamma_max=10.0, gamma_start=4.0, log_scale=True, imin=self.imin, imax=self.imax) def setup_peakmap_plotter(self, peakmap, peakmap2, extra_items): self.peakmap = peakmap # .getDominatingPeakmap() self.dual_mode = peakmap2 is not None self.peakmap2 = peakmap2 if self.dual_mode: self.peakmap2 = peakmap2.getDominatingPeakmap() (self.rtmin, self.rtmax, self.mzmin, self.mzmax, self.imin, self.imax) = get_range(peakmap, peakmap2) # jparam = PeakMapProcessingParameters(self.params.gamma_start, True, 0, self.imax) # self.peakmap_plotter.set_processing_parameters(param) def plot_peakmap(self): # includes replot: self.peakmap_plotter.update_image_limits(self.rtmin, self.rtmax, self.mzmin, self.mzmax) def setup_widgets_and_layout(self): sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.gridLayout = QGridLayout(self) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) self.peakmap_plotter = PeakmapPlotter(self.splitter) self.verticalLayoutWidget = QWidget(self.splitter) self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setMargin(0) self.params = PeakMapScalingParameters(self.verticalLayoutWidget) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.params.sizePolicy().hasHeightForWidth()) self.params.setSizePolicy(sizePolicy) self.verticalLayout.addWidget(self.params) spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) self.verticalLayout.addItem(spacerItem) self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
class EventLogViewer(QWidget): def __init__(self, node=None, chunks=None, parent=None): super(EventLogViewer, self).__init__(parent) self.display_mode = 0 # self.chunks = chunks self.node = node self.evtx_parser = EvtxXml(chunks, self.node) self.level = [ ':/audit_success', ':/audit_failure', ':/error', ':/warning', ':/info', ':/chat.png' ] self.txt = [ 'Audit success', 'Audit failure', 'Error', 'Warning', 'Information', 'Comment' ] self.disp = None self.current_row = 0 self.widget = None self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setMargin(3) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Horizontal) #self.evtx_table_view = QTableWidget(self.splitter) self.evtx_table_view = EvtxTableView(self.splitter, self) self.admin_pannel = EvtxAdminPannel(self.splitter, chunks or []) self.verticalLayout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 2) if PYQT_VERSION_STR >= "4.5.0": self.evtx_table_view.cellDoubleClicked.connect(self.dispEvent) self.admin_pannel.admin_events.clicked.connect( self.dispAdminEvents) self.admin_pannel.choose_event_type.activated.connect( self.dispEventType) self.admin_pannel.cb.activated.connect(self.dispIdL) self.admin_pannel.cbs.activated.connect(self.dispSourceL) self.admin_pannel.search_id.clicked.connect(self.dispId) self.admin_pannel.search_source.clicked.connect(self.dispSource) self.admin_pannel.search_date.clicked.connect(self.dispDate) else: QObject.connect(self.evtx_table_view, SIGNAL("cellDoubleClicked(int, int)"), self.dispEvent) QObject.connect(self.admin_pannel.admin_events, SIGNAL("clicked(bool)"), self.dispAdminEvents) QObject.connect(self.admin_pannel.search_id, SIGNAL("clicked(bool)"), self.dispId) QObject.connect(self.admin_pannel.search_source, SIGNAL("clicked(bool)"), self.dispSource) QObject.connect(self.admin_pannel.search_date, SIGNAL("clicked(bool)"), self.dispSource) QObject.connect(self.admin_pannel.choose_event_type, SIGNAL("currentIndexChanged(int)"), self.dispEventType) def addEvents(self, events): self.evtx_table_view.addEvents(events) def display(self, chunks, node=None): self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) nb_chunk = 0 evtxInfos = [] for chunk in chunks: events = chunk.events() for event in events: QCoreApplication.processEvents() if node: nodePtr = node.uid() elif self.node: nodePtr = self.node.uid() else: nodePtr = None evtxInfo = EvtxInfo(event, events[event], nb_chunk, nodePtr) evtxInfos.append(evtxInfo) nb_chunk += 1 self.addEvents(evtxInfos) def display_chunk(self, events): self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) evtxInfos = [] for event in events: for evtx in event: QCoreApplication.processEvents() evtxInfo = EvtxInfo(evtx, event[evtx], event[evtx]['chunk_nb'], self.node.uid()) evtxInfos.append(evtxInfo) def dispAdminEvents(self, checked): self.evtx_table_view.clearContents() if self.display_mode == 0: error_list = self.evtx_parser.getEventBylevel(2) self.admin_pannel.admin_events.setText("All events") tmp_list = self.evtx_parser.getEventBylevel(3) error_list.extend(tmp_list) self.display_mode = 1 self.display_chunk(error_list) elif self.display_mode == 1: self.admin_pannel.admin_events.setText("Admin. events") self.display_mode = 0 processus_manager = ModuleProcessusManager() evtx = processus_manager.get('evtx') chunks = evtx.data(self.node.uid()) self.display(chunks, self.node) def dispId(self, checked): txt = self.admin_pannel.id.text() if txt == "": return try: event_list = self.evtx_parser.getEventById(int(txt)) self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) self.display_chunk(event_list) except ValueError: pass def dispIdL(self): txt = self.admin_pannel.id.text() txt = self.admin_pannel.cb.currentText() try: event_list = self.evtx_parser.getEventById(int(txt)) self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) self.display_chunk(event_list) except ValueError: pass def fill_log_viewer(self, item): ptr = item.data(QListWidgetItem.UserType) node = VFS.Get().getNodeById(ptr.toULongLong()[0]) processus_manager = ModuleProcessusManager() evtx = processus_manager.get('evtx') self.node = node self.evtx_parser.chunks = evtx.data(ptr.toULongLong()[0]) self.evtx_parser.node = node self.admin_pannel.cb = self.admin_pannel.initId( evtx.data(ptr.toULongLong()[0]), 'id') self.admin_pannel.cbs = self.admin_pannel.initId( evtx.data(ptr.toULongLong()[0]), 'source') self.display(evtx.data(ptr.toULongLong()[0]), node) def dispDate(self, checked): date_begin = str(self.admin_pannel.select_date_b.dateTime().toString( "yyyy-MM-ddThh:mm:ss")) date_end = str(self.admin_pannel.select_date_e.dateTime().toString( "yyyy-MM-ddThh:mm:ss")) self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) event_list = self.evtx_parser.getEventsBetween(date_begin, date_end) self.display_chunk(event_list) def dispSource(self, checked): txt = self.admin_pannel.source.text() if txt == "": return self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) event_list = self.evtx_parser.getEventBySource(txt) self.display_chunk(event_list) def dispSourceL(self, checked): txt = self.admin_pannel.cbs.currentText() self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) event_list = self.evtx_parser.getEventBySource(txt) self.display_chunk(event_list) def dispEventType(self, index): if index == 0: processus_manager = ModuleProcessusManager() evtx = processus_manager.get('evtx') chunks = evtx.data(self.node.uid()) self.display(chunks, self.node) else: self.evtx_table_view.clearContents() self.evtx_table_view.setRowCount(0) event_list = self.evtx_parser.getEventBylevel(index - 1) self.display_chunk(event_list) def dispEvent(self, row, column): item = self.evtx_table_view.item(row, 4) offset_str = item.text() offset = int(offset_str) item = self.evtx_table_view.item(row, 5) chunk_str = item.text() chunk_nb = int(chunk_str) if self.evtx_table_view.columnCount() == 7: item = self.evtx_table_view.item(row, 6).data(QTableWidgetItem.Type) n = item.toULongLong()[0] self.evtx_parser.node = VFS.Get().getNodeById(n) xml = self.evtx_parser.getXML(chunk_nb, offset, self.evtx_parser.node) xml_str = tostring(xml, "utf-8") self.disp = ViewEvtx() self.disp.view.setAlternatingRowColors(1) self.disp.view.setSelectionBehavior(QAbstractItemView.SelectRows) self.disp.view.setSelectionMode(QAbstractItemView.SingleSelection) self.current_row = row if not row: self.disp.prev_evtx.setEnabled(False) if row + 1 == self.evtx_table_view.rowCount(): self.disp.next_evtx.setEnabled(False) self.widget = EvtxTree(xml_str, self.disp) self.disp.textEdit.setText(self.widget.doc.toString(3)) self.disp.view.expandAll() self.disp.view.resizeColumnToContents(0) if PYQT_VERSION_STR >= "4.5.0": self.disp.next_evtx.clicked.connect(self.nextEvent) self.disp.prev_evtx.clicked.connect(self.prevEvent) self.disp.exec_() del self.disp self.disp = None def nextEvent(self, checked): row = self.current_row + 1 self.disp.prev_evtx.setEnabled(True) while row + 1 != self.evtx_table_view.rowCount( ) and self.evtx_table_view.isRowHidden(row): row += 1 # row = self.current_row item = self.evtx_table_view.item(row, 4) offset_str = item.text() offset = int(offset_str) item = self.evtx_table_view.item(row, 5) chunk_str = item.text() chunk_nb = int(chunk_str) node = None if self.evtx_table_view.columnCount() == 7: item = self.evtx_table_view.item(row, 6) node = VFS.Get().getNodeById(long(item.text())) else: node = self.node self.evtx_table_view.setCurrentCell(row, 0) xml = self.evtx_parser.getXML(chunk_nb, offset, node) xml_str = tostring(xml, "utf-8") self.widget = EvtxTree(xml_str, self.disp) self.disp.textEdit.setText(self.widget.doc.toString(3)) self.disp.view.expandAll() self.disp.view.resizeColumnToContents(0) self.current_row = row while row + 1 != self.evtx_table_view.rowCount(): row += 1 if not self.evtx_table_view.isRowHidden(row): return self.disp.next_evtx.setEnabled(False) def prevEvent(self, checked): row = self.current_row - 1 self.disp.next_evtx.setEnabled(True) while row != 0 and self.evtx_table_view.isRowHidden(row): row -= 1 item = self.evtx_table_view.item(row, 4) offset_str = item.text() offset = int(offset_str) item = self.evtx_table_view.item(row, 5) chunk_str = item.text() chunk_nb = int(chunk_str) node = None if self.evtx_table_view.columnCount() == 7: item = self.evtx_table_view.item(row, 6) node = VFS.Get().getNodeById(long(item.text())) else: node = self.node self.current_row = row self.evtx_table_view.setCurrentCell(self.current_row, 0) xml = self.evtx_parser.getXML(chunk_nb, offset, node) xml_str = tostring(xml, "utf-8") self.widget = EvtxTree(xml_str, self.disp) self.disp.textEdit.setText(self.widget.doc.toString(3)) self.disp.view.expandAll() self.disp.view.resizeColumnToContents(0) while row != 0: row -= 1 if not self.evtx_table_view.isRowHidden(row): return self.disp.prev_evtx.setEnabled(False)
class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...')) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database')) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase) self.dropButton = QToolButton(self.toolBar) self.dropButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Close All')) self.dropButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.clear))) self.dropButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Drop all open databases')) self.toolBarLayout.addWidget(self.dropButton) self.connect(self.dropButton, SIGNAL('pressed()'), self.dropDatabases) self.dropButton.setEnabled(False) self.toolBarLayout.addStretch(100) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser', "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.expandToDepth(1) def dropDatabases(self): # FIXME: implement it pass def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == 'R': # FIXME: no metadata? txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)) # + formatMetaData(n) elif t == 'P': txt = projectInfo.substitute(name=n.name, title=escape(n.title), groups=len(n)) + formatMetaData(n) elif t == 'G': txt = groupInfo.substitute(name=n.name, title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n) elif t == 'S': txt = sensorInfo.substitute(name=n.name, title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop, step=n.timegrid.step, length=n.datalen()) + formatMetaData(n) elif t == 'C': txt = chartInfo.substitute(name=n.name) self.textBrowser.setText(txt) def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == 'R': pass elif t == 'P': pass elif t == 'G': pass elif t == 'S': print n self.showQwtPlot(n) elif t == 'C': self.showMplChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t in 'RPGS': p = m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata) if t == 'R': pass elif t == 'P': pass elif t == 'G': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart) elif t == 'S': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot) elif t == 'C': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem) a = m.exec_(self.treeView.mapToGlobal(pos)) def showMplChart(self, node=None): if node is None: node = self.selectedNode showChartMplWindow(node, maximized=showChartMaximized) def showQwtPlot(self, node=None): if node is None: node = self.selectedNode showQwtPlotWindow(node, maximized=showChartMaximized) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)
def __init__(self, manager): self.manager = manager KDialog.__init__(self, manager.mainwin) self.setCaption(i18n("Expansion Manager")) self.setButtons(KDialog.ButtonCode( KDialog.Help | KDialog.Ok | KDialog.Close | KDialog.User1 | KDialog.User2 )) self.setButtonGuiItem(KDialog.User1, KStandardGuiItem.remove()) self.setButtonGuiItem(KDialog.User2, KStandardGuiItem.add()) self.setHelp("expand") layout = QVBoxLayout(self.mainWidget()) layout.setContentsMargins(0, 0, 0, 0) search = KTreeWidgetSearchLine() search.setClickMessage(i18n("Search...")) layout.addWidget(search) splitter = QSplitter() splitter.setOrientation(Qt.Vertical) layout.addWidget(splitter) tree = QTreeWidget() tree.setColumnCount(3) tree.setHeaderLabels((i18n("Name"), i18n("Description"), i18n("Shortcut"))) tree.setRootIsDecorated(False) tree.setAllColumnsShowFocus(True) search.setTreeWidget(tree) splitter.addWidget(tree) box = KVBox() splitter.addWidget(box) key = KKeySequenceWidget(box) key.layout().setContentsMargins(0, 0, 0, 0) key.layout().insertStretch(0, 1) key.setEnabled(False) edit = QTextEdit(box) edit.setAcceptRichText(False) edit.setStyleSheet("QTextEdit { font-family: monospace; }") edit.item = None edit.dirty = False ExpandHighlighter(edit.document()) # whats this etc. tree.setWhatsThis(i18n( "This is the list of defined expansions.\n\n" "Click on a row to see or change the associated text. " "Doubleclick a shortcut or its description to change it. " "You can also press F2 to edit the current shortcut.\n\n" "Use the buttons below to add or remove expansions.\n\n" "There are two ways to use the expansion: either type the " "shortcut in the text and then call the Expand function, or " "just call the Expand function (default shortcut: Ctrl+.), " "choose the expansion from the list and press Enter or click Ok." )) edit.setWhatsThis( "<html><head><style type='text/css'>" "td.short {{ font-family: monospace; font-weight: bold; }}" "</style></head><body>" "<p>{0}</p><table border=0 width=300 cellspacing=2><tbody>" "<tr><td class=short align=center>(|)</td><td>{1}</td></tr>" "<tr><td class=short align=center>@</td><td>{2}</td></tr>" "</tbody></table></body></html>".format( i18n("This is the text associated with the selected shortcut. " "Some characters have special meaning:"), i18n("Place the cursor on this spot."), i18n("Translate the following pitch."), )) self.searchLine = search self.treeWidget = tree self.key = key self.edit = edit self.restoreDialogSize(config()) # load the expansions for name in sorted(self.manager.expansionsList()): self.createItem(name, self.manager.description(name)) tree.sortByColumn(1, Qt.AscendingOrder) tree.setSortingEnabled(True) tree.resizeColumnToContents(1) self.user1Clicked.connect(self.removeItem) self.user2Clicked.connect(self.addItem) edit.textChanged.connect(self.editChanged) search.textChanged.connect(self.checkMatch) tree.itemSelectionChanged.connect(self.updateSelection) tree.itemChanged.connect(self.itemChanged, Qt.QueuedConnection) key.keySequenceChanged.connect(self.keySequenceChanged)
class __CentralWidget(QWidget): ############################################################################### # CentralWidget SIGNALS ############################################################################### """ splitterCentralRotated() """ ############################################################################### def __init__(self, parent=None): QWidget.__init__(self, parent) self.parent = parent #This variables are used to save the splitter sizes before hide self._splitterMainSizes = None self._splitterAreaSizes = None self.lateralPanel = None hbox = QHBoxLayout(self) hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) #Create Splitters to divide the UI in: MainPanel, Explorer, Misc self._splitterArea = QSplitter(Qt.Horizontal) self._splitterMain = QSplitter(Qt.Vertical) #Create scrollbar for follow mode self.scrollBar = QScrollBar(Qt.Vertical, self) self.scrollBar.setFixedWidth(20) self.scrollBar.setToolTip('Follow Mode: Scroll the Editors together') self.scrollBar.hide() self.connect(self.scrollBar, SIGNAL("valueChanged(int)"), self.move_follow_scrolls) #Add to Main Layout hbox.addWidget(self.scrollBar) hbox.addWidget(self._splitterArea) def insert_central_container(self, container): self.mainContainer = container self._splitterMain.insertWidget(0, container) def insert_lateral_container(self, container): self.lateralPanel = LateralPanel(container) self._splitterArea.insertWidget(0, self.lateralPanel) def insert_bottom_container(self, container): self.misc = container self._splitterMain.insertWidget(1, container) def showEvent(self, event): #Show Event QWidget.showEvent(self, event) #Avoid recalculate the panel sizes if they are already loaded if self._splitterArea.count() == 2: return #Rearrange widgets on Window self._splitterArea.insertWidget(0, self._splitterMain) qsettings = QSettings() #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant] heightList = list( qsettings.value("window/central/mainSize", [(self.height() / 3) * 2, self.height() / 3])) widthList = list( qsettings.value("window/central/areaSize", [(self.width() / 6) * 5, self.width() / 6])) self._splitterMainSizes = [int(heightList[0]), int(heightList[1])] self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])] if not event.spontaneous(): self.change_misc_visibility() if bin(settings.UI_LAYOUT)[-1] == '1': self.splitter_central_rotate() if bin(settings.UI_LAYOUT >> 1)[-1] == '1': self.splitter_misc_rotate() if bin(settings.UI_LAYOUT >> 2)[-1] == '1': self.splitter_central_orientation() #Set the sizes to splitters self._splitterMain.setSizes(self._splitterMainSizes) self._splitterArea.setSizes(self._splitterAreaSizes) self.misc.setVisible( qsettings.value("window/show_misc", False, type=bool)) def change_misc_visibility(self): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() self.misc.hide() widget = self.mainContainer.get_actual_widget() if widget: widget.setFocus() else: self.misc.show() self.misc.gain_focus() def change_main_visibility(self): if self.mainContainer.isVisible(): self.mainContainer.hide() else: self.mainContainer.show() def change_explorer_visibility(self, force_hide=False): if self.lateralPanel.isVisible() or force_hide: self._splitterAreaSizes = self._splitterArea.sizes() self.lateralPanel.hide() else: self.lateralPanel.show() def splitter_central_rotate(self): w1, w2 = self._splitterArea.widget(0), self._splitterArea.widget(1) self._splitterArea.insertWidget(0, w2) self._splitterArea.insertWidget(1, w1) self.emit(SIGNAL("splitterCentralRotated()")) def splitter_central_orientation(self): if self._splitterArea.orientation() == Qt.Horizontal: self._splitterArea.setOrientation(Qt.Vertical) else: self._splitterArea.setOrientation(Qt.Horizontal) def splitter_misc_rotate(self): w1, w2 = self._splitterMain.widget(0), self._splitterMain.widget(1) self._splitterMain.insertWidget(0, w2) self._splitterMain.insertWidget(1, w1) def splitter_misc_orientation(self): if self._splitterMain.orientation() == Qt.Horizontal: self._splitterMain.setOrientation(Qt.Vertical) else: self._splitterMain.setOrientation(Qt.Horizontal) def get_area_sizes(self): if self.lateralPanel.isVisible(): self._splitterAreaSizes = self._splitterArea.sizes() return self._splitterAreaSizes def get_main_sizes(self): if self.misc.isVisible(): self._splitterMainSizes = self._splitterMain.sizes() return self._splitterMainSizes def enable_follow_mode_scrollbar(self, val): if val: editorWidget = self.mainContainer.get_actual_editor() maxScroll = editorWidget.verticalScrollBar().maximum() position = editorWidget.verticalScrollBar().value() self.scrollBar.setMaximum(maxScroll) self.scrollBar.setValue(position) self.scrollBar.setVisible(val) def move_follow_scrolls(self, val): widget = self.mainContainer._tabMain.currentWidget() diff = widget._sidebarWidget.highest_line - val s1 = self.mainContainer._tabMain.currentWidget().verticalScrollBar() s2 = self.mainContainer._tabSecondary.\ currentWidget().verticalScrollBar() s1.setValue(val) s2.setValue(val + diff)
class WWorkspace(QWidget): """ Workspace widget """ WORKSPACE = 0 UpdateWindowTitle = pyqtSignal(str) RecentFile = pyqtSignal(dict) BusyCursor = pyqtSignal() ArrowCursor = pyqtSignal() def __init__(self, parent=None): """ Constructs WWorkspace widget Signals emited: * updateWindowTitle @param parent: @type parent: """ QWidget.__init__(self, parent) self.parent = parent self.type = self.WORKSPACE self.name = self.tr('Workspace') # create each part WRepositories.initialize(parent=self) WDocumentViewer.initialize(parent=self, iRepo=WRepositories.instance(), lRepo=WRepositories.LocalRepository, rRepo=WRepositories.RemoteRepository) WDocumentProperties.initialize(parent=self, iRepo=WRepositories.instance(), lRepo=WRepositories.LocalRepository, rRepo=WRepositories.RemoteRepository) WHelper.initialize(parent=self) # splitter state self.splitterState = None self.splitterHelperState = None # create widget self.createWidgets() self.createActions() self.creationConnections() def createWidgets(self): """ QtWidgets creation _________ _______________________ _________ / \__________ | | / \__ | | Q | | Q | | | WRepositories | S | | S | | | | p | | p | | |_____________________| l | | l | | _____QSplitter i | WDocumentViewer | i | WHelper | / \__________ t | | t | | | | t | | t | | | WDocumentProperties | e | | e | | | | r | | r | | |_____________________| |_______________________| |_____________| """ self.wCursorPosition = WCursorPosition(self) self.parent.addWidgetToStatusBar(self.wCursorPosition) WDocumentProperties.instance().setDisabled(True) layout = QHBoxLayout(self) # properties | viewer | helper self.vSplitter = QSplitter(self) if not QtHelper.str2bool( Settings.instance().readValue(key='View/tab-left')): self.hSplitter = QSplitter(self) self.hSplitter.setOrientation(Qt.Vertical) self.hSplitter.addWidget(WRepositories.instance()) self.hSplitter.addWidget(WDocumentProperties.instance()) self.hSplitter.setContentsMargins(0, 0, 0, 0) self.vSplitter.addWidget(self.hSplitter) else: WRepositories.instance().hideWidgetsHeader() WDocumentProperties.instance().hideWidgetsHeader() self.leftTab = QTabWidget(self) self.leftTab.addTab(WRepositories.instance(), QIcon(":/folders.png"), self.tr("Repositories")) self.leftTab.addTab(WDocumentProperties.instance(), QIcon(":/controls.png"), self.tr("Test Properties")) self.vSplitter.addWidget(self.leftTab) self.vSplitter.addWidget(WDocumentViewer.instance()) self.vSplitter.setStretchFactor(1, 1) layout.addWidget(self.vSplitter) self.hSplitter2 = QSplitter(self) self.hSplitter2.setOrientation(Qt.Vertical) self.vSplitter.addWidget(self.hSplitter2) self.hSplitter2.addWidget(WHelper.instance()) self.setLayout(layout) def creationConnections(self): """ QtSignals connection: * WRepositories <=> WDocumentViewer.newTab * WDocumentViewer <=> cursorPositionChanged * WDocumentViewer <=> focusChanged """ WRepositories.instance().local().OpenFile.connect( WDocumentViewer.instance().newTab) WDocumentViewer.instance().CursorPositionChanged.connect( self.cursorPositionChanged) WDocumentViewer.instance().TotalLinesChanged.connect( self.totalLinesChanged) WDocumentViewer.instance().FocusChanged.connect(self.focusChanged) WDocumentViewer.instance().BusyCursor.connect(self.emitBusy) WDocumentViewer.instance().ArrowCursor.connect(self.emitIdle) WDocumentViewer.instance().CurrentDocumentChanged.connect( self.currentDocumentChanged) WDocumentViewer.instance().DocumentOpened.connect(self.documentOpened) WDocumentViewer.instance().UpdateWindowTitle.connect( self.updateWindowTitle) WDocumentViewer.instance().DocumentViewerEmpty.connect( self.documentViewerEmpty) # from testplan when the test selection changed in the tree WDocumentViewer.instance().PropertiesChanged.connect( self.propertiesChanged) if WRepositories.instance().localConfigured != "Undefined": if RCI.instance().isAuthenticated(): WDocumentViewer.instance().RefreshLocalRepository.connect( WRepositories.instance().localRepository.refreshAll) WDocumentProperties.instance().RefreshLocalRepository.connect( WRepositories.instance().localRepository.refreshAll) WDocumentViewer.instance().RecentFile.connect(self.recentFileUpdated) WHelper.instance().ShowAssistant.connect(self.onEnterAssistant) WHelper.instance().HideAssistant.connect(self.onLeaveAssistant) # new in v16 WDocumentViewer.instance().ShowPropertiesTab.connect( self.onShowPropertiesTab) def onShowPropertiesTab(self): """ On show properties tabulation """ if QtHelper.str2bool( Settings.instance().readValue(key='View/tab-left')): self.leftTab.setCurrentIndex(TAB_PROPERTIES) def onEnterAssistant(self): """ On mouse enter in the online helper """ pass def onLeaveAssistant(self): """ On mouse leave in the online helper """ pass def createActions(self): """ Create qt actions """ self.hideDeveloperModeAction = QtHelper.createAction( self, self.tr("Developer"), self.hideDeveloperMode, checkable=True, icon=QIcon(":/window-fit.png"), shortcut=Settings.instance().readValue( key='KeyboardShorcuts/developer'), tip=self.tr('Fit the document viewer to maximize the editor area')) WDocumentViewer.instance().addActionToolbar( action=self.hideDeveloperModeAction) def emitBusy(self): """ Emit busy """ self.BusyCursor.emit() def emitIdle(self): """ Emit idle """ self.ArrowCursor.emit() def hideDeveloperMode(self): """ Hide developer mode """ if not self.hideDeveloperModeAction.isChecked(): Settings.instance().setValue(key='View/developer', value='False') self.deactiveDeveloperView() else: Settings.instance().setValue(key='View/developer', value='True') self.activeDeveloperView() def activeDeveloperView(self): """ Activate developer view """ self.splitterState = self.vSplitter.saveState() self.vSplitter.setSizes([0, self.vSplitter.sizes()[1], 0]) def deactiveDeveloperView(self): """ Deactive developer view """ if self.splitterState is not None: self.vSplitter.restoreState(self.splitterState) def mainSplitterMoved(self, index, pos): """ Memorize the new position of the splitter """ Settings.instance().setValue(key='View/helper-pos', value=self.vSplitter.sizes()[2]) def hideHelper(self): """ Hide assistant """ self.splitterHelperState = self.vSplitter.saveState() self.vSplitter.setSizes( [self.vSplitter.sizes()[0], self.vSplitter.sizes()[1], 0]) def showHelper(self): """ Show assistant """ if self.splitterHelperState is not None: self.vSplitter.restoreState(self.splitterHelperState) def documentViewerEmpty(self): """ Called to deactivate the WDocumentProperties widget Hide the WCursorPosition widget in the status bar """ WDocumentProperties.instance().clear() WDocumentProperties.instance().setDisabled(True) self.hideStatusBar() WDocumentViewer.instance().findWidget.hide() def currentDocumentChanged(self, wdocument): """ Called when the current document is changed @param wdocument: @type wdocument: """ # hide cursor position widget on disconnection or on the welcome page if isinstance(wdocument, WDocumentViewer.WelcomePage): self.hideStatusBar() if not RCI.instance().isAuthenticated(): WDocumentProperties.instance().setDisabled(True) return # test properties uneeded for test config, test adapter and library adapters # and welcome page if isinstance(wdocument, WDocumentViewer.WelcomePage): WDocumentProperties.instance().setDisabled(True) WDocumentProperties.instance().clear() elif isinstance(wdocument, TestConfig.WTestConfig) or isinstance(wdocument, TestAdapter.WTestAdapter) \ or isinstance(wdocument, TestTxt.WTestTxt) or isinstance(wdocument, TestLibrary.WTestLibrary) \ or isinstance(wdocument, TestPng.WTestPng) : WDocumentProperties.instance().setDisabled(True) WDocumentProperties.instance().clear() else: WDocumentProperties.instance().setDocument(wdoc=wdocument) WDocumentProperties.instance().setDisabled(False) WDocumentProperties.instance().addDescriptions(wdoc=wdocument) WDocumentProperties.instance().addParameters(wdoc=wdocument) if not isinstance(wdocument, TestData.WTestData): WDocumentProperties.instance().addParametersOutput( wdoc=wdocument) WDocumentProperties.instance().addProbes(wdoc=wdocument) WDocumentProperties.instance().addAgents(wdoc=wdocument) WDocumentViewer.instance().updateActions(wdocument=wdocument) if isinstance(wdocument, TestData.WTestData): WDocumentProperties.instance().disableOutputParameters() WDocumentProperties.instance().disableAgents() WDocumentProperties.instance().disableProbes() else: WDocumentProperties.instance().enableOutputParameters() WDocumentProperties.instance().enableProbes() WDocumentProperties.instance().enableAgents() if not isinstance(wdocument, TestAbstract.WTestAbstract): WDocumentProperties.instance().disableSteps() WDocumentProperties.instance().disableAdapters() WDocumentProperties.instance().disableLibraries() else: WDocumentProperties.instance().addSteps(wdoc=wdocument) WDocumentProperties.instance().enableSteps() WDocumentProperties.instance().addAdapters(wdoc=wdocument) WDocumentProperties.instance().enableAdapters() WDocumentProperties.instance().addLibraries(wdoc=wdocument) WDocumentProperties.instance().enableLibraries() if isinstance(wdocument, TestUnit.WTestUnit) or isinstance( wdocument, TestSuite.WTestSuite): WDocumentProperties.instance().enableMarkUnused() else: WDocumentProperties.instance().disableMarkUnused() # disable/enable status bar if isinstance(wdocument, TestConfig.WTestConfig) \ or isinstance(wdocument, TestPlan.WTestPlan) \ or isinstance(wdocument, TestPng.WTestPng) \ or isinstance(wdocument, TestAbstract.WTestAbstract) \ or isinstance(wdocument, WDocumentViewer.WelcomePage) : self.hideStatusBar() else: self.showStatusBar() self.wCursorPosition.setNumberLines(nb=wdocument.editor().lines()) def propertiesChanged(self, properties, isRoot, testId): """ Called when document propertis changed @param properties: @param properties: dict @param isRoot: @type isRoot: """ if isRoot: WDocumentProperties.instance().addDescriptions(wdoc=properties) WDocumentProperties.instance().addParameters(wdoc=properties) WDocumentProperties.instance().addParametersOutput(wdoc=properties) WDocumentProperties.instance().addAgents(wdoc=properties) WDocumentProperties.instance().addProbes(wdoc=properties) WDocumentProperties.instance().probes.setEnabled(True) else: WDocumentProperties.instance().addParameters(wdoc=properties) WDocumentProperties.instance().addAgents(wdoc=properties) WDocumentProperties.instance().addParametersOutput(wdoc=properties) WDocumentProperties.instance().probes.clear() WDocumentProperties.instance().probes.setEnabled(False) # new in v19 WDocumentProperties.instance().updateCache(properties, isRoot, testId) def documentOpened(self, wdocument): """ Called when a document is opened @param wdocument: @type wdocument: """ WDocumentProperties.instance().setEnabled(True) self.currentDocumentChanged(wdocument=wdocument) def updateWindowTitle(self, windowTitle): """ Emit the signal "updateWindowTitle" to update the title of the application @param windowTitle: new window title @type windowTitle: string """ self.UpdateWindowTitle.emit(windowTitle) def recentFileUpdated(self, fileDescription): """ Emit the signal "recentFile" to update the title of the application @param windowTitle: file descr with the complete path and type @type windowTitle: string """ self.RecentFile.emit(fileDescription) def focusChanged(self, wdocument): """ Called when the focus of the WDocumentViewer is changed @param wdocument: @type wdocument: """ WDocumentViewer.instance().updateActions(wdocument=wdocument) self.wCursorPosition.setNumberLines(nb=wdocument.editor().lines()) def totalLinesChanged(self, nb): """ This function is automaticaly called when the cursor changed in both editors and enables to update the cursor's position in the widget WCursorPosition @param ln: line index @type ln: Integer @param col: column index @type col: Integer """ self.wCursorPosition.setNumberLines(nb=nb) def cursorPositionChanged(self, ln, col): """ This function is automaticaly called when the cursor changed in both editors and enables to update the cursor's position in the widget WCursorPosition @param ln: line index @type ln: Integer @param col: column index @type col: Integer """ self.wCursorPosition.cursorPositionChanged(ln, col) def showStatusBar(self): """ Show WCursorPosition widget """ self.wCursorPosition.show() def hideStatusBar(self): """ Hide WCursorPosition widget """ self.wCursorPosition.hide()
class EntryView(BaseView): def _setup(self): self._setupUi() self.etable = EntryTable(self.model.etable, view=self.tableView) self.efbar = EntryFilterBar(model=self.model.filter_bar, view=self.filterBar) self.bgraph = Chart(self.model.bargraph, view=self.barGraphView) self.lgraph = Chart(self.model.balgraph, view=self.lineGraphView) self._setupColumns() # Can only be done after the model has been connected self.reconciliationButton.clicked.connect(self.model.toggle_reconciliation_mode) def _setupUi(self): self.resize(483, 423) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) self.verticalLayout.setMargin(0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(0) self.filterBar = RadioBox(self) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.filterBar.sizePolicy().hasHeightForWidth()) self.filterBar.setSizePolicy(sizePolicy) self.horizontalLayout.addWidget(self.filterBar) self.horizontalLayout.addItem(horizontalSpacer()) self.reconciliationButton = QPushButton(tr("Reconciliation")) self.reconciliationButton.setCheckable(True) self.horizontalLayout.addWidget(self.reconciliationButton) self.verticalLayout.addLayout(self.horizontalLayout) self.splitterView = QSplitter() self.splitterView.setOrientation(Qt.Vertical) self.splitterView.setChildrenCollapsible(False) self.tableView = TableView(self) self.tableView.setAcceptDrops(True) self.tableView.setEditTriggers(QAbstractItemView.DoubleClicked|QAbstractItemView.EditKeyPressed) self.tableView.setDragEnabled(True) self.tableView.setDragDropMode(QAbstractItemView.InternalMove) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setSortingEnabled(True) self.tableView.horizontalHeader().setHighlightSections(False) self.tableView.horizontalHeader().setMinimumSectionSize(18) self.tableView.verticalHeader().setVisible(False) self.tableView.verticalHeader().setDefaultSectionSize(18) self.splitterView.addWidget(self.tableView) self.graphView = QStackedWidget(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.graphView.sizePolicy().hasHeightForWidth()) self.graphView.setSizePolicy(sizePolicy) self.graphView.setMinimumSize(0, 200) self.lineGraphView = LineGraphView() self.graphView.addWidget(self.lineGraphView) self.barGraphView = BarGraphView() self.graphView.addWidget(self.barGraphView) self.splitterView.addWidget(self.graphView) self.graphView.setCurrentIndex(1) self.splitterView.setStretchFactor(0, 1) self.splitterView.setStretchFactor(1, 0) self.verticalLayout.addWidget(self.splitterView) def _setupColumns(self): h = self.tableView.horizontalHeader() h.setMovable(True) # column drag & drop reorder #--- QWidget override def setFocus(self): self.etable.view.setFocus() #--- Public def fitViewsForPrint(self, viewPrinter): hidden = self.model.mainwindow.hidden_areas viewPrinter.fitTable(self.etable) if PaneArea.BottomGraph not in hidden: viewPrinter.fit(self.graphView.currentWidget(), 300, 150, expandH=True, expandV=True) def restoreSubviewsSize(self): graphHeight = self.model.graph_height_to_restore if graphHeight: splitterHeight = self.splitterView.height() sizes = [splitterHeight-graphHeight, graphHeight] self.splitterView.setSizes(sizes) #--- model --> view def refresh_reconciliation_button(self): if self.model.can_toggle_reconciliation_mode: self.reconciliationButton.setEnabled(True) self.reconciliationButton.setChecked(self.model.reconciliation_mode) else: self.reconciliationButton.setEnabled(False) self.reconciliationButton.setChecked(False) def show_bar_graph(self): self.graphView.setCurrentIndex(1) def show_line_graph(self): self.graphView.setCurrentIndex(0) def update_visibility(self): hidden = self.model.mainwindow.hidden_areas self.graphView.setHidden(PaneArea.BottomGraph in hidden)
class MainWindow(QWidget, MainWindowGeneric): def __init__(self, parent): QWidget.__init__(self) MainWindowGeneric.__init__(self) self._parent = parent self.settings = QSettings("NINJA-IDE", "Kunai") self.settings.beginGroup("Preferences") self.settings.beginGroup("Interface") self._vbox = QVBoxLayout(self) # Splitters self.splitterMain = QSplitter() self.splitterCentral = QSplitter(Qt.Vertical) # Properties Panel self._properties = PropertiesWidget(self) # Central self._central = CentralWidget(self) self.show_start_page() self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], self._central) # Display Container self.container = DisplayContainer(self) self._hide_container() self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], self.container) height = [(self.height() / 3) * 2, self.height() / 3] self.splitterCentral.setSizes( [ height[self.settings.value("central_tab_position", 0).toInt()[0]], height[self.settings.value("container_tab_position", 1).toInt()[0]], ] ) # Size Central Splitter self.splitterMain.insertWidget(self.settings.value("main_tab_position", 0).toInt()[0], self.splitterCentral) self.splitterMain.insertWidget(self.settings.value("properties_tab_position", 1).toInt()[0], self._properties) width = [(self.width() / 6) * 5, self.width() / 6] self.splitterMain.setSizes( [ width[self.settings.value("main_tab_position", 0).toInt()[0]], width[self.settings.value("properties_tab_position", 1).toInt()[0]], ] ) self._vbox.addWidget(self.splitterMain) self.settings.endGroup() # End General Preferences self.settings.endGroup() # flag for reload_file self._reloading = False # Shortcuts shortCloseTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_W), self) shortNew = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_N), self) shortNewProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_J), self) shortOpen = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_O), self) shortOpenProject = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_P), self) shortSave = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_S), self) shortSaveAll = QShortcut(QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_S), self) shortRedo = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y), self) shortComment = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_D), self) shortHorizontalLine = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_R), self) shortIndentLess = QShortcut(QKeySequence(Qt.SHIFT + Qt.Key_Tab), self) shortHideContainer = QShortcut(QKeySequence(Qt.Key_F4), self) shortHideEditor = QShortcut(QKeySequence(Qt.Key_F3), self) shortHideExplorer = QShortcut(QKeySequence(Qt.Key_F2), self) shortRunFile = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F6), self) shortRunProgram = QShortcut(QKeySequence(Qt.Key_F6), self) shortHideAll = QShortcut(QKeySequence(Qt.Key_F11), self) shortFind = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_F), self) shortFindReplace = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_H), self) shortHelp = QShortcut(QKeySequence(Qt.Key_F1), self) shortSplitHorizontal = QShortcut(QKeySequence(Qt.Key_F10), self) shortSplitVertical = QShortcut(QKeySequence(Qt.Key_F9), self) shortReloadFile = QShortcut(QKeySequence(Qt.Key_F5), self) # Signal -> Slot self.connect(shortCloseTab, SIGNAL("activated()"), self.close_actual_tab) self.connect(shortNew, SIGNAL("activated()"), self.new_editor) self.connect(shortNewProject, SIGNAL("activated()"), self.new_project) self.connect(shortOpen, SIGNAL("activated()"), self.open_file) self.connect(shortOpenProject, SIGNAL("activated()"), self.open_project_folder) self.connect(shortSave, SIGNAL("activated()"), self.save) self.connect(shortSaveAll, SIGNAL("activated()"), self.save_project) self.connect(shortComment, SIGNAL("activated()"), lambda: self._central.obtain_editor().comment()) self.connect(shortIndentLess, SIGNAL("activated()"), lambda: self._central.obtain_editor().indent_less()) self.connect( shortHorizontalLine, SIGNAL("activated()"), lambda: self._central.obtain_editor().insert_horizontal_line() ) self.connect(shortRedo, SIGNAL("activated()"), lambda: self._central.obtain_editor().redo()) self.connect(shortHideContainer, SIGNAL("activated()"), self._hide_container) self.connect(shortHideEditor, SIGNAL("activated()"), self._hide_editor) self.connect(shortHideExplorer, SIGNAL("activated()"), self._hide_explorer) self.connect(shortRunFile, SIGNAL("activated()"), self._run_code) self.connect(shortRunProgram, SIGNAL("activated()"), self._run_program) self.connect(shortHideAll, SIGNAL("activated()"), self._hide_all) self.connect(shortFind, SIGNAL("activated()"), self._open_find) self.connect(shortFindReplace, SIGNAL("activated()"), self._open_find_replace) self.connect(shortHelp, SIGNAL("activated()"), self._show_python_doc) self.connect(shortSplitHorizontal, SIGNAL("activated()"), lambda: self.split_tab(True)) self.connect(shortSplitVertical, SIGNAL("activated()"), lambda: self.split_tab(False)) self.connect(shortReloadFile, SIGNAL("activated()"), lambda: self.reload_file()) def change_window_title(self, title): self._parent.setWindowTitle("NINJA-IDE - " + title) def _open_find(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.focus_find(self._central.obtain_editor()) def _open_find_replace(self): if not self._parent._status.isVisible(): self._parent._status.show() self._parent._status.replace_visibility(True) self._parent._status.focus_find(self._central.obtain_editor()) def _hide_container(self): if self.containerIsVisible: self.container.hide() self.containerIsVisible = False self._central.obtain_editor().setFocus() else: self.container.show() self.containerIsVisible = True self.container.gain_focus() def _hide_editor(self): if self._central.isVisible(): self._central.hide() else: self._central.show() def _hide_explorer(self): if self._properties.isVisible(): self._properties.hide() else: self._properties.show() def _splitter_central_orientation(self): if self.splitterCentral.orientation() == Qt.Horizontal: self.splitterCentral.setOrientation(Qt.Vertical) else: self.splitterCentral.setOrientation(Qt.Horizontal) def get_splitter_central_orientation(self): return self.splitterCentral.orientation() def _splitter_main_orientation(self): if self.splitterMain.orientation() == Qt.Horizontal: self.splitterMain.setOrientation(Qt.Vertical) else: self.splitterMain.setOrientation(Qt.Horizontal) def get_splitter_main_orientation(self): return self.splitterMain.orientation() def _splitter_main_rotate(self): w = self.splitterMain.widget(0) w1 = self.splitterMain.widget(1) self.splitterMain.insertWidget(0, w1) self.splitterMain.insertWidget(1, w) def get_splitter_main_position(self): w = self.splitterMain.widget(0) return w.__class__ def _splitter_central_rotate(self): w = self.splitterCentral.widget(0) w1 = self.splitterCentral.widget(1) self.splitterCentral.insertWidget(0, w1) self.splitterCentral.insertWidget(1, w) def get_splitter_central_position(self): w = self.splitterCentral.widget(0) return w.__class__ def get_splitter_position_0(self): return type(self.splitterCentral.widget(0)) def get_splitter_main_position_0(self): return type(self.splitterMain.widget(0)) def reload_panels_position(self): self.settings = QSettings("NINJA-IDE", "Kunai") self.settings.beginGroup("Preferences") self.settings.beginGroup("Interface") # first with the splitterCentral c = self.splitterCentral.widget(0) c1 = self.splitterCentral.widget(1) if type(c) == CentralWidget: self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], c) self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], c1) else: self.splitterCentral.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], c1) self.splitterCentral.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], c) # now with the splitterMain m = self.splitterMain.widget(0) m1 = self.splitterMain.widget(1) if type(m) == QSplitter: self.splitterMain.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], m) self.splitterMain.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], m1) else: self.splitterMain.insertWidget(self.settings.value("central_tab_position", 0).toInt()[0], m1) self.splitterMain.insertWidget(self.settings.value("container_tab_position", 1).toInt()[0], m) def get_open_projects(self): return self._properties._treeProjects.get_open_projects() def _run_code(self): if self.save(): self.container.show() self.containerIsVisible = True editor = self._central.obtain_editor() ext = self.get_file_extension(editor.path) if ext == "html": height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(editor.path) elif ext == "py": height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(editor.path) else: self.execute_file(editor.path, ext) def _run_program(self, actual=None): self.container.show() self.containerIsVisible = True if actual is None: actual = self._properties._treeProjects.actualProject if actual is None: return mainFile = actual.mainFile if mainFile == "": self._properties._treeProjects.open_project_properties() self.containerIsVisible = False self.container.hide() return path = manage_files.create_abs_path(actual.path, mainFile) self._central.save_project_files(actual.path) lang = actual.lang() type_ = actual.projectType if lang == "html": height = self.height() / 3 self.splitterCentral.setSizes([height, height * 2]) self.container.render_web_page(path) elif lang == "py": height = self.height() / 3 self.splitterCentral.setSizes([height * 2, height]) self.container.run_application(path) else: self.execute_program(path, lang, type_) def _stop_program(self): self.container.kill_application() def _hide_all(self): if self._properties.isVisible(): self._properties.hide() self.container.hide() self._parent._toolbar.hide() else: if self.containerIsVisible: self.container.show() self._properties.show() self._parent._toolbar.show() def show_start_page(self): startPage = Browser(resources.start_page_url) self.add_tab(startPage, "Start Page") def show_report_bugs(self): bugsPage = Browser(resources.bugs_page) self.add_tab(bugsPage, "Report Bugs!") def _show_python_doc(self): process = runner.start_pydoc() docPage = Browser(process[1], process[0]) self.add_tab(docPage, "Python Documentation") def new_editor(self, lang="py"): if not self._reloading: editor = factory_editor(lang, self._central.actual_tab()) self.add_tab(editor, "New Document") def add_tab(self, component, title): self._central.actual_tab().add_tab(component, title) def split_tab(self, option): if option: self._central.show_split(Qt.Horizontal) else: self._central.show_split(Qt.Vertical) def new_project(self): project = WizardNewProject(self) project.show() def show_preferences(self): prefs = PreferencesWindow(self) prefs.show() def open_document(self, fileName, project=None): try: if not self._central.actual_tab().is_open(fileName): self._central.actual_tab().notOpening = False editor = factory_editor(fileName, self._central.actual_tab(), project) content = self.read_file_content(fileName) editor.setPlainText(content) editor.path = fileName editor.ask_if_externally_modified = True # self.add_tab(editor, self.get_file_name(fileName)) if not editor.has_write_permission(): fileName += " (Read-Only)" self.add_tab(editor, self.get_file_name(fileName)) self.change_window_title(fileName) else: self._central.actual_tab().move_to_open(fileName) except Exception, reason: print reason QMessageBox.information(self, "Incorrect File", "The file couldn't be open") self._central.actual_tab().notOpening = True
class PlotWidgetContainer(QWidget): def __init__(self, modelRoot, *args, **kwargs): super(PlotWidgetContainer, self).__init__(*args) self.modelRoot = modelRoot if len(moose.wildcardFind(modelRoot + "/##[ISA=ChemCompt]")) == 0: self.modelType = ELECTRICAL else: self.modelType = CHEMICAL self.model = moose.element(self.modelRoot) if self.modelRoot != "/": if moose.exists(modelRoot + "/data"): self.data = moose.element(self.modelRoot + "/data") else: self.data = moose.Neutral(self.modelRoot + "/data") else: self.data = moose.element("/data") self._layout = QVBoxLayout() self.graphs = QSplitter() self.graphs.setOrientation(PyQt4.QtCore.Qt.Vertical) self.graphsArea = QScrollArea() # self.graphsLayout = QGridLayout() # self.menubar = self.createMenuBar() self.rowIndex = 0 # self.setSizePolicy( QtGui.QSizePolicy.Expanding # , QtGui.QSizePolicy.Expanding # ) self.graphs.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.setAcceptDrops(True) # self._layout.setSizeConstraint( QLayout.SetNoConstraint ) # self.graphs.setLayout(self.graphsLayout) self.graphsArea.setWidget(self.graphs) self.graphsArea.setWidgetResizable(True) self.graphWidgets = [] # self._layout.addWidget(self.menubar) self._layout.addWidget(self.graphsArea) self.setLayout(self._layout) for graph in self.data.children: self.addPlotWidget(graph=graph) if len(self.data.children) == 0: self.addPlotWidget() def deleteWidget(self, graphWidget): # print("Deleted => ", graphWidget) self.graphWidgets.remove(graphWidget) graphWidget.setParent(None) graphWidget.close() def createMenuBar(self): bar = sidebar.sidebar() bar.addAction( sidebar.add_graph_action(bar, lambda event: self.addPlotWidget())) # bar.addAction(sidebar.delete_graph_action(bar, lambda event: self.addPlotWidget() )) # bar.addAction(sidebar.list_action(bar, self.showPlotView)) return bar def addPlotWidget(self, row=None, col=0, graph=None): if graph == None: graph = moose.Neutral(self.data.path + "/graph_" + str(self.rowIndex)) widget = default.PlotWidget(self.model, graph, self.rowIndex, self) if self.modelType == ELECTRICAL: for axes in widget.canvas.axes.values(): # axes.autoscale(False, axis='x', tight=True) axes.set_ylim(bottom=-0.07, top=0.03) if row == None: row = self.rowIndex self.graphs.addWidget(widget) self.rowIndex += 1 self.graphWidgets.append(widget) widget.widgetClosedSignal.connect(self.deleteWidget) widget.addGraph.connect(lambda event: self.addPlotWidget()) # widget.resize(1, 1); return widget def showPlotView(self): pass def setModelRoot(self, *args): pass def getMenus(self, *args): return [] def setDataRoot(self, *args): pass def updatePlots(self): self.apply(lambda obj: obj.updatePlots()) def rescalePlots(self): self.apply(lambda obj: obj.rescalePlots()) def extendXAxes(self, xlim): self.apply(lambda obj: obj.extendXAxes(xlim)) def plotAllData(self): self.apply(lambda obj: obj.plotAllData()) def apply(self, f): for graphWidget in self.graphWidgets: f(graphWidget)
class DSBrowser(QWidget): """browser for datastorage databases Nodes are identified by a string, containing fields separated by '|'. - first filed is a capital letter: 'R'oot, 'P'roject, sensor'G'roup, 'S'ensor and 'C'hart - second field is the database folder - third filed is the path of the node in the database - for charts the fourth field is the chart name (third is path of sensorgroup in this case) """ def __init__(self): QWidget.__init__(self) self.layout = QVBoxLayout(self) self.layout.setSpacing(0) self.layout.setMargin(0) self.toolBar = QFrame(self) self.toolBarLayout = QHBoxLayout(self.toolBar) self.toolBarLayout.setMargin(2) self.toolBarLayout.setSpacing(2) self.layout.addWidget(self.toolBar) self.loadButton = QToolButton(self.toolBar) self.loadButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open...')) self.loadButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.fileOpen))) self.loadButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Open a datastorage database')) self.toolBarLayout.addWidget(self.loadButton) self.connect(self.loadButton, SIGNAL('pressed()'), self.loadDatabase) self.expandButton = QToolButton(self.toolBar) self.expandButton.setText('Expand/Collapse') self.expandButton.setIcon(QIcon(QPixmap(Icons.exp_col))) self.expandButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Expand or collapse the whole tree')) self.toolBarLayout.addWidget(self.expandButton) self.connect(self.expandButton, SIGNAL('pressed()'), self.expandCollapseAll) self.searchInput = QLineEdit(self.toolBar) self.searchInput.setText(QCoreApplication.translate('DataStorageBrowser', 'Enter search text here')) self.searchInput.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Enter search text using wildcards here, press ENTER again to go to next match!')) self.toolBarLayout.addWidget(self.searchInput, 100) self.connect(self.searchInput, SIGNAL('returnPressed()'), self.searchItem) self.helpButton = QToolButton(self.toolBar) self.helpButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Help')) self.helpButton.setIcon(QIcon(QPixmap(SimuVis4.Icons.help))) self.helpButton.setToolTip(QCoreApplication.translate('DataStorageBrowser', 'Show help for DataStorageBrowser')) self.toolBarLayout.addWidget(self.helpButton) self.connect(self.helpButton, SIGNAL('pressed()'), self.showHelp) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.treeView = QTreeView(self.splitter) self.treeView.setAlternatingRowColors(True) self.treeView.setEditTriggers(QAbstractItemView.NoEditTriggers) self.treeView.setContextMenuPolicy(Qt.CustomContextMenu) self.treeView.setAutoExpandDelay(500) self.textBrowser = QTextBrowser(self.splitter) self.layout.addWidget(self.splitter) self.splitter.setStretchFactor(0, 60) self.splitter.setStretchFactor(1, 40) self.model = DSModel() self.treeView.setModel(self.model) self.treeView.setSortingEnabled(True) self.treeView.expandAll() self.connect(self.treeView.selectionModel(), SIGNAL("currentChanged(QModelIndex, QModelIndex)"), self.showItem) self.connect(self.treeView, SIGNAL("doubleClicked(QModelIndex)"), self.itemAction) self.connect(self.treeView, SIGNAL("customContextMenuRequested(QPoint)"), self.showContextMenu) self.selectedNode = None self.selectedMI = None self.searchText = '' self.searchResults = [] self.collExpand = SimuVis4.Misc.Switcher() def loadDatabase(self, dn=None): """load a database""" if not dn: dn = QFileDialog.getExistingDirectory(self, QCoreApplication.translate('DataStorageBrowser', "Select a folder containing a datastorage database"), SimuVis4.Globals.defaultFolder) if not dn.isEmpty(): dn = unicode(dn) SimuVis4.Globals.defaultFolder = dn else: return self.model.addDatabase(dn) self.treeView.expandToDepth(1) self.treeView.resizeColumnToContents(0) def showHelp(self): SimuVis4.HelpBrowser.showHelp('/plugin/DataStorageBrowser/index.html') def showItem(self, mi, pr): """show the item at model index mi""" t, n = self.model.dsNode(mi) txt = "" if t == 'R': # FIXME: no metadata? txt = rootInfo.substitute(name=n.name, title=escape(n.title), folder=n.h5dir, projects=len(n)) + formatMetaData(n) elif t == 'P': txt = projectInfo.substitute(name=n.name, path=escape(n.parent.name), title=escape(n.title), groups=len(n)) + formatMetaData(n) elif t == 'G': txt = groupInfo.substitute(name=n.name, path='/'.join(n.path.split('/')[:-1]), title=escape(n.title), sensors=len(n), charts=len(n.charts)) + formatMetaData(n) elif t == 'S': txt = sensorInfo.substitute(name=n.name, path='/'.join(n.path.split('/')[:-1]), title=escape(n.title), start=n.timegrid.start, stop=n.timegrid.stop, step=n.timegrid.step, length=n.datalen()) + formatMetaData(n) elif t == 'C': txt = chartInfo.substitute(name=n.name, path=n.sensorgroup.path) self.textBrowser.setText(txt) def searchItem(self): """execute the search and highlight the (next) result""" txt = str(self.searchInput.text()) if txt != self.searchText: self.searchText = txt tmp = self.model.findItems(txt, Qt.MatchFixedString | Qt.MatchContains | Qt.MatchWildcard | Qt.MatchRecursive) self.searchList = [i.index() for i in tmp] if self.searchList: mi = self.searchList.pop() self.treeView.setCurrentIndex(mi) self.treeView.expand(mi) self.treeView.scrollTo(mi) else: QMessageBox.information(self, QCoreApplication.translate('DataStorageBrowser', 'No (more) matches!'), QCoreApplication.translate('DataStorageBrowser', 'No (more) matches found! Change you search criteria and try again!')) self.searchText = '' def expandCollapseAll(self): if self.collExpand(): self.treeView.collapseAll() else: self.treeView.expandAll() def itemAction(self, mi): """default action (on doubleclick) for item at model index mi""" t, n = self.model.dsNode(mi) if t == 'R': pass elif t == 'P': pass elif t == 'G': pass elif t == 'S': self.showQwtPlot(n) elif t == 'C': self.showMplChart(n) def showContextMenu(self, pos): """show context menu for item at pos""" mi = self.treeView.indexAt(pos) t, n = self.model.dsNode(mi) self.selectedNode = n self.selectedMI = mi m = QMenu() if t == 'R': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Close'), self.closeDatabase) elif t == 'P': pass elif t == 'G': nCharts = len(n.charts) if nCharts > 0: txt = str(QCoreApplication.translate('DataStorageBrowser', 'Show all Charts (%d)')) % nCharts m.addAction(txt, self.showAllCharts) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Add Chart'), self.newChart) elif t == 'S': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Plot (Qwt)'), self.showQwtPlot) elif t == 'C': m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Show'), self.showMplChart) m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Delete'), self.deleteItem) if t in 'RPGS': m.addSeparator() m.addAction(QCoreApplication.translate('DataStorageBrowser', 'Edit metadata'), self.editMetadata) a = m.exec_(self.treeView.mapToGlobal(pos)) def showMplChart(self, node=None): if node is None: node = self.selectedNode showChartMplWindow(node, maximized=showChartMaximized) def showAllCharts(self, node=None): if node is None: node = self.selectedNode for chart in node.charts.values(): showChartMplWindow(chart, maximized=showChartMaximized) def showQwtPlot(self, node=None): if node is None: node = self.selectedNode showQwtPlotWindow(node, maximized=showChartMaximized) def editMetadata(self, node=None): if node is None: node = self.selectedNode editMetadata(node) def closeDatabase(self, mi=None): if mi is None: mi = self.selectedMI self.model.closeDatabase(mi) def newChart(self, mi=None): """add a chart to sensorgroup at mi using the wizard""" if mi is None: mi = self.selectedMI showNewChartWizard(self.model, mi) def deleteItem(self, mi=None): """delete the item at mi""" if mi is None: mi = self.selectedMI self.model.deleteItem(mi)
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 Ui_dev_client(object): def setupUi(self, dev_client): dev_client.resize(935, 660) dev_client.setWindowTitle(QApplication.translate("dev_client", "DevClient")) self.centralwidget = QWidget(dev_client) dev_client.setCentralWidget(self.centralwidget) main_layout = QGridLayout(self.centralwidget) main_layout.setContentsMargins(5, 5, 5, 3) main_layout.setSpacing(3) main_layout.setColumnStretch(0, 1) main_layout.setRowStretch(1, 1) top_layout = QHBoxLayout() top_layout.setContentsMargins(0, 0, 0, 0) top_layout.setSpacing(5) top_label_conn = QLabel() top_label_conn.setText(QApplication.translate("dev_client", "Connection")) top_layout.addWidget(top_label_conn) self.list_conn = QComboBox() self.list_conn.setFixedSize(145, 26) self.list_conn.setFocusPolicy(Qt.NoFocus) top_layout.addWidget(self.list_conn) self.list_account = QComboBox() self.list_account.setFixedSize(145, 26) self.list_account.setFocusPolicy(Qt.NoFocus) top_layout.addWidget(self.list_account) top_layout.addItem(QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) top_label_account = QLabel() top_label_account.setText(QApplication.translate("dev_client", "Account")) top_layout.addWidget(top_label_account) self.button_connect = QPushButton() self.button_connect.setFixedSize(105, 26) self.button_connect.setFocusPolicy(Qt.NoFocus) self.button_connect.setIcon(QIcon(":/images/connect.png")) self.button_connect.setIconSize(QSize(16, 16)) self.button_connect.setText(QApplication.translate("dev_client", "Connect")) top_layout.addWidget(self.button_connect) self.button_option = QPushButton() self.button_option.setFixedSize(105, 26) self.button_option.setFocusPolicy(Qt.NoFocus) self.button_option.setIcon(QIcon(":/images/option.png")) self.button_option.setIconSize(QSize(16, 16)) self.button_option.setText(QApplication.translate("dev_client", "Option")) top_layout.addWidget(self.button_option) main_layout.addLayout(top_layout, 0, 0) right_layout = QVBoxLayout() right_layout.setContentsMargins(0, 0, 0, 0) right_layout.addItem(QSpacerItem(40, 29, QSizePolicy.Minimum, QSizePolicy.Fixed)) self.rightpanel = QWidget() self.rightpanel.setMinimumWidth(225) right_layout.addWidget(self.rightpanel) main_layout.addLayout(right_layout, 0, 1, 3, 1) self.output_splitter = QSplitter(self.centralwidget) self.output_splitter.setOrientation(Qt.Vertical) self.output_splitter.setHandleWidth(3) self.output_splitter.setChildrenCollapsible(False) self.text_output = QTextEdit(self.output_splitter) self.text_output.setMinimumWidth(690) self.text_output.setFocusPolicy(Qt.NoFocus) self.text_output.setAutoFillBackground(True) self.text_output.setUndoRedoEnabled(False) self.text_output.setReadOnly(True) self.text_output_noscroll = QTextEdit(self.output_splitter) self.text_output_noscroll.setMinimumWidth(690) self.text_output_noscroll.setFocusPolicy(Qt.NoFocus) self.text_output_noscroll.setAutoFillBackground(True) self.text_output_noscroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_output_noscroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.text_output_noscroll.setUndoRedoEnabled(False) self.text_output_noscroll.setReadOnly(True) main_layout.addWidget(self.output_splitter, 1, 0) bottom_layout = QHBoxLayout() bottom_layout.setContentsMargins(0, 0, 0, 0) bottom_layout.setSpacing(5) self.text_input = QComboBox() self.text_input.setMinimumWidth(660) self.text_input.setFixedHeight(25) self.text_input.setEditable(True) self.text_input.addItem("") bottom_layout.addWidget(self.text_input) self.toggle_splitter = QPushButton() self.toggle_splitter.setFixedSize(25, 25) self.toggle_splitter.setFocusPolicy(Qt.NoFocus) self.toggle_splitter.setIcon(QIcon(":/images/split-window.png")) bottom_layout.addWidget(self.toggle_splitter) main_layout.addLayout(bottom_layout, 2, 0)