def initUI(self, engine): splitter = QSplitter(Qt.Horizontal) # make the right panel right_panel = QSplitter(Qt.Vertical) player = Player() track_queue = QListWidget() ## set play on double click def play_track(): player.set_track(track_queue.currentItem().get_track()) player.play() track_queue.doubleClicked.connect(play_track) ## advance list on track finish def track_finish_task(): print 'track finished' if track_queue.currentRow() == track_queue.count() - 1: track_queue.setCurrentRow(0) else: track_queue.setCurrentRow(track_queue.currentRow() + 1) play_track() player.track_finished.connect(track_finish_task) ## put some entry controls on menu track_queue.setContextMenuPolicy(Qt.CustomContextMenu) def onContext(point): ## make action qaction = QAction('Delete item', track_queue) def remove_entry(): track_queue.takeItem(track_queue.currentRow()) qaction.triggered.connect(remove_entry) # Create a menu menu = QMenu("Menu", track_queue) menu.addAction(qaction) # Show the context menu. menu.exec_(track_queue.mapToGlobal(point)) track_queue.connect(track_queue, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), onContext) utils.add_widgets_to_component(right_panel, [player, track_queue]) ## make the left panel left_panel = QWidget() vbox = QVBoxLayout() utils.add_widgets_to_component(vbox, [PlaylistsPanel(engine, [player], [track_queue]), SearchPanel(engine, [player], [track_queue])]) left_panel.setLayout(vbox) utils.add_widgets_to_component(splitter, [left_panel, right_panel]) splitter.setSizes([1, 10]) bottomBar = self.make_bottom_bar() # Application UI layout vBox = QVBoxLayout(self) vBox.addWidget(splitter) vBox.addWidget(bottomBar) self.setLayout(vBox)
def __init__(self, client, messageQueue, isLightTheme): QMainWindow.__init__(self) self.client = client self.messageQueue = messageQueue self.isLightTheme = isLightTheme self.__setMenubar() self.chatLog = QTextEdit() self.chatLog.setReadOnly(True) self.chatInput = QTextEdit() self.chatInput.textChanged.connect(self.chatInputTextChanged) self.sendButton = QPushButton("Send") self.sendButton.clicked.connect(self.sendMessage) # Set the min height for the chatlog and a matching fixed height for the send button chatInputFontMetrics = QFontMetrics(self.chatInput.font()) self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3) self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3) hboxLayout = QHBoxLayout() hboxLayout.addWidget(self.chatInput) hboxLayout.addWidget(self.sendButton) # Put the chatinput and send button in a wrapper widget so they may be added to the splitter chatInputWrapper = QWidget() chatInputWrapper.setLayout(hboxLayout) chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7) # Put the chat log and chat input into a splitter so the user can resize them at will splitter = QSplitter(Qt.Vertical) splitter.addWidget(self.chatLog) splitter.addWidget(chatInputWrapper) splitter.setSizes([int(self.height()), 1]) vboxLayout = QVBoxLayout() vboxLayout.addWidget(splitter) # Add the completeted layout to the window self.centralWidget = QWidget() self.centralWidget.setLayout(vboxLayout) self.setCentralWidget(self.centralWidget) qtUtils.resizeWindow(self, 700, 400) qtUtils.centerWindow(self) # Title and icon self.setWindowTitle("Cryptully") self.setWindowIcon(QIcon(utils.getAbsoluteResourcePath('images/' + ('light' if isLightTheme else 'dark') + '/icon.png'))) self.statusBar().showMessage("Not Connected")
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()
def __init__(self, connectionManager, parent=None): QWidget.__init__(self, parent) self.connectionManager = connectionManager self.isDisabled = False self.wasCleared = False self.urlRegex = re.compile(constants.URL_REGEX) self.chatLog = QTextBrowser() self.chatLog.setOpenExternalLinks(True) self.chatInput = QTextEdit() self.chatInput.textChanged.connect(self.chatInputTextChanged) self.sendButton = QPushButton("Send") self.sendButton.clicked.connect(self.sendMessage) # Set the min height for the chatlog and a matching fixed height for the send button chatInputFontMetrics = QFontMetrics(self.chatInput.font()) self.chatInput.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3) self.sendButton.setFixedHeight(chatInputFontMetrics.lineSpacing() * 3) hbox = QHBoxLayout() hbox.addWidget(self.chatInput) hbox.addWidget(self.sendButton) # Put the chatinput and send button in a wrapper widget so they may be added to the splitter chatInputWrapper = QWidget() chatInputWrapper.setLayout(hbox) chatInputWrapper.setMinimumHeight(chatInputFontMetrics.lineSpacing() * 3.7) # Put the chat log and chat input into a splitter so the user can resize them at will splitter = QSplitter(Qt.Vertical) splitter.addWidget(self.chatLog) splitter.addWidget(chatInputWrapper) splitter.setSizes([int(parent.height()), 1]) hbox = QHBoxLayout() hbox.addWidget(splitter) self.setLayout(hbox) self.typingTimer = QTimer() self.typingTimer.setSingleShot(True) self.typingTimer.timeout.connect(self.stoppedTyping)
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())
def __init__(self, panel): super(Widget, self).__init__(panel) layout = QVBoxLayout() self.setLayout(layout) layout.setSpacing(0) self.searchEntry = SearchLineEdit() self.treeView = QTreeView(contextMenuPolicy=Qt.CustomContextMenu) self.textView = QTextBrowser() applyButton = QToolButton(autoRaise=True) editButton = QToolButton(autoRaise=True) addButton = QToolButton(autoRaise=True) self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) splitter = QSplitter(Qt.Vertical) top = QHBoxLayout() layout.addLayout(top) splitter.addWidget(self.treeView) splitter.addWidget(self.textView) layout.addWidget(splitter) splitter.setSizes([200, 100]) splitter.setCollapsible(0, False) top.addWidget(self.searchEntry) top.addWidget(applyButton) top.addSpacing(10) top.addWidget(addButton) top.addWidget(editButton) top.addWidget(self.menuButton) # action generator for actions added to search entry def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) a.setShortcutContext(Qt.WidgetWithChildrenShortcut) icon and a.setIcon(icons.get(icon)) return a # hide if ESC pressed in lineedit a = act(self.slotEscapePressed) a.setShortcut(QKeySequence(Qt.Key_Escape)) # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) # apply button a = self.applyAction = act(self.slotApply, 'edit-paste') applyButton.setDefaultAction(a) menu.addSeparator() menu.addAction(a) # add button a = self.addAction_ = act(self.slotAdd, 'list-add') a.setShortcut(QKeySequence(Qt.Key_Insert)) addButton.setDefaultAction(a) menu.addSeparator() menu.addAction(a) # edit button a = self.editAction = act(self.slotEdit, 'document-edit') a.setShortcut(QKeySequence(Qt.Key_F2)) editButton.setDefaultAction(a) menu.addAction(a) # set shortcut action a = self.shortcutAction = act(self.slotShortcut, 'preferences-desktop-keyboard-shortcuts') menu.addAction(a) # delete action a = self.deleteAction = act(self.slotDelete, 'list-remove') a.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Delete)) menu.addAction(a) # restore action a = self.restoreAction = act(self.slotRestore) menu.addSeparator() menu.addAction(a) # help button a = self.helpAction = act(self.slotHelp, 'help-contents') menu.addSeparator() menu.addAction(a) self.treeView.setSelectionBehavior(QTreeView.SelectRows) self.treeView.setSelectionMode(QTreeView.ExtendedSelection) self.treeView.setRootIsDecorated(False) self.treeView.setAllColumnsShowFocus(True) self.treeView.setModel(model.model()) self.treeView.setCurrentIndex(QModelIndex()) # signals self.searchEntry.returnPressed.connect(self.slotReturnPressed) self.searchEntry.textChanged.connect(self.updateFilter) self.treeView.doubleClicked.connect(self.slotDoubleClicked) self.treeView.customContextMenuRequested.connect(self.showContextMenu) self.treeView.selectionModel().currentChanged.connect(self.updateText) self.treeView.model().dataChanged.connect(self.updateFilter) # highlight text self.highlighter = highlight.Highlighter(self.textView.document()) # complete on snippet variables self.searchEntry.setCompleter(QCompleter([ ':icon', ':indent', ':menu', ':name', ':python', ':selection', ':set', ':symbol', ':template', ':template-run'], self.searchEntry)) self.readSettings() app.settingsChanged.connect(self.readSettings) app.translateUI(self) self.updateColumnSizes() self.setAcceptDrops(True)
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 OWPythonScript(widget.OWWidget): name = "Python Script" description = "Executes a Python script." icon = "icons/PythonScript.svg" priority = 3150 inputs = [ ("in_data", Orange.data.Table, "setExampleTable", widget.Default), # ("in_distance", Orange.misc.SymMatrix, "setDistanceMatrix", # widget.Default), ("in_learner", Orange.classification.Fitter, "setLearner", widget.Default), ("in_classifier", Orange.classification.Model, "setClassifier", widget.Default), ("in_object", object, "setObject") ] outputs = [ ( "out_data", Orange.data.Table, ), # ("out_distance", Orange.misc.SymMatrix, ), ( "out_learner", Orange.classification.Fitter, ), ("out_classifier", Orange.classification.Model, widget.Dynamic), ("out_object", object, widget.Dynamic) ] libraryListSource = \ Setting([Script("Hello world", "print('Hello world')\n")]) currentScriptIndex = Setting(0) splitterState = Setting(None) auto_execute = Setting(False) def __init__(self): super().__init__() self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = gui.widgetBox(self.controlArea, 'Info') gui.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t.name for t in self.inputs) + \ "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t.name for t in self.outputs) + \ "</ul></p>" ) self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = gui.widgetBox(self.controlArea, 'Run') gui.button(self.runBox, self, "Execute", callback=self.execute) gui.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip="Run the script automatically whenever " + "the inputs to the widget change.") self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): if self.auto_execute: self.execute() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)') filename = str(filename) if filename: name = os.path.basename(filename) contents = open(filename, "rb").read().decode("utf-8", errors="ignore") self.libraryList.append(Script(name, contents, 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QtGui.QTextDocument(self) doc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitCanvas.saveState()) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def saveScript(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] filename = script.filename else: filename = os.path.expanduser("~/") filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)') if filename: fn = "" head, tail = os.path.splitext(filename) if not tail: fn = head + ".py" else: fn = filename f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def execute(self): self._script = str(self.text.toPlainText()) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for out in self.outputs: signal = out.name self.send(signal, getattr(self, signal, None))
class OWPySparkScript(SharedSparkContext, widget.OWWidget): priority = 3 name = "PySpark Script" description = "Write a PySpark script and run it on input" icon = "../icons/PythonScript.svg" inputs = [("in_object", object, "setObject")] outputs = [("out_object", object, widget.Dynamic)] libraryListSource = \ Setting([Script("Hello world", "print('Hello world')\n")]) currentScriptIndex = Setting(0) splitterState = Setting(None) auto_execute = Setting(False) def __init__(self): super().__init__() self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = { } self.infoBox = gui.widgetBox(self.controlArea, 'Info') gui.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t.name for t in self.inputs) + \ "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t.name for t in self.outputs) + \ "</ul></p>" ) self.libraryList = itemmodels.PyListModel( [], self, flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers = QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) ) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged ) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip = "More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) gui.auto_commit(self.controlArea, self, "auto_execute", "Execute") self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.__dict__['sc'] = self._sc self.__dict__['hc'] = self._hc self.console = PySparkConsole(self.__dict__, self, sc = self.sc) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): self.unconditional_commit() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)' ) filename = str(filename) if filename: name = os.path.basename(filename) contents = open(filename, "rb").read().decode("utf-8", errors = "ignore") self.libraryList.append(Script(name, contents, 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script = 0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QtGui.QTextDocument(self) doc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitCanvas.saveState()) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def saveScript(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] filename = script.filename else: filename = os.path.expanduser("~/") filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)' ) if filename: fn = "" head, tail = os.path.splitext(filename) if not tail: fn = head + ".py" else: fn = filename f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def commit(self): self._script = str(self.text.toPlainText()) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for out in self.outputs: signal = out.name self.send(signal, getattr(self, signal, None))
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 __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 OWPySparkScript(SharedSparkContext, widget.OWWidget): priority = 3 name = "PySpark Script" description = "Write a PySpark script and run it on input" icon = "../icons/PythonScript.svg" inputs = [("in_object", object, "setObject")] outputs = [("out_object", object, widget.Dynamic)] in_object = None out_object = None auto_execute = Setting(False) libraryListSource = \ Setting([Script("Hello world", "print('Hello world')\n")]) currentScriptIndex = Setting(0) splitterState = Setting(None) auto_execute = Setting(False) _script = Setting("") def __init__(self): super().__init__() self.spark_logo = """ ____ __ / __/__ ___ _____/ /__ _\ \/ _ \/ _ `/ __/ '_/ /__ / .__/\_,_/_/ /_/\_\ version {version} /_/ """.format(version=self.sc.version) for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = gui.widgetBox(self.controlArea, 'Info') gui.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t.name for t in self.inputs) + \ "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t.name for t in self.outputs) + \ "</ul></p>" ) self.libraryList = itemmodels.PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred)) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) gui.auto_commit(self.controlArea, self, "auto_execute", "Execute") self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = gui.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) # self.console = PySparkConsole(self.__dict__, self, sc = self.sc) self.console = EmbedIPython(sc=self._sc, hc=self._hc, in_object=self.in_object, out_object=self.out_object) # self.console.kernel.shell.run_cell('%pylab qt') self.console.kernel.shell.run_cell( "print('{sparklogo}')".format(sparklogo=self.spark_logo)) self.consoleBox.layout().addWidget(self.console) self.consoleBox.setAlignment(Qt.AlignBottom) select_row(self.libraryView, self.currentScriptIndex) self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setObject(self, obj): self.in_object = obj def handleNewSignals(self): self.unconditional_commit() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)') filename = str(filename) if filename: name = os.path.basename(filename) contents = open(filename, "rb").read().decode("utf-8", errors="ignore") self.libraryList.append(Script(name, contents, 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QtGui.QTextDocument(self) doc.setDocumentLayout(QtGui.QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitCanvas.saveState()) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def saveScript(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] filename = script.filename else: filename = os.path.expanduser("~/") filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)') if filename: fn = "" head, tail = os.path.splitext(filename) if not tail: fn = head + ".py" else: fn = filename f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def commit(self): self._script = str(self.text.toPlainText()) self.console.execute(self._script) self.send("out_object", self.out_object)
class OWPythonScript(OWWidget): settingsList = ["libraryListSource", "currentScriptIndex", "splitterState", "auto_execute"] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject)] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.libraryListSource = [Script("Hello world", "print 'Hello world'\n")] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + "<li>".join(t[0] for t in self.inputs) + "</ul></p><p>Output variables:<ul><li>" + "<li>".join(t[0] for t in self.outputs) + "</ul></p>" ) self.libraryList = PyListModel( [], self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable ) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView( editTriggers=QListView.DoubleClicked | QListView.EditKeyPressed, sizePolicy=QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) ) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged ) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self, toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitter = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitter) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitter.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitter.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.splitter.setSizes([2, 1]) if self.splitterState is not None: self.splitter.restoreState(QByteArray(self.splitterState)) self.splitter.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): if self.auto_execute: self.execute() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', os.path.expanduser("~/"), 'Python files (*.py)\nAll files(*.*)' ) filename = unicode(filename) if filename: name = os.path.basename(filename) self.libraryList.append(Script(name, open(filename, "rb").read(), 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = unicode(self.text.toPlainText()) self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitter.saveState()) def saveScript(self): index = self.selectedScriptIndex() filename = os.path.expanduser("~/") if index is not None: script = self.libraryList[index] filename = script.sourceFileName or filename filename = QFileDialog.getSaveFileName( self, 'Save Python Script', filename, 'Python files (*.py)\nAll files(*.*)' ) self.codeFile = unicode(filename) if self.codeFile: fn = "" head, tail = os.path.splitext(self.codeFile) if not tail: fn = head + ".py" else: fn = self.codeFile f = open(fn, 'w') f.write(self.text.toPlainText()) f.close() def execute(self): self._script = str(self.text.toPlainText()) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for out in self.outputs: signal = out[0] self.send(signal, getattr(self, signal, None))
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 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 QuadView(QWidget): def __init__(self, parent, view1, view2, view3, view4 = None): QWidget.__init__(self, parent) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.installEventFilter(self) self.dockableContainer = [] self.layout = QVBoxLayout() self.setLayout(self.layout) self.layout.setContentsMargins(4, 4, 4, 4) self.layout.setSpacing(0) self.splitVertical = QSplitter(Qt.Vertical, self) self.layout.addWidget(self.splitVertical) self.splitHorizontal1 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal1.setObjectName("splitter1") self.splitHorizontal2 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal2.setObjectName("splitter2") self.splitHorizontal1.splitterMoved.connect(self.horizontalSplitterMoved) self.splitHorizontal2.splitterMoved.connect(self.horizontalSplitterMoved) self.imageView2D_1 = view1 self.imageView2D_2 = view2 self.imageView2D_3 = view3 self.testView4 = ImageView2DDockWidget(view4) self.dock1_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_1) self.dock1_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal1) self.dock1_ofSplitHorizontal1.onDockButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_dock(arg)) self.dock1_ofSplitHorizontal1.onMaxButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_max(arg)) self.dock1_ofSplitHorizontal1.onMinButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_min(arg)) self.splitHorizontal1.addWidget(self.dock1_ofSplitHorizontal1) self.dock2_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_2) self.dock2_ofSplitHorizontal1.onDockButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_dock(arg)) self.dock2_ofSplitHorizontal1.onMaxButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_max(arg)) self.dock2_ofSplitHorizontal1.onMinButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_min(arg)) self.dock2_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock2_ofSplitHorizontal1) self.splitHorizontal1.addWidget(self.dock2_ofSplitHorizontal1) self.dock1_ofSplitHorizontal2 = ImageView2DDockWidget(self.imageView2D_3) self.dock1_ofSplitHorizontal2.onDockButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_dock(arg)) self.dock1_ofSplitHorizontal2.onMaxButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_max(arg)) self.dock1_ofSplitHorizontal2.onMinButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_min(arg)) self.dock1_ofSplitHorizontal2.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock1_ofSplitHorizontal2) self.dock2_ofSplitHorizontal2 = ImageView2DDockWidget(self.testView4) self.dockableContainer.append(self.dock2_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock2_ofSplitHorizontal2) #this is a hack: with 0 ms it does not work... QTimer.singleShot(250, self._resizeEqual) def _resizeEqual(self): w, h = self.size().width()-self.splitHorizontal1.handleWidth(), self.size().height()-self.splitVertical.handleWidth() docks = [self.imageView2D_1, self.imageView2D_2, self.imageView2D_3, self.testView4] w1 = [docks[i].minimumSize().width() for i in [0,2] ] w2 = [docks[i].minimumSize().width() for i in [1,3] ] wLeft = max(w1) wRight = max(w2) if wLeft > wRight and wLeft > w/2: wRight = w - wLeft elif wRight >= wLeft and wRight > w/2: wLeft = w - wRight else: wLeft = w/2 wRight = w/2 self.splitHorizontal1.setSizes([wLeft, wRight]) self.splitHorizontal2.setSizes([wLeft, wRight]) self.splitVertical.setSizes([h/2, h/2]) def eventFilter(self, obj, event): if(event.type()==QEvent.WindowActivate): self._synchronizeSplitter() return False def _synchronizeSplitter(self): sizes1 = self.splitHorizontal1.sizes() sizes2 = self.splitHorizontal2.sizes() if sizes1[0] > sizes2[0]: self.splitHorizontal1.setSizes(sizes2) else: self.splitHorizontal2.setSizes(sizes1) def resizeEvent(self, event): QWidget.resizeEvent(self, event) self._synchronizeSplitter() def horizontalSplitterMoved(self, x, y): sizes = self.splitHorizontal1.sizes() #What. Nr2 if self.splitHorizontal2.closestLegalPosition(x, y) < self.splitHorizontal2.closestLegalPosition(x, y): sizeLeft = self.splitHorizontal1.closestLegalPosition(x, y) else: sizeLeft = self.splitHorizontal2.closestLegalPosition(x, y) sizeRight = sizes[0] + sizes[1] - sizeLeft sizes = [sizeLeft, sizeRight] self.splitHorizontal1.setSizes(sizes) self.splitHorizontal2.setSizes(sizes) def addStatusBar(self, bar): self.statusBar = bar self.layout.addLayout(self.statusBar) def setGrayScaleToQuadStatusBar(self, gray): self.quadViewStatusBar.setGrayScale(gray) def setMouseCoordsToQuadStatusBar(self, x, y, z): self.quadViewStatusBar.setMouseCoords(x, y, z) def on_dock(self, dockWidget): if dockWidget._isDocked: dockWidget.undockView() self.on_min(dockWidget) dockWidget.minimizeView() else: dockWidget.dockView() def on_max(self, dockWidget): for dock in self.dockableContainer: if not dockWidget == dock: dock.setVisible(False) def on_min(self, dockWidget): for dock in self.dockableContainer: if not dockWidget == dock: dock.setVisible(True)
class QuadView(QWidget): def __init__(self, parent, view1, view2, view3, view4 = None): QWidget.__init__(self, parent) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.installEventFilter(self) self.dockableContainer = [] self.layout = QVBoxLayout() self.setLayout(self.layout) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.splitVertical = QSplitter(Qt.Vertical, self) self.layout.addWidget(self.splitVertical) self.splitHorizontal1 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal1.setObjectName("splitter1") self.splitHorizontal2 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal2.setObjectName("splitter2") self.splitHorizontal1.splitterMoved.connect(self.horizontalSplitterMoved) self.splitHorizontal2.splitterMoved.connect(self.horizontalSplitterMoved) self.imageView2D_1 = view1 self.imageView2D_2 = view2 self.imageView2D_3 = view3 self.dock1_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_1) self.dock1_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal1) self.dock1_ofSplitHorizontal1.onDockButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_dock(arg)) self.dock1_ofSplitHorizontal1.onMaxButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_max(arg)) self.dock1_ofSplitHorizontal1.onMinButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal1 : self.on_min(arg)) self.splitHorizontal1.addWidget(self.dock1_ofSplitHorizontal1) self.dock2_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_2) self.dock2_ofSplitHorizontal1.onDockButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_dock(arg)) self.dock2_ofSplitHorizontal1.onMaxButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_max(arg)) self.dock2_ofSplitHorizontal1.onMinButtonClicked.connect(lambda arg=self.dock2_ofSplitHorizontal1 : self.on_min(arg)) self.dock2_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock2_ofSplitHorizontal1) self.splitHorizontal1.addWidget(self.dock2_ofSplitHorizontal1) self.dock1_ofSplitHorizontal2 = ImageView2DDockWidget(self.imageView2D_3) self.dock1_ofSplitHorizontal2.onDockButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_dock(arg)) self.dock1_ofSplitHorizontal2.onMaxButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_max(arg)) self.dock1_ofSplitHorizontal2.onMinButtonClicked.connect(lambda arg=self.dock1_ofSplitHorizontal2 : self.on_min(arg)) self.dock1_ofSplitHorizontal2.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock1_ofSplitHorizontal2) self.dock2_ofSplitHorizontal2 = ImageView2DDockWidget(view4) self.dockableContainer.append(self.dock2_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock2_ofSplitHorizontal2) #this is a hack: with 0 ms it does not work... QTimer.singleShot(250, self._resizeEqual) def _resizeEqual(self): if not all( [dock.isVisible() for dock in self.dockableContainer] ): return w, h = self.size().width()-self.splitHorizontal1.handleWidth(), self.size().height()-self.splitVertical.handleWidth() self.splitVertical.setSizes([h/2, h/2]) if self.splitHorizontal1.count() == 2 and self.splitHorizontal2.count() == 2: #docks = [self.imageView2D_1, self.imageView2D_2, self.imageView2D_3, self.testView4] docks = [] for splitter in [self.splitHorizontal1, self.splitHorizontal2]: for i in range( splitter.count() ): docks.append( splitter.widget(i).graphicsView ) w1 = [docks[i].minimumSize().width() for i in [0,2] ] w2 = [docks[i].minimumSize().width() for i in [1,3] ] wLeft = max(w1) wRight = max(w2) if wLeft > wRight and wLeft > w/2: wRight = w - wLeft elif wRight >= wLeft and wRight > w/2: wLeft = w - wRight else: wLeft = w/2 wRight = w/2 self.splitHorizontal1.setSizes([wLeft, wRight]) self.splitHorizontal2.setSizes([wLeft, wRight]) def eventFilter(self, obj, event): if(event.type() in [QEvent.WindowActivate, QEvent.Show]): self._synchronizeSplitter() return False def _synchronizeSplitter(self): sizes1 = self.splitHorizontal1.sizes() sizes2 = self.splitHorizontal2.sizes() if len(sizes1) > 0 and sizes1[0] > 0: self.splitHorizontal2.setSizes(sizes1) elif len(sizes2) > 0 and sizes2[0] > 0: self.splitHorizontal1.setSizes(sizes2) def resizeEvent(self, event): QWidget.resizeEvent(self, event) self._synchronizeSplitter() def horizontalSplitterMoved(self, x, y): if self.splitHorizontal1.count() != 2 or self.splitHorizontal2.count() != 2: return sizes = self.splitHorizontal1.sizes() #What. Nr2 if self.splitHorizontal2.closestLegalPosition(x, y) < self.splitHorizontal2.closestLegalPosition(x, y): sizeLeft = self.splitHorizontal1.closestLegalPosition(x, y) else: sizeLeft = self.splitHorizontal2.closestLegalPosition(x, y) sizeRight = sizes[0] + sizes[1] - sizeLeft sizes = [sizeLeft, sizeRight] self.splitHorizontal1.setSizes(sizes) self.splitHorizontal2.setSizes(sizes) def addStatusBar(self, bar): self.statusBar = bar self.layout.addLayout(self.statusBar) def setGrayScaleToQuadStatusBar(self, gray): self.quadViewStatusBar.setGrayScale(gray) def setMouseCoordsToQuadStatusBar(self, x, y, z): self.quadViewStatusBar.setMouseCoords(x, y, z) def ensureMaximized(self, axis): """ Maximize the view for the given axis if it isn't already maximized. """ axisDict = { 0 : self.dock2_ofSplitHorizontal1, # x 1 : self.dock1_ofSplitHorizontal2, # y 2 : self.dock1_ofSplitHorizontal1 } # z if not axisDict[axis]._isMaximized: self.switchMinMax(axis) def switchMinMax(self,axis): """Switch an AxisViewWidget between from minimized to maximized and vice versa. Keyword arguments: axis -- the axis which is represented by the widget (no default) either string or integer 'x' - 0 'y' - 1 'z' - 2 """ #TODO: get the mapping information from where it is set! if this is not #done properly - do it properly if type(axis) == str: axisDict = { 'x' : self.dock2_ofSplitHorizontal1, # x 'y' : self.dock1_ofSplitHorizontal2, # y 'z' : self.dock1_ofSplitHorizontal1 } # z elif type(axis) == int: axisDict = { 0 : self.dock2_ofSplitHorizontal1, # x 1 : self.dock1_ofSplitHorizontal2, # y 2 : self.dock1_ofSplitHorizontal1 } # z dockWidget = axisDict.pop(axis) for dWidget in axisDict.values(): if dWidget._isMaximized: dWidget.graphicsView._hud.maximizeButtonClicked.emit() dockWidget.graphicsView._hud.maximizeButtonClicked.emit() def switchXMinMax(self): self.switchMinMax('x') def switchYMinMax(self): self.switchMinMax('y') def switchZMinMax(self): self.switchMinMax('z') def on_dock(self, dockWidget): if dockWidget._isDocked: dockWidget.undockView() self.on_min(dockWidget) dockWidget.minimizeView() else: dockWidget.dockView() def on_max(self, dockWidget): dockWidget.setVisible(True) for dock in self.dockableContainer: if not dockWidget == dock: dock.setVisible(False) # Force sizes to be updated now QApplication.processEvents() # On linux, the vertical splitter doesn't seem to refresh unless we do so manually # Presumably, this is a QT bug. self.splitVertical.refresh() # Viewport doesn't update automatically... view = dockWidget.graphicsView view.viewport().setGeometry( view.rect() ) def on_min(self, dockWidget): for dock in self.dockableContainer: dock.setVisible(True) # Force sizes to be updated now QApplication.processEvents() self._resizeEqual() # Viewports don't update automatically... for dock in self.dockableContainer: view = dock.graphicsView if hasattr(view, 'viewport'): view.viewport().setGeometry( view.rect() )
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 RestEditor(WithSingleIO, QWidget): """Restructredtext editor """ def __init__(self, params, parent=None): QWidget.__init__(self, parent) self.setMinimumWidth(300) self.setMinimumHeight(300) # create widgets self._editor_widget = mixin( WithFind, WithMqEditIO, WithBasicIdentationManager, WithLineHighlight, WithFixedFont, WithLineNumbers, WithViewPortMargins, WithWordCompletionMulty_, WithCompletion, QPlainTextEdit)(self) self.webview = QWebView(self) #self.webview.load(QUrl("/home/maiquel/develop/developing/main/qt/qadoc/bin/__builds/documents.html")) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self._editor_widget) self.splitter.addWidget(self.webview) self.splitter.setSizes([self.size().width(), self.size().width()]) self.splitterv = QSplitter(Qt.Vertical) self.splitterv.addWidget(self.splitter) self.log_widget = QPlainTextEdit() self.splitterv.addWidget(self.log_widget) layout = QVBoxLayout(self) layout.addWidget(self.splitterv) layout.setMargin(0) self.setLayout(layout) # proc_compile self.proc_compile = QProcess() self.proc_compile.finished.connect(self.proc_compile_finished) self.proc_compile.error.connect(self.proc_compile_error) self.proc_compile.readyReadStandardOutput.connect(self.proc_compile_readyReadStandardOutput) self.proc_compile.readyReadStandardError.connect(self.proc_compile_readyReadStandardError) WithSingleIO.__init__(self, params) def bw_add_command_list(self, command_list): command_list += [ ("generate preview restructuretext", "pp", 1.0, "self.get_current_widget().command_generate_preview('rst2html')"), ] super(RestEditor, self).bw_add_command_list(command_list) self._editor_widget.bw_add_command_list(command_list) command_list += [ ("focus editor", "fe", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self._editor_widget.setFocus();"), ("focus preview", "fp", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setFocus();"), ] def command_generate_preview(self, backend): self.command_save_file() if not os.path.exists(TEMP_DIR): os.mkdir(TEMP_DIR) temp_source_file = open(TEMP_DIR + 'pr.rst','wt') temp_source_file.write(self._editor_widget.toPlainText()) temp_source_file.close() self.compile(backend + " --stylesheet=./widgets/rst2html.style " + TEMP_DIR + "pr.rst" + " " + self.get_html_output()) if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def compile(self, command): self.log(command) self.proc_compile.start(command) def bw_lock_command_window(self): return self._editor_widget.completer.popup().isVisible() def focusInEvent(self, focus_event): super(RestEditor, self).focusInEvent(focus_event) self._editor_widget.setFocus() def get_html_output(self): return TEMP_DIR + "pr.html" def proc_compile_finished(self, result, exit_status): self.log("compilation finished") if self.webview.url().toString() == "": self.webview.load(QUrl(self.get_html_output())) else: self.webview.reload() def proc_compile_error(self, q_process_error): self.log("compilation error") print(q_process_error) def proc_compile_readyReadStandardOutput(self): result = self.proc_compile.readAllStandardOutput(); self.log(result) def proc_compile_readyReadStandardError(self): result = str(self.proc_compile.readAllStandardError()) self.log(result) def log(self, text): self.log_widget.appendPlainText(text)
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 ConfigEditorTab(BrowserTab): """ This is the main frame of the Config Editor Plugin. The tab is split in three horizontal parts, from left to right: Tree View, Center View, Property View. The editor can be dispayed using createEditor(). The Property View is then shared with the ConfigBrowser. """ def __init__(self, parent=None): """ constructor """ logging.debug(self.__class__.__name__ + ": __init__()") BrowserTab.__init__(self, parent, True) self._editorSplitter = None def createEditor(self): self.createToolBar(0) self._editorSplitter = QSplitter(Qt.Horizontal) toolBarSectionId = self.toolBar().addSection( SplitterToolBar.ALIGNMENT_LEFT) self._editorTableView = CodeTableView(self._editorSplitter) self._editorSplitter.setSizes([100, 300]) self._minimizeButton = QToolButton() self._minimizeButton.setText("v") self._minimizeButton.setCheckable(True) self._originalButton = QToolButton() self._originalButton.setText("-") self._originalButton.setCheckable(True) self._originalButton.setChecked(True) self._maximizeButton = QToolButton() self._maximizeButton.setText("^") self._maximizeButton.setCheckable(True) self._centerViewToolBarId = self.toolBar().addSection( SplitterToolBar.ALIGNMENT_CENTER) self.toolBar().addWidgetToSection(self._minimizeButton, self._centerViewToolBarId) self.toolBar().addWidgetToSection(self._originalButton, self._centerViewToolBarId) self.toolBar().addWidgetToSection(self._maximizeButton, self._centerViewToolBarId) self.verticalSplitter().insertWidget(0, self._editorSplitter) self.updateToolBarSizes() controller = self.controller() if controller: self.connect(self._minimizeButton, SIGNAL('clicked(bool)'), controller.minimizeEditor) self.connect(self._originalButton, SIGNAL('clicked(bool)'), controller.originalEditor) self.connect(self._maximizeButton, SIGNAL('clicked(bool)'), controller.maximizeEditor) def editorSplitter(self): return self._editorSplitter def horizontalSplitterMovedSlot(self, pos, index): if self.toolBar(): self.updateToolBarSizes() def updateToolBarSizes(self): self.toolBar().setSectionSizes(self.horizontalSplitter().sizes()) def minimizeButton(self): return self._minimizeButton def originalButton(self): return self._originalButton def maximizeButton(self): return self._maximizeButton def editorTableView(self): return self._editorTableView
class MainWindow(QWidget): """Miow main window """ def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setMinimumWidth(400) self.setMinimumHeight(400) # create widgets self._main_tab = QTabWidget(self) # self._main_tab.setTabsClosable(True) self._main_tab.setMovable(True) self.v_splitter = QSplitter(Qt.Vertical, self) self.v_splitter.addWidget(self._main_tab) layout = QVBoxLayout(self) layout.addWidget(self.v_splitter) layout.setMargin(0) self.setLayout(layout) self.command_window = CommandWindow(self) self.command_window.event_selected_command += self.cw_selected_command import shutil shutil.rmtree("/tmp/miow/", True) os.makedirs("/tmp/miow/") def cw_selected_command(self, command): exec(command) def get_current_widget(self): return self.main_tab.currentWidget() def show_command_window(self, context=None): self.command_window.show_hide(context) def get_command_list(self, context=None): if context == None: command_list = copy(COMMAND_LIST) if self.get_current_widget(): self.get_current_widget().bw_add_command_list(command_list) else: command_list = [] EVENT_REQUEST_COMMAND_CONTEXT(context, command_list) return command_list @property def main_tab(self): return self._main_tab def _add_widget(self, widget_class, params): """Add any kind of widget""" widget = widget_class(params, self.main_tab) self.main_tab.addTab(widget, "?") self.main_tab.setCurrentIndex(self.main_tab.count() - 1) if self.main_tab.count() == 1: # self.v_splitter.setStretchFactor(0, 10) # self.v_splitter.setStretchFactor(1, 3) total_size = sum(self.v_splitter.sizes()) self.v_splitter.setSizes([total_size / 100 * 70, total_size / 100 * 30]) widget.setFocus() core.InterpreterEditor.CURRENT_WIDGET = widget
class OWPythonScript(OWWidget): settingsList = [ "codeFile", "libraryListSource", "currentScriptIndex", "splitterState", "auto_execute" ] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, 'Python Script') self.inputs = [ ("in_data", Orange.data.Table, self.setExampleTable, Default), ("in_distance", Orange.misc.SymMatrix, self.setDistanceMatrix, Default), ("in_learner", Orange.core.Learner, self.setLearner, Default), ("in_classifier", Orange.core.Classifier, self.setClassifier, Default), ("in_object", object, self.setObject) ] self.outputs = [("out_data", Orange.data.Table), ("out_distance", Orange.misc.SymMatrix), ("out_learner", Orange.core.Learner), ("out_classifier", Orange.core.Classifier, Dynamic), ("out_object", object, Dynamic)] self.in_data = None self.in_distance = None self.in_learner = None self.in_classifier = None self.in_object = None self.auto_execute = False self.codeFile = '' self.libraryListSource = [ Script("Hello world", "print 'Hello world'\n") ] self.currentScriptIndex = 0 self.splitterState = None self.loadSettings() for s in self.libraryListSource: s.flags = 0 self._cachedDocuments = {} self.infoBox = OWGUI.widgetBox(self.controlArea, 'Info') OWGUI.label( self.infoBox, self, "<p>Execute python script.</p><p>Input variables:<ul><li> " + \ "<li>".join(t[0] for t in self.inputs) + \ "</ul></p><p>Output variables:<ul><li>" + \ "<li>".join(t[0] for t in self.outputs) + \ "</ul></p>" ) self.libraryList = PyListModel([], self, flags=Qt.ItemIsSelectable | \ Qt.ItemIsEnabled | Qt.ItemIsEditable) self.libraryList.wrap(self.libraryListSource) self.controlBox = OWGUI.widgetBox(self.controlArea, 'Library') self.controlBox.layout().setSpacing(1) self.libraryView = QListView() self.libraryView.setEditTriggers(QListView.DoubleClicked | \ QListView.EditKeyPressed) self.libraryView.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.connect( self.libraryView.selectionModel(), SIGNAL("selectionChanged(QItemSelection, QItemSelection)"), self.onSelectedScriptChanged) self.controlBox.layout().addWidget(self.libraryView) w = ModelActionsWidget() self.addNewScriptAction = action = QAction("+", self) action.setToolTip("Add a new script to the library") self.connect(action, SIGNAL("triggered()"), self.onAddScript) w.addAction(action) self.removeAction = action = QAction("-", self) action.setToolTip("Remove script from library") self.connect(action, SIGNAL("triggered()"), self.onRemoveScript) w.addAction(action) action = QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(QKeySequence(QKeySequence.Save)) self.connect(action, SIGNAL("triggered()"), self.commitChangesToLibrary) w.addAction(action) action = QAction("More", self) action.pyqtConfigure(toolTip="More actions") new_from_file = QAction("Import a script from a file", self) save_to_file = QAction("Save selected script to a file", self) save_to_file.setShortcut(QKeySequence(QKeySequence.SaveAs)) self.connect(new_from_file, SIGNAL("triggered()"), self.onAddScriptFromFile) self.connect(save_to_file, SIGNAL("triggered()"), self.saveScript) menu = QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.runBox = OWGUI.widgetBox(self.controlArea, 'Run') OWGUI.button(self.runBox, self, "Execute", callback=self.execute) OWGUI.checkBox(self.runBox, self, "auto_execute", "Auto execute", tooltip=("Run the script automatically whenever " "the inputs to the widget change.")) self.splitCanvas = QSplitter(Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = \ "Monaco" if sys.platform == "darwin" else "Courier" self.textBox = OWGUI.widgetBox(self, 'Python script') self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(Qt.AlignVCenter) self.text.setTabStopWidth(4) self.connect(self.text, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) self.saveAction = action = QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(QKeySequence(QKeySequence.Save)) action.setShortcutContext(Qt.WidgetWithChildrenShortcut) self.connect(action, SIGNAL("triggered()"), self.saveScript) self.consoleBox = OWGUI.widgetBox(self, 'Console') self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole(self.__dict__, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(QFont(defaultFont)) self.consoleBox.setAlignment(Qt.AlignBottom) self.console.setTabStopWidth(4) self.openScript(self.codeFile) try: self.libraryView.selectionModel().select( self.libraryList.index(self.currentScriptIndex), QItemSelectionModel.ClearAndSelect) except Exception: pass self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(QByteArray(self.splitterState)) self.connect(self.splitCanvas, SIGNAL("splitterMoved(int, int)"), self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def setExampleTable(self, et): self.in_data = et def setDistanceMatrix(self, dm): self.in_distance = dm def setLearner(self, learner): self.in_learner = learner def setClassifier(self, classifier): self.in_classifier = classifier def setObject(self, obj): self.in_object = obj def handleNewSignals(self): if self.auto_execute: self.execute() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): selection = self.libraryView.selectionModel() selection.select(self.libraryList.index(index), QItemSelectionModel.ClearAndSelect) def onAddScript(self, *args): self.libraryList.append(Script("New script", "", 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): filename = QFileDialog.getOpenFileName( self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)') filename = unicode(filename) if filename: name = os.path.basename(filename) self.libraryList.append( Script(name, open(filename, "rb").read(), 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] self.libraryView.selectionModel().select( self.libraryList.index(max(index - 1, 0)), QItemSelectionModel.ClearAndSelect) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) != Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = QTextDocument(self) doc.setDocumentLayout(QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) self.connect(doc, SIGNAL("modificationChanged(bool)"), self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = str(self.splitCanvas.saveState()) def updateSelecetdScriptState(self): index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] self.libraryList[index] = Script(script.name, self.text.toPlainText(), 0) def openScript(self, filename=None): if filename == None: filename = QFileDialog.getOpenFileName( self, 'Open Python Script', self.codeFile, 'Python files (*.py)\nAll files(*.*)') filename = unicode(filename) self.codeFile = filename else: self.codeFile = filename if self.codeFile == "": return self.error(0) try: f = open(self.codeFile, 'r') except (IOError, OSError), ex: self.text.setPlainText("") return self.text.setPlainText(f.read()) f.close()
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 ScoreTable(QWidget): """show scores of current or last game, even if the last game is finished. To achieve this we keep our own reference to game.""" def __init__(self, game): super(ScoreTable, self).__init__(None) self.setObjectName('ScoreTable') self.game = None self.scoreModel = None self.scoreModelTest = None self.setWindowTitle(m18nc('kajongg', 'Scores') + ' - Kajongg') self.setAttribute(Qt.WA_AlwaysShowToolTips) self.setMouseTracking(True) self.__tableFields = ['prevailing', 'won', 'wind', 'points', 'payments', 'balance', 'hand', 'manualrules'] self.setupUi() self.refresh(game) StateSaver(self, self.splitter) def setColWidth(self): """we want to accomodate 5 digits plus minus sign and all column widths should be the same, making horizontal scrolling per item more pleasant""" self.viewRight.setColWidth() def setupUi(self): """setup UI elements""" self.viewLeft = ScoreViewLeft(self) self.viewRight = ScoreViewRight(self) self.viewRight.setHorizontalScrollBar(HorizontalScrollBar(self)) self.viewRight.setHorizontalScrollMode(QAbstractItemView.ScrollPerItem) self.viewRight.setFocusPolicy(Qt.NoFocus) self.viewRight.header().setClickable(False) self.viewRight.header().setMovable(False) self.viewRight.setSelectionMode(QAbstractItemView.NoSelection) windowLayout = QVBoxLayout(self) self.splitter = QSplitter(Qt.Vertical) self.splitter.setObjectName('ScoreTableSplitter') windowLayout.addWidget(self.splitter) scoreWidget = QWidget() self.scoreLayout = QHBoxLayout(scoreWidget) leftLayout = QVBoxLayout() leftLayout.addWidget(self.viewLeft) self.leftLayout = leftLayout self.scoreLayout.addLayout(leftLayout) self.scoreLayout.addWidget(self.viewRight) self.splitter.addWidget(scoreWidget) self.ruleTree = RuleTreeView(m18nc('kajongg','Used Rules')) self.splitter.addWidget(self.ruleTree) # this shows just one line for the ruleTree - so we just see the # name of the ruleset: self.splitter.setSizes(list([1000, 1])) def sizeHint(self): """give the scoring table window a sensible default size""" result = QWidget.sizeHint(self) result.setWidth(result.height() * 3 / 2) # the default is too small. Use at least 2/5 of screen height and 1/4 of screen width: available = KApplication.kApplication().desktop().availableGeometry() height = max(result.height(), available.height() * 2 / 5) width = max(result.width(), available.width() / 4) result.setHeight(height) result.setWidth(width) return result def refresh(self, game): """load this game and this player. Keep parameter list identical with ExplainView""" if not game: # keep scores of previous game on display return if self.scoreModel: expandGroups = [ self.viewLeft.isExpanded(self.scoreModel.index(x, 0, QModelIndex())) for x in range(4)] else: expandGroups = [True, False, True, True] self.game = game gameid = str(self.game.seed or self.game.gameid) if self.game.finished(): title = m18n('Final scores for game <numid>%1</numid>', gameid) else: title = m18n('Scores for game <numid>%1</numid>', gameid) self.setWindowTitle(title + ' - Kajongg') self.ruleTree.rulesets = list([self.game.ruleset]) self.scoreModel = ScoreModel(self) if Debug.modelTest: self.scoreModelTest = ModelTest(self.scoreModel, self) for view in [self.viewLeft, self.viewRight]: view.setModel(self.scoreModel) header = view.header() header.setStretchLastSection(False) view.setAlternatingRowColors(True) self.viewRight.header().setResizeMode(QHeaderView.Fixed) for col in range(self.viewLeft.header().count()): self.viewLeft.header().setSectionHidden(col, col > 0) self.viewRight.header().setSectionHidden(col, col == 0) self.scoreLayout.setStretch(1, 100) self.scoreLayout.setSpacing(0) self.viewLeft.setFrameStyle(QFrame.NoFrame) self.viewRight.setFrameStyle(QFrame.NoFrame) self.viewLeft.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) for master, slave in ((self.viewRight, self.viewLeft), (self.viewLeft, self.viewRight)): master.expanded.connect(slave.expand) master.collapsed.connect(slave.collapse) master.verticalScrollBar().valueChanged.connect(slave.verticalScrollBar().setValue) for row, expand in enumerate(expandGroups): self.viewLeft.setExpanded(self.scoreModel.index(row, 0, QModelIndex()), expand) self.viewLeft.resizeColumnToContents(0) self.viewRight.setColWidth() # we need a timer since the scrollbar is not yet visible QTimer.singleShot(0, self.scrollRight) def scrollRight(self): """make sure the latest hand is visible""" scrollBar = self.viewRight.horizontalScrollBar() scrollBar.setValue(scrollBar.maximum()) def showEvent(self, dummyEvent): """Only now the views and scrollbars have useful sizes, so we can compute the spacer for the left view""" self.adaptLeftViewHeight() def adaptLeftViewHeight(self): """if the right view has a horizontal scrollbar, make sure both view have the same vertical scroll area. Otherwise scrolling to bottom results in unsyncronized views.""" if self.viewRight.horizontalScrollBar().isVisible(): height = self.viewRight.horizontalScrollBar().height() else: height = 0 if self.leftLayout.count() > 1: # remove previous spacer self.leftLayout.takeAt(1) if height: self.leftLayout.addSpacing(height)
class AsciidocEditor(WithSingleIO, QWidget): """Asciidoc editor """ def __init__(self, params, parent=None): self.base_dir = os.path.dirname(__file__) QWidget.__init__(self, parent) self.setMinimumWidth(300) self.setMinimumHeight(300) # create widgets self._editor_widget = mixin( WithFind, WidthMqHighlighter, WithMqEditIO, WithBasicIdentationManager, WithLineHighlight, WithFixedFont, WithLineNumbers, WithViewPortMargins, WithWordCompletionMulty_, WithCompletion, QPlainTextEdit)(self) self.webview = QWebView(self) #self.webview.load(QUrl("/home/maiquel/develop/developing/main/qt/qadoc/bin/__builds/documents.html")) self.splitter = QSplitter(Qt.Horizontal) self.splitter.addWidget(self._editor_widget) self.splitter.addWidget(self.webview) self.splitter.setSizes([self.size().width(), self.size().width()]) self.splitterv = QSplitter(Qt.Vertical) self.splitterv.addWidget(self.splitter) self.log_widget = QPlainTextEdit() self.splitterv.addWidget(self.log_widget) layout = QVBoxLayout(self) layout.addWidget(self.splitterv) layout.setMargin(0) self.setLayout(layout) # proc_compile self.proc_compile = QProcess() self.proc_compile.finished.connect(self.proc_compile_finished) self.proc_compile.error.connect(self.proc_compile_error) self.proc_compile.readyReadStandardOutput.connect(self.proc_compile_readyReadStandardOutput) self.proc_compile.readyReadStandardError.connect(self.proc_compile_readyReadStandardError) WithSingleIO.__init__(self, params) def bw_add_command_list(self, command_list): command_list += [ ("generate preview asciidoc", "pp", 1.0, "self.get_current_widget().command_generate_preview('asciidoc -a toc -a data-uri -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview asciidoc style_sheet no images embeded", "pp", 1.0, "self.get_current_widget().command_generate_preview('asciidoc -a toc --attribute stylesheet="+self.base_dir+"/adoc/mq_red.css -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview asciidoc style_sheet", "pp", 1.2, "self.get_current_widget().command_generate_preview('asciidoc -a toc --attribute stylesheet="+self.base_dir+"/adoc/mq_red.css -a data-uri -a icons -a iconsdir="+self.base_dir+"/adoc/icons/')"), ("generate preview slidy", "pp slides", 0.8, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b slidy -a data-uri -a icons')"), ("generate preview slidy2", "pp slides", 0.9, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b slidy2 -a data-uri -a icons')"), ("generate preview asciidoctor", "pp", 0.7, "self.get_current_widget().command_generate_preview('asciidoctor -a toc -a data-uri -a icons')"), ("generate preview deck.js", "pp slides", 0.7, "self.get_current_widget().command_generate_preview('asciidoc -a toc -b deckjs -a data-uri -a icons')"), ("generate pdf small", "", 0., """self.get_current_widget().command_generate_document('a2x --verbose -d article --icons --dblatex-opts "-T native -P doc.pdfcreator.show=0 -P doc.collab.show=0 -P latex.output.revhistory=0 -P doc.toc.show=1 -P table.title.top" -f pdf -D /tmp/adoc/ ')"""), ("generate pdf book", "", 0., """self.get_current_widget().command_generate_document('a2x --verbose -d book --icons --dblatex-opts "-T native -P doc.pdfcreator.show=0 -P doc.collab.show=0 -P latex.output.revhistory=0 -P doc.toc.show=1 -P table.title.top" -f pdf -D /tmp/adoc/ ')"""), ] super(AsciidocEditor, self).bw_add_command_list(command_list) self._editor_widget.bw_add_command_list(command_list) command_list += [ ("focus editor", "fe", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self._editor_widget.setFocus();"), ("focus preview", "fp", 0.5, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setFocus();"), ("increase font webview", "if if", 0.7, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setTextSizeMultiplier(_self.webview.textSizeMultiplier()+0.1);"), ("decrease font webview", "df df", 0.7, "import ctypes; _self = ctypes.cast(" + str(id(self)) + ", ctypes.py_object).value;" "_self.webview.setTextSizeMultiplier(_self.webview.textSizeMultiplier()-0.1);"), ] def copy2tmp(self): if not os.path.exists(TEMP_DIR): os.mkdir(TEMP_DIR) source = os.listdir(self.base_dir) destination = TEMP_DIR for files in source: shutil.move(files,destination) def command_generate_preview(self, adoc_command): self.command_save_file() #self.compile(backend + " -b deckjs -o " + self.get_html_output() + " " + TEMP_DIR + "pr.adoc") #asciidoc --verbose -a data-uri -a icons -a toc -a max-width=55em -o __builds/index.html /home/maiquel/Documents/qadoc/adoc/index.adoc #self.compile(adoc_command + " --attribute stylesheet=/home/maiquel/inet.prj/miow/widgets/adoc/mq_red.css -a data-uri -a icons -o " + self.get_html_output() + " " + TEMP_DIR + "pr.adoc") self.compile(adoc_command + ' -o ' +self.get_html_output() + ' ./"' + self.file_name + '"') if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def command_generate_document(self, adoc_command): self.command_save_file() self.compile(adoc_command + " " + TEMP_DIR + "pr.adoc") if self.webview.url() != QUrl("file://" + self.get_html_output()): self.webview.load(QUrl(self.get_html_output())) def compile(self, command): self.log(command) self.proc_compile.start(command) def bw_lock_command_window(self): return self._editor_widget.completer.popup().isVisible() def focusInEvent(self, focus_event): super(AsciidocEditor, self).focusInEvent(focus_event) self._editor_widget.setFocus() def get_html_output(self): return TEMP_DIR + "pr.html" def proc_compile_finished(self, result, exit_status): self.log("compilation finished") if self.webview.url().toString() == "": self.webview.load(QUrl(self.get_html_output())) else: self.webview.reload() def proc_compile_error(self, q_process_error): self.log("compilation error") print(q_process_error) def proc_compile_readyReadStandardOutput(self): result = self.proc_compile.readAllStandardOutput(); self.log(result) def proc_compile_readyReadStandardError(self): result = str(self.proc_compile.readAllStandardError()) self.log(result) def log(self, text): self.log_widget.appendPlainText(unicode(text))
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 QuadView(QWidget): def __init__(self, parent, view1, view2, view3, view4=None): QWidget.__init__(self, parent) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.installEventFilter(self) self.dockableContainer = [] self.layout = QVBoxLayout() self.setLayout(self.layout) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.splitVertical = QSplitter(Qt.Vertical, self) self.layout.addWidget(self.splitVertical) self.splitHorizontal1 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal1.setObjectName("splitter1") self.splitHorizontal2 = QSplitter(Qt.Horizontal, self.splitVertical) self.splitHorizontal2.setObjectName("splitter2") self.splitHorizontal1.splitterMoved.connect( self.horizontalSplitterMoved) self.splitHorizontal2.splitterMoved.connect( self.horizontalSplitterMoved) self.imageView2D_1 = view1 self.imageView2D_2 = view2 self.imageView2D_3 = view3 self.dock1_ofSplitHorizontal1 = ImageView2DDockWidget( self.imageView2D_1) self.dock1_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal1) self.dock1_ofSplitHorizontal1.onDockButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal1: self.on_dock(arg)) self.dock1_ofSplitHorizontal1.onMaxButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal1: self.on_max(arg)) self.dock1_ofSplitHorizontal1.onMinButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal1: self.on_min(arg)) self.splitHorizontal1.addWidget(self.dock1_ofSplitHorizontal1) self.dock2_ofSplitHorizontal1 = ImageView2DDockWidget( self.imageView2D_2) self.dock2_ofSplitHorizontal1.onDockButtonClicked.connect( lambda arg=self.dock2_ofSplitHorizontal1: self.on_dock(arg)) self.dock2_ofSplitHorizontal1.onMaxButtonClicked.connect( lambda arg=self.dock2_ofSplitHorizontal1: self.on_max(arg)) self.dock2_ofSplitHorizontal1.onMinButtonClicked.connect( lambda arg=self.dock2_ofSplitHorizontal1: self.on_min(arg)) self.dock2_ofSplitHorizontal1.connectHud() self.dockableContainer.append(self.dock2_ofSplitHorizontal1) self.splitHorizontal1.addWidget(self.dock2_ofSplitHorizontal1) self.dock1_ofSplitHorizontal2 = ImageView2DDockWidget( self.imageView2D_3) self.dock1_ofSplitHorizontal2.onDockButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal2: self.on_dock(arg)) self.dock1_ofSplitHorizontal2.onMaxButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal2: self.on_max(arg)) self.dock1_ofSplitHorizontal2.onMinButtonClicked.connect( lambda arg=self.dock1_ofSplitHorizontal2: self.on_min(arg)) self.dock1_ofSplitHorizontal2.connectHud() self.dockableContainer.append(self.dock1_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock1_ofSplitHorizontal2) self.dock2_ofSplitHorizontal2 = ImageView2DDockWidget(view4) self.dockableContainer.append(self.dock2_ofSplitHorizontal2) self.splitHorizontal2.addWidget(self.dock2_ofSplitHorizontal2) #this is a hack: with 0 ms it does not work... QTimer.singleShot(250, self._resizeEqual) def _resizeEqual(self): if not all([dock.isVisible() for dock in self.dockableContainer]): return assert sys.version_info.major == 2, "Alert! This function has not been tested "\ "under python 3. Please remove this assetion and be wary of any strnage behavior you encounter" w, h = self.size().width() - self.splitHorizontal1.handleWidth( ), self.size().height() - self.splitVertical.handleWidth() self.splitVertical.setSizes([h / 2, h / 2]) if self.splitHorizontal1.count() == 2 and self.splitHorizontal2.count( ) == 2: #docks = [self.imageView2D_1, self.imageView2D_2, self.imageView2D_3, self.testView4] docks = [] for splitter in [self.splitHorizontal1, self.splitHorizontal2]: for i in range(splitter.count()): docks.append(splitter.widget(i).graphicsView) w1 = [docks[i].minimumSize().width() for i in [0, 2]] w2 = [docks[i].minimumSize().width() for i in [1, 3]] wLeft = max(w1) wRight = max(w2) if wLeft > wRight and wLeft > w // 2: wRight = w - wLeft elif wRight >= wLeft and wRight > w // 2: wLeft = w - wRight else: wLeft = w // 2 wRight = w // 2 self.splitHorizontal1.setSizes([wLeft, wRight]) self.splitHorizontal2.setSizes([wLeft, wRight]) def eventFilter(self, obj, event): if (event.type() in [QEvent.WindowActivate, QEvent.Show]): self._synchronizeSplitter() return False def _synchronizeSplitter(self): sizes1 = self.splitHorizontal1.sizes() sizes2 = self.splitHorizontal2.sizes() if len(sizes1) > 0 and sizes1[0] > 0: self.splitHorizontal2.setSizes(sizes1) elif len(sizes2) > 0 and sizes2[0] > 0: self.splitHorizontal1.setSizes(sizes2) def resizeEvent(self, event): QWidget.resizeEvent(self, event) self._synchronizeSplitter() def horizontalSplitterMoved(self, x, y): if self.splitHorizontal1.count() != 2 or self.splitHorizontal2.count( ) != 2: return sizes = self.splitHorizontal1.sizes() #What. Nr2 if self.splitHorizontal2.closestLegalPosition( x, y) < self.splitHorizontal2.closestLegalPosition(x, y): sizeLeft = self.splitHorizontal1.closestLegalPosition(x, y) else: sizeLeft = self.splitHorizontal2.closestLegalPosition(x, y) sizeRight = sizes[0] + sizes[1] - sizeLeft sizes = [sizeLeft, sizeRight] self.splitHorizontal1.setSizes(sizes) self.splitHorizontal2.setSizes(sizes) def addStatusBar(self, bar): self.statusBar = bar self.layout.addLayout(self.statusBar) def setGrayScaleToQuadStatusBar(self, gray): self.quadViewStatusBar.setGrayScale(gray) def setMouseCoordsToQuadStatusBar(self, x, y, z): self.quadViewStatusBar.setMouseCoords(x, y, z) def ensureMaximized(self, axis): """ Maximize the view for the given axis if it isn't already maximized. """ axisDict = { 0: self.dock2_ofSplitHorizontal1, # x 1: self.dock1_ofSplitHorizontal2, # y 2: self.dock1_ofSplitHorizontal1 } # z if not axisDict[axis]._isMaximized: self.switchMinMax(axis) def switchMinMax(self, axis): """Switch an AxisViewWidget between from minimized to maximized and vice versa. Keyword arguments: axis -- the axis which is represented by the widget (no default) either string or integer 'x' - 0 'y' - 1 'z' - 2 """ #TODO: get the mapping information from where it is set! if this is not #done properly - do it properly if type(axis) == str: axisDict = { 'x': self.dock2_ofSplitHorizontal1, # x 'y': self.dock1_ofSplitHorizontal2, # y 'z': self.dock1_ofSplitHorizontal1 } # z elif type(axis) == int: axisDict = { 0: self.dock2_ofSplitHorizontal1, # x 1: self.dock1_ofSplitHorizontal2, # y 2: self.dock1_ofSplitHorizontal1 } # z dockWidget = axisDict.pop(axis) for dWidget in axisDict.values(): if dWidget._isMaximized: dWidget.graphicsView._hud.maximizeButtonClicked.emit() dockWidget.graphicsView._hud.maximizeButtonClicked.emit() def switchXMinMax(self): self.switchMinMax('x') def switchYMinMax(self): self.switchMinMax('y') def switchZMinMax(self): self.switchMinMax('z') def on_dock(self, dockWidget): if dockWidget._isDocked: dockWidget.undockView() self.on_min(dockWidget) dockWidget.minimizeView() else: dockWidget.dockView() def on_max(self, dockWidget): dockWidget.setVisible(True) for dock in self.dockableContainer: if not dockWidget == dock: dock.setVisible(False) # Force sizes to be updated now QApplication.processEvents() # On linux, the vertical splitter doesn't seem to refresh unless we do so manually # Presumably, this is a QT bug. self.splitVertical.refresh() # Viewport doesn't update automatically... view = dockWidget.graphicsView view.viewport().setGeometry(view.rect()) def on_min(self, dockWidget): for dock in self.dockableContainer: dock.setVisible(True) # Force sizes to be updated now QApplication.processEvents() self._resizeEqual() # Viewports don't update automatically... for dock in self.dockableContainer: view = dock.graphicsView if hasattr(view, 'viewport'): view.viewport().setGeometry(view.rect())
class ConfigEditorTab(BrowserTab): """ This is the main frame of the Config Editor Plugin. The tab is split in three horizontal parts, from left to right: Tree View, Center View, Property View. The editor can be dispayed using createEditor(). The Property View is then shared with the ConfigBrowser. """ def __init__(self, parent=None): """ constructor """ logging.debug(self.__class__.__name__ +": __init__()") BrowserTab.__init__(self, parent,True) self._editorSplitter = None def createEditor(self): self.createToolBar(0) self._editorSplitter = QSplitter(Qt.Horizontal) toolBarSectionId = self.toolBar().addSection(SplitterToolBar.ALIGNMENT_LEFT) self._editorTableView=CodeTableView(self._editorSplitter) self._editorSplitter.setSizes([100, 300]) self._minimizeButton = QToolButton() self._minimizeButton.setText("v") self._minimizeButton.setCheckable(True) self._originalButton = QToolButton() self._originalButton.setText("-") self._originalButton.setCheckable(True) self._originalButton.setChecked(True) self._maximizeButton = QToolButton() self._maximizeButton.setText("^") self._maximizeButton.setCheckable(True) self._centerViewToolBarId = self.toolBar().addSection(SplitterToolBar.ALIGNMENT_CENTER) self.toolBar().addWidgetToSection(self._minimizeButton, self._centerViewToolBarId) self.toolBar().addWidgetToSection(self._originalButton, self._centerViewToolBarId) self.toolBar().addWidgetToSection(self._maximizeButton, self._centerViewToolBarId) self.verticalSplitter().insertWidget(0,self._editorSplitter) self.updateToolBarSizes() controller = self.controller() if controller: self.connect(self._minimizeButton, SIGNAL('clicked(bool)'), controller.minimizeEditor) self.connect(self._originalButton, SIGNAL('clicked(bool)'), controller.originalEditor) self.connect(self._maximizeButton, SIGNAL('clicked(bool)'), controller.maximizeEditor) def editorSplitter(self): return self._editorSplitter def horizontalSplitterMovedSlot(self, pos, index): if self.toolBar(): self.updateToolBarSizes() def updateToolBarSizes(self): self.toolBar().setSectionSizes(self.horizontalSplitter().sizes()) def minimizeButton(self): return self._minimizeButton def originalButton(self): return self._originalButton def maximizeButton(self): return self._maximizeButton def editorTableView(self): return self._editorTableView
class PythonConsoleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setWindowTitle(QCoreApplication.translate("PythonConsole", "Python Console")) self.settings = QSettings() self.shell = ShellScintilla(self) self.setFocusProxy(self.shell) self.shellOut = ShellOutputScintilla(self) self.tabEditorWidget = EditorTabWidget(self) ##------------ UI ------------------------------- self.splitterEditor = QSplitter(self) self.splitterEditor.setOrientation(Qt.Horizontal) self.splitterEditor.setHandleWidth(6) self.splitterEditor.setChildrenCollapsible(True) self.shellOutWidget = QWidget(self) self.shellOutWidget.setLayout(QVBoxLayout()) self.shellOutWidget.layout().setContentsMargins(0, 0, 0, 0) self.shellOutWidget.layout().addWidget(self.shellOut) self.splitter = QSplitter(self.splitterEditor) self.splitter.setOrientation(Qt.Vertical) self.splitter.setHandleWidth(3) self.splitter.setChildrenCollapsible(False) self.splitter.addWidget(self.shellOutWidget) self.splitter.addWidget(self.shell) #self.splitterEditor.addWidget(self.tabEditorWidget) self.splitterObj = QSplitter(self.splitterEditor) self.splitterObj.setHandleWidth(3) self.splitterObj.setOrientation(Qt.Horizontal) #self.splitterObj.setSizes([0, 0]) #self.splitterObj.setStretchFactor(0, 1) self.widgetEditor = QWidget(self.splitterObj) self.widgetFind = QWidget(self) self.listClassMethod = QTreeWidget(self.splitterObj) self.listClassMethod.setColumnCount(2) objInspLabel = QCoreApplication.translate("PythonConsole", "Object Inspector") self.listClassMethod.setHeaderLabels([objInspLabel, '']) self.listClassMethod.setColumnHidden(1, True) self.listClassMethod.setAlternatingRowColors(True) #self.splitterEditor.addWidget(self.widgetEditor) #self.splitterObj.addWidget(self.listClassMethod) #self.splitterObj.addWidget(self.widgetEditor) # Hide side editor on start up self.splitterObj.hide() self.listClassMethod.hide() # Hide search widget on start up self.widgetFind.hide() sizes = self.splitter.sizes() self.splitter.setSizes(sizes) ##----------------Restore Settings------------------------------------ self.restoreSettingsConsole() ##------------------Toolbar Editor------------------------------------- ## Action for Open File openFileBt = QCoreApplication.translate("PythonConsole", "Open file") self.openFileButton = QAction(self) self.openFileButton.setCheckable(False) self.openFileButton.setEnabled(True) self.openFileButton.setIcon(QgsApplication.getThemeIcon("console/iconOpenConsole.png")) self.openFileButton.setMenuRole(QAction.PreferencesRole) self.openFileButton.setIconVisibleInMenu(True) self.openFileButton.setToolTip(openFileBt) self.openFileButton.setText(openFileBt) openExtEditorBt = QCoreApplication.translate("PythonConsole", "Open in external editor") self.openInEditorButton = QAction(self) self.openInEditorButton.setCheckable(False) self.openInEditorButton.setEnabled(True) self.openInEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.openInEditorButton.setMenuRole(QAction.PreferencesRole) self.openInEditorButton.setIconVisibleInMenu(True) self.openInEditorButton.setToolTip(openExtEditorBt) self.openInEditorButton.setText(openExtEditorBt) ## Action for Save File saveFileBt = QCoreApplication.translate("PythonConsole", "Save") self.saveFileButton = QAction(self) self.saveFileButton.setCheckable(False) self.saveFileButton.setEnabled(False) self.saveFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveConsole.png")) self.saveFileButton.setMenuRole(QAction.PreferencesRole) self.saveFileButton.setIconVisibleInMenu(True) self.saveFileButton.setToolTip(saveFileBt) self.saveFileButton.setText(saveFileBt) ## Action for Save File As saveAsFileBt = QCoreApplication.translate("PythonConsole", "Save As...") self.saveAsFileButton = QAction(self) self.saveAsFileButton.setCheckable(False) self.saveAsFileButton.setEnabled(True) self.saveAsFileButton.setIcon(QgsApplication.getThemeIcon("console/iconSaveAsConsole.png")) self.saveAsFileButton.setMenuRole(QAction.PreferencesRole) self.saveAsFileButton.setIconVisibleInMenu(True) self.saveAsFileButton.setToolTip(saveAsFileBt) self.saveAsFileButton.setText(saveAsFileBt) ## Action Cut cutEditorBt = QCoreApplication.translate("PythonConsole", "Cut") self.cutEditorButton = QAction(self) self.cutEditorButton.setCheckable(False) self.cutEditorButton.setEnabled(True) self.cutEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCutEditorConsole.png")) self.cutEditorButton.setMenuRole(QAction.PreferencesRole) self.cutEditorButton.setIconVisibleInMenu(True) self.cutEditorButton.setToolTip(cutEditorBt) self.cutEditorButton.setText(cutEditorBt) ## Action Copy copyEditorBt = QCoreApplication.translate("PythonConsole", "Copy") self.copyEditorButton = QAction(self) self.copyEditorButton.setCheckable(False) self.copyEditorButton.setEnabled(True) self.copyEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCopyEditorConsole.png")) self.copyEditorButton.setMenuRole(QAction.PreferencesRole) self.copyEditorButton.setIconVisibleInMenu(True) self.copyEditorButton.setToolTip(copyEditorBt) self.copyEditorButton.setText(copyEditorBt) ## Action Paste pasteEditorBt = QCoreApplication.translate("PythonConsole", "Paste") self.pasteEditorButton = QAction(self) self.pasteEditorButton.setCheckable(False) self.pasteEditorButton.setEnabled(True) self.pasteEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconPasteEditorConsole.png")) self.pasteEditorButton.setMenuRole(QAction.PreferencesRole) self.pasteEditorButton.setIconVisibleInMenu(True) self.pasteEditorButton.setToolTip(pasteEditorBt) self.pasteEditorButton.setText(pasteEditorBt) ## Action Run Script (subprocess) runScriptEditorBt = QCoreApplication.translate("PythonConsole", "Run script") self.runScriptEditorButton = QAction(self) self.runScriptEditorButton.setCheckable(False) self.runScriptEditorButton.setEnabled(True) self.runScriptEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconRunScriptConsole.png")) self.runScriptEditorButton.setMenuRole(QAction.PreferencesRole) self.runScriptEditorButton.setIconVisibleInMenu(True) self.runScriptEditorButton.setToolTip(runScriptEditorBt) self.runScriptEditorButton.setText(runScriptEditorBt) ## Action Run Script (subprocess) commentEditorBt = QCoreApplication.translate("PythonConsole", "Comment") self.commentEditorButton = QAction(self) self.commentEditorButton.setCheckable(False) self.commentEditorButton.setEnabled(True) self.commentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconCommentEditorConsole.png")) self.commentEditorButton.setMenuRole(QAction.PreferencesRole) self.commentEditorButton.setIconVisibleInMenu(True) self.commentEditorButton.setToolTip(commentEditorBt) self.commentEditorButton.setText(commentEditorBt) ## Action Run Script (subprocess) uncommentEditorBt = QCoreApplication.translate("PythonConsole", "Uncomment") self.uncommentEditorButton = QAction(self) self.uncommentEditorButton.setCheckable(False) self.uncommentEditorButton.setEnabled(True) self.uncommentEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconUncommentEditorConsole.png")) self.uncommentEditorButton.setMenuRole(QAction.PreferencesRole) self.uncommentEditorButton.setIconVisibleInMenu(True) self.uncommentEditorButton.setToolTip(uncommentEditorBt) self.uncommentEditorButton.setText(uncommentEditorBt) ## Action for Object browser objList = QCoreApplication.translate("PythonConsole", "Object Inspector") self.objectListButton = QAction(self) self.objectListButton.setCheckable(True) self.objectListButton.setEnabled(self.settings.value("pythonConsole/enableObjectInsp", False, type=bool)) self.objectListButton.setIcon(QgsApplication.getThemeIcon("console/iconClassBrowserConsole.png")) self.objectListButton.setMenuRole(QAction.PreferencesRole) self.objectListButton.setIconVisibleInMenu(True) self.objectListButton.setToolTip(objList) self.objectListButton.setText(objList) ## Action for Find text findText = QCoreApplication.translate("PythonConsole", "Find Text") self.findTextButton = QAction(self) self.findTextButton.setCheckable(True) self.findTextButton.setEnabled(True) self.findTextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchEditorConsole.png")) self.findTextButton.setMenuRole(QAction.PreferencesRole) self.findTextButton.setIconVisibleInMenu(True) self.findTextButton.setToolTip(findText) self.findTextButton.setText(findText) ##----------------Toolbar Console------------------------------------- ## Action Show Editor showEditor = QCoreApplication.translate("PythonConsole", "Show editor") self.showEditorButton = QAction(self) self.showEditorButton.setEnabled(True) self.showEditorButton.setCheckable(True) self.showEditorButton.setIcon(QgsApplication.getThemeIcon("console/iconShowEditorConsole.png")) self.showEditorButton.setMenuRole(QAction.PreferencesRole) self.showEditorButton.setIconVisibleInMenu(True) self.showEditorButton.setToolTip(showEditor) self.showEditorButton.setText(showEditor) ## Action for Clear button clearBt = QCoreApplication.translate("PythonConsole", "Clear console") self.clearButton = QAction(self) self.clearButton.setCheckable(False) self.clearButton.setEnabled(True) self.clearButton.setIcon(QgsApplication.getThemeIcon("console/iconClearConsole.png")) self.clearButton.setMenuRole(QAction.PreferencesRole) self.clearButton.setIconVisibleInMenu(True) self.clearButton.setToolTip(clearBt) self.clearButton.setText(clearBt) ## Action for settings optionsBt = QCoreApplication.translate("PythonConsole", "Settings") self.optionsButton = QAction(self) self.optionsButton.setCheckable(False) self.optionsButton.setEnabled(True) self.optionsButton.setIcon(QgsApplication.getThemeIcon("console/iconSettingsConsole.png")) self.optionsButton.setMenuRole(QAction.PreferencesRole) self.optionsButton.setIconVisibleInMenu(True) self.optionsButton.setToolTip(optionsBt) self.optionsButton.setText(optionsBt) ## Action menu for class actionClassBt = QCoreApplication.translate("PythonConsole", "Import Class") self.actionClass = QAction(self) self.actionClass.setCheckable(False) self.actionClass.setEnabled(True) self.actionClass.setIcon(QgsApplication.getThemeIcon("console/iconClassConsole.png")) self.actionClass.setMenuRole(QAction.PreferencesRole) self.actionClass.setIconVisibleInMenu(True) self.actionClass.setToolTip(actionClassBt) self.actionClass.setText(actionClassBt) ## Import Processing class loadProcessingBt = QCoreApplication.translate("PythonConsole", "Import Processing class") self.loadProcessingButton = QAction(self) self.loadProcessingButton.setCheckable(False) self.loadProcessingButton.setEnabled(True) self.loadProcessingButton.setIcon(QgsApplication.getThemeIcon("console/iconProcessingConsole.png")) self.loadProcessingButton.setMenuRole(QAction.PreferencesRole) self.loadProcessingButton.setIconVisibleInMenu(True) self.loadProcessingButton.setToolTip(loadProcessingBt) self.loadProcessingButton.setText(loadProcessingBt) ## Import QtCore class loadQtCoreBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtCore class") self.loadQtCoreButton = QAction(self) self.loadQtCoreButton.setCheckable(False) self.loadQtCoreButton.setEnabled(True) self.loadQtCoreButton.setIcon(QgsApplication.getThemeIcon("console/iconQtCoreConsole.png")) self.loadQtCoreButton.setMenuRole(QAction.PreferencesRole) self.loadQtCoreButton.setIconVisibleInMenu(True) self.loadQtCoreButton.setToolTip(loadQtCoreBt) self.loadQtCoreButton.setText(loadQtCoreBt) ## Import QtGui class loadQtGuiBt = QCoreApplication.translate("PythonConsole", "Import PyQt.QtGui class") self.loadQtGuiButton = QAction(self) self.loadQtGuiButton.setCheckable(False) self.loadQtGuiButton.setEnabled(True) self.loadQtGuiButton.setIcon(QgsApplication.getThemeIcon("console/iconQtGuiConsole.png")) self.loadQtGuiButton.setMenuRole(QAction.PreferencesRole) self.loadQtGuiButton.setIconVisibleInMenu(True) self.loadQtGuiButton.setToolTip(loadQtGuiBt) self.loadQtGuiButton.setText(loadQtGuiBt) ## Action for Run script runBt = QCoreApplication.translate("PythonConsole", "Run command") self.runButton = QAction(self) self.runButton.setCheckable(False) self.runButton.setEnabled(True) self.runButton.setIcon(QgsApplication.getThemeIcon("console/iconRunConsole.png")) self.runButton.setMenuRole(QAction.PreferencesRole) self.runButton.setIconVisibleInMenu(True) self.runButton.setToolTip(runBt) self.runButton.setText(runBt) ## Help action helpBt = QCoreApplication.translate("PythonConsole", "Help") self.helpButton = QAction(self) self.helpButton.setCheckable(False) self.helpButton.setEnabled(True) self.helpButton.setIcon(QgsApplication.getThemeIcon("console/iconHelpConsole.png")) self.helpButton.setMenuRole(QAction.PreferencesRole) self.helpButton.setIconVisibleInMenu(True) self.helpButton.setToolTip(helpBt) self.helpButton.setText(helpBt) self.toolBar = QToolBar() self.toolBar.setEnabled(True) self.toolBar.setFocusPolicy(Qt.NoFocus) self.toolBar.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBar.setLayoutDirection(Qt.LeftToRight) self.toolBar.setIconSize(QSize(16, 16)) self.toolBar.setMovable(False) self.toolBar.setFloatable(False) self.toolBar.addAction(self.clearButton) self.toolBar.addAction(self.actionClass) self.toolBar.addAction(self.runButton) self.toolBar.addSeparator() self.toolBar.addAction(self.showEditorButton) self.toolBar.addSeparator() self.toolBar.addAction(self.optionsButton) self.toolBar.addAction(self.helpButton) self.toolBarEditor = QToolBar() self.toolBarEditor.setEnabled(False) self.toolBarEditor.setFocusPolicy(Qt.NoFocus) self.toolBarEditor.setContextMenuPolicy(Qt.DefaultContextMenu) self.toolBarEditor.setLayoutDirection(Qt.LeftToRight) self.toolBarEditor.setIconSize(QSize(16, 16)) self.toolBarEditor.setMovable(False) self.toolBarEditor.setFloatable(False) self.toolBarEditor.addAction(self.openFileButton) self.toolBarEditor.addAction(self.openInEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.saveFileButton) self.toolBarEditor.addAction(self.saveAsFileButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.runScriptEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.findTextButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.cutEditorButton) self.toolBarEditor.addAction(self.copyEditorButton) self.toolBarEditor.addAction(self.pasteEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.commentEditorButton) self.toolBarEditor.addAction(self.uncommentEditorButton) self.toolBarEditor.addSeparator() self.toolBarEditor.addAction(self.objectListButton) ## Menu Import Class self.classMenu = QMenu() self.classMenu.addAction(self.loadProcessingButton) self.classMenu.addAction(self.loadQtCoreButton) self.classMenu.addAction(self.loadQtGuiButton) cM = self.toolBar.widgetForAction(self.actionClass) cM.setMenu(self.classMenu) cM.setPopupMode(QToolButton.InstantPopup) self.widgetButton = QWidget() sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButton.sizePolicy().hasHeightForWidth()) self.widgetButton.setSizePolicy(sizePolicy) self.widgetButtonEditor = QWidget(self.widgetEditor) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.widgetButtonEditor.sizePolicy().hasHeightForWidth()) self.widgetButtonEditor.setSizePolicy(sizePolicy) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.shellOut.sizePolicy().hasHeightForWidth()) self.shellOut.setSizePolicy(sizePolicy) self.shellOut.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.shell.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) ##------------ Layout ------------------------------- self.mainLayout = QGridLayout(self) self.mainLayout.setMargin(0) self.mainLayout.setSpacing(0) self.mainLayout.addWidget(self.widgetButton, 0, 0, 1, 1) self.mainLayout.addWidget(self.splitterEditor, 0, 1, 1, 1) self.shellOutWidget.layout().insertWidget(0, self.toolBar) self.layoutEditor = QGridLayout(self.widgetEditor) self.layoutEditor.setMargin(0) self.layoutEditor.setSpacing(0) self.layoutEditor.addWidget(self.toolBarEditor, 0, 1, 1, 1) self.layoutEditor.addWidget(self.widgetButtonEditor, 1, 0, 2, 1) self.layoutEditor.addWidget(self.tabEditorWidget, 1, 1, 1, 1) self.layoutEditor.addWidget(self.widgetFind, 2, 1, 1, 1) ## Layout for the find widget self.layoutFind = QGridLayout(self.widgetFind) self.layoutFind.setContentsMargins(0, 0, 0, 0) self.lineEditFind = QgsFilterLineEdit() placeHolderTxt = QCoreApplication.translate("PythonConsole", "Enter text to find...") if pyqtconfig.Configuration().qt_version >= 0x40700: self.lineEditFind.setPlaceholderText(placeHolderTxt) else: self.lineEditFind.setToolTip(placeHolderTxt) self.findNextButton = QToolButton() self.findNextButton.setEnabled(False) toolTipfindNext = QCoreApplication.translate("PythonConsole", "Find Next") self.findNextButton.setToolTip(toolTipfindNext) self.findNextButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchNextEditorConsole.png")) self.findNextButton.setIconSize(QSize(24, 24)) self.findNextButton.setAutoRaise(True) self.findPrevButton = QToolButton() self.findPrevButton.setEnabled(False) toolTipfindPrev = QCoreApplication.translate("PythonConsole", "Find Previous") self.findPrevButton.setToolTip(toolTipfindPrev) self.findPrevButton.setIcon(QgsApplication.getThemeIcon("console/iconSearchPrevEditorConsole.png")) self.findPrevButton.setIconSize(QSize(24, 24)) self.findPrevButton.setAutoRaise(True) self.caseSensitive = QCheckBox() caseSensTr = QCoreApplication.translate("PythonConsole", "Case Sensitive") self.caseSensitive.setText(caseSensTr) self.wholeWord = QCheckBox() wholeWordTr = QCoreApplication.translate("PythonConsole", "Whole Word") self.wholeWord.setText(wholeWordTr) self.wrapAround = QCheckBox() self.wrapAround.setChecked(True) wrapAroundTr = QCoreApplication.translate("PythonConsole", "Wrap Around") self.wrapAround.setText(wrapAroundTr) self.layoutFind.addWidget(self.lineEditFind, 0, 1, 1, 1) self.layoutFind.addWidget(self.findPrevButton, 0, 2, 1, 1) self.layoutFind.addWidget(self.findNextButton, 0, 3, 1, 1) self.layoutFind.addWidget(self.caseSensitive, 0, 4, 1, 1) self.layoutFind.addWidget(self.wholeWord, 0, 5, 1, 1) self.layoutFind.addWidget(self.wrapAround, 0, 6, 1, 1) ##------------ Add first Tab in Editor ------------------------------- #self.tabEditorWidget.newTabEditor(tabName='first', filename=None) ##------------ Signal ------------------------------- self.findTextButton.toggled.connect(self.findTextEditor) self.objectListButton.toggled.connect(self.toggleObjectListWidget) self.commentEditorButton.triggered.connect(self.commentCode) self.uncommentEditorButton.triggered.connect(self.uncommentCode) self.runScriptEditorButton.triggered.connect(self.runScriptEditor) self.cutEditorButton.triggered.connect(self.cutEditor) self.copyEditorButton.triggered.connect(self.copyEditor) self.pasteEditorButton.triggered.connect(self.pasteEditor) self.showEditorButton.toggled.connect(self.toggleEditor) self.clearButton.triggered.connect(self.shellOut.clearConsole) self.optionsButton.triggered.connect(self.openSettings) self.loadProcessingButton.triggered.connect(self.processing) self.loadQtCoreButton.triggered.connect(self.qtCore) self.loadQtGuiButton.triggered.connect(self.qtGui) self.runButton.triggered.connect(self.shell.entered) self.openFileButton.triggered.connect(self.openScriptFile) self.openInEditorButton.triggered.connect(self.openScriptFileExtEditor) self.saveFileButton.triggered.connect(self.saveScriptFile) self.saveAsFileButton.triggered.connect(self.saveAsScriptFile) self.helpButton.triggered.connect(self.openHelp) self.connect(self.listClassMethod, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), self.onClickGoToLine) self.lineEditFind.returnPressed.connect(self._findText) self.findNextButton.clicked.connect(self._findNext) self.findPrevButton.clicked.connect(self._findPrev) self.lineEditFind.textChanged.connect(self._textFindChanged) def _findText(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findNext(self): self.tabEditorWidget.currentWidget().newEditor.findText(True) def _findPrev(self): self.tabEditorWidget.currentWidget().newEditor.findText(False) def _textFindChanged(self): if self.lineEditFind.text(): self.findNextButton.setEnabled(True) self.findPrevButton.setEnabled(True) else: self.lineEditFind.setStyleSheet('') self.findNextButton.setEnabled(False) self.findPrevButton.setEnabled(False) def onClickGoToLine(self, item, column): tabEditor = self.tabEditorWidget.currentWidget().newEditor if item.text(1) == 'syntaxError': check = tabEditor.syntaxCheck(fromContextMenu=False) if check and not tabEditor.isReadOnly(): self.tabEditorWidget.currentWidget().save() return linenr = int(item.text(1)) itemName = str(item.text(0)) charPos = itemName.find(' ') if charPos != -1: objName = itemName[0:charPos] else: objName = itemName tabEditor.goToLine(objName, linenr) def processing(self): self.shell.commandConsole('processing') def qtCore(self): self.shell.commandConsole('qtCore') def qtGui(self): self.shell.commandConsole('qtGui') def toggleEditor(self, checked): self.splitterObj.show() if checked else self.splitterObj.hide() if not self.tabEditorWidget: self.tabEditorWidget.enableToolBarEditor(checked) self.tabEditorWidget.restoreTabsOrAddNew() def toggleObjectListWidget(self, checked): self.listClassMethod.show() if checked else self.listClassMethod.hide() def findTextEditor(self, checked): self.widgetFind.show() if checked else self.widgetFind.hide() def pasteEditor(self): self.tabEditorWidget.currentWidget().newEditor.paste() def cutEditor(self): self.tabEditorWidget.currentWidget().newEditor.cut() def copyEditor(self): self.tabEditorWidget.currentWidget().newEditor.copy() def runScriptEditor(self): self.tabEditorWidget.currentWidget().newEditor.runScriptCode() def commentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(True) def uncommentCode(self): self.tabEditorWidget.currentWidget().newEditor.commentEditorCode(False) def openScriptFileExtEditor(self): tabWidget = self.tabEditorWidget.currentWidget() path = tabWidget.path import subprocess try: subprocess.Popen([os.environ['EDITOR'], path]) except KeyError: QDesktopServices.openUrl(QUrl.fromLocalFile(path)) def openScriptFile(self): lastDirPath = self.settings.value("pythonConsole/lastDirPath", QDir.homePath()) openFileTr = QCoreApplication.translate("PythonConsole", "Open File") fileList = QFileDialog.getOpenFileNames( self, openFileTr, lastDirPath, "Script file (*.py)") if fileList: for pyFile in fileList: for i in range(self.tabEditorWidget.count()): tabWidget = self.tabEditorWidget.widget(i) if tabWidget.path == pyFile: self.tabEditorWidget.setCurrentWidget(tabWidget) break else: tabName = QFileInfo(pyFile).fileName() self.tabEditorWidget.newTabEditor(tabName, pyFile) lastDirPath = QFileInfo(pyFile).path() self.settings.setValue("pythonConsole/lastDirPath", pyFile) self.updateTabListScript(pyFile, action='append') def saveScriptFile(self): tabWidget = self.tabEditorWidget.currentWidget() try: tabWidget.save() except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) def saveAsScriptFile(self, index=None): tabWidget = self.tabEditorWidget.currentWidget() if not index: index = self.tabEditorWidget.currentIndex() if not tabWidget.path: fileName = self.tabEditorWidget.tabText(index) + '.py' folder = self.settings.value("pythonConsole/lastDirPath", QDir.home()) pathFileName = os.path.join(folder, fileName) fileNone = True else: pathFileName = tabWidget.path fileNone = False saveAsFileTr = QCoreApplication.translate("PythonConsole", "Save File As") filename = QFileDialog.getSaveFileName(self, saveAsFileTr, pathFileName, "Script file (*.py)") if filename: try: tabWidget.save(filename) except (IOError, OSError) as error: msgText = QCoreApplication.translate('PythonConsole', 'The file <b>{0}</b> could not be saved. Error: {1}').format(tabWidget.path, error.strerror) self.callWidgetMessageBarEditor(msgText, 2, False) if fileNone: tabWidget.path = None else: tabWidget.path = pathFileName return if not fileNone: self.updateTabListScript(pathFileName, action='remove') def openHelp(self): QgsContextHelp.run("PythonConsole") def openSettings(self): if optionsDialog(self).exec_(): self.shell.refreshSettingsShell() self.shellOut.refreshSettingsOutput() self.tabEditorWidget.refreshSettingsEditor() def callWidgetMessageBar(self, text): self.shellOut.widgetMessageBar(iface, text) def callWidgetMessageBarEditor(self, text, level, timed): self.tabEditorWidget.widgetMessageBar(iface, text, level, timed) def updateTabListScript(self, script, action=None): if action == 'remove': self.tabListScript.remove(script) elif action == 'append': if not self.tabListScript: self.tabListScript = [] if script not in self.tabListScript: self.tabListScript.append(script) else: self.tabListScript = [] self.settings.setValue("pythonConsole/tabScripts", self.tabListScript) def saveSettingsConsole(self): self.settings.setValue("pythonConsole/splitterConsole", self.splitter.saveState()) self.settings.setValue("pythonConsole/splitterObj", self.splitterObj.saveState()) self.settings.setValue("pythonConsole/splitterEditor", self.splitterEditor.saveState()) self.shell.writeHistoryFile(True) def restoreSettingsConsole(self): storedTabScripts = self.settings.value("pythonConsole/tabScripts", []) self.tabListScript = storedTabScripts self.splitter.restoreState(self.settings.value("pythonConsole/splitterConsole", QByteArray())) self.splitterEditor.restoreState(self.settings.value("pythonConsole/splitterEditor", QByteArray())) self.splitterObj.restoreState(self.settings.value("pythonConsole/splitterObj", QByteArray()))
class MainWindow(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