def __init__(self): QObject.__init__(self) self._createdActions = [] self._createdMenus = [] self._currentDocument = core.workspace().currentDocument() # probably None model = core.actionManager() for menu in _MENUS: if menu[2]: menuObj = model.addMenu(menu[0], menu[1], QIcon(':/enkiicons/' + menu[2])) else: menuObj = model.addMenu(menu[0], menu[1]) menuObj.setEnabled(False) self._createdMenus.append(menuObj) for command, path, text, shortcut, icon in _ACTIONS: actObject = QAction(text, self) if shortcut: actObject.setShortcut(shortcut) if icon: actObject.setIcon(QIcon(':/enkiicons/' + icon)) actObject.setData(command) actObject.setEnabled(False) actObject.triggered.connect(self.onAction) model.addAction(path, actObject) self._createdActions.append(actObject) core.workspace().currentDocumentChanged.connect(self.onCurrentDocumentChanged)
def hide(self): """Reimplemented function. Sends signal, returns focus to workspace """ super(SearchWidget, self).hide() core.workspace().focusCurrentDocument() self.visibilityChanged.emit(self.isVisible())
def test_logWindowSplitter4(self): """User actively hide log window, Enki should be able to remember this. """ document1 = self.createFile('file1.rst', '.. file1::') document2 = self.createFile('file2.rst', '') document3 = self.createFile('file3.rst', '.. file3::') self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document1)) # Wait for events to process. See qWait comment above. QTest.qWait(100) # User manually change error state splitter size such that log window # is hidden. self._widget().splitter.setSizes([1, 0]) self._widget().splitter.splitterMoved.emit(1, 1) # Switch to document 2. Log window is hidden now. self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document2)) # Wait for events to process. See qWait comment above. QTest.qWait(100) self.assertFalse(self._widget().splitter.sizes()[1]) # Switch to document 3. Log window should keep hidden. self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document3)) # Wait for events to process. See qWait comment above. QTest.qWait(100) self.assertFalse(self._widget().splitter.sizes()[1])
def test_previewCheck2b(self): """Check for double builds. """ self._doBasicSphinxConfig() webViewContent, logContent = self._doBasicSphinxTest('rst') # After the inital ``_clear`` then a build with text, we expect to # see two builds. self.assertEqual(self._dock()._sphinxConverter._SphinxInvocationCount, 2) # Inserting a character when auto-save is enabled can cause a double # build: the save made in preparation for the first build also invokes # the second build. qp = core.workspace().currentDocument().qutepart core.config()['Sphinx']['BuildOnSave'] = False with self._WaitForHtmlReady(timeout=10000, numEmittedExpected=1): qp.lines[0] += ' ' self.assertEqual(self._dock()._sphinxConverter._SphinxInvocationCount, 3) # Inserting a space at the end of the line can cause a double build, # since the StripTrailingWhitespace option deletes the space, then # the auto-save and build code restores it. # # However, double builds still only produce a single ``loadFinished`` # signal. core.config()["Qutepart"]["StripTrailingWhitespace"] = True qp = core.workspace().currentDocument().qutepart with self._WaitForHtmlReady(timeout=10000, numEmittedExpected=1): qp.appendPlainText('\nTesting...') self.assertEqual(self._dock()._sphinxConverter._SphinxInvocationCount, 4)
def test_logWindowSplitter2(self): """Feature 2. All build-with-error files' splitter size are connected. """ document1 = self.createFile('file1.rst', '.. file1::') document2 = self.createFile('file2.rst', '.. file2::') self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document2)) # Change splitter location of document 2. newSplitterSize = [124, 123] self._widget().splitter.setSizes(newSplitterSize) # Calling setSizes directly will not trigger splitter's ``splitterMoved`` # signal. We need to manually emit this signal with two arguments (not # important here.) self._widget().splitter.splitterMoved.emit(newSplitterSize[0], 1) # Assert preview window and log window are visible and are of almost equal size self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10) # Switch to document 1, make sure its splitter size is changed, too. self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document1)) self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10)
def test_logWindowSplitter3a(self): """Feature 1,2,3. A combination of the above test cases. """ document1 = self.createFile('file1.rst', '.. file1::') document2 = self.createFile('file2.rst', '') document3 = self.createFile('file3.rst', '.. file3::') self._assertHtmlReady(lambda: None) self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document1)) # Wait for events to process. See qWait comment above. QTest.qWait(100) # Change splitter setting of document 1. newSplitterSize = [125, 124] self._widget().splitter.setSizes(newSplitterSize) self._widget().splitter.splitterMoved.emit(newSplitterSize[0], 1) # Assert log window and preview window are visible and are of almost # equal size. self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10) # Switch to an error-free document, assert log window hidden. self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document2)) # Wait for events to process. See qWait comment above. QTest.qWait(100) self.assertFalse(self._widget().splitter.sizes()[1]) # Switch to file3 which will cause build error, check splitter size. self._assertHtmlReady( lambda: core.workspace().setCurrentDocument(document3)) self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10)
def _searchWord(self, forward=True): """Do search in file operation. Will select next found item if updateWidget is True, search widget line edit will color will be set according to result """ document = core.workspace().currentDocument() word, wordStartAbsPos, wordEndAbsPos = document.wordUnderCursor() if word is None: return regExp = re.compile('\\b%s\\b' % re.escape(word)) text = document.text() # avoid matching word under cursor if forward: startPoint = wordEndAbsPos else: startPoint = wordStartAbsPos match, matches = self._searchInText(regExp, document.text(), startPoint, forward) if match is not None: document.goTo(absPos = match.start(), selectionLength = len(match.group(0))) core.mainWindow().statusBar().showMessage('Match %d of %d' % \ (matches.index(match) + 1, len(matches)), 3000) else: self._resetSelection(core.workspace().currentDocument())
def test_4(self): # dock remembers its Enabled/Disabled state ruby = self.createFile('source.rb', RUBY_SOURCE) txt = self.createFile('file.txt', "asdf") dock = self.findDock('&Navigator') core.workspace().setCurrentDocument(ruby) self.retryUntilPassed(200, lambda: self.assertTrue(dock.isVisible())) self.keyClicks('N', Qt.AltModifier) self.keyClick(Qt.Key_Escape) self.assertFalse(dock.isVisible()) self.assertFalse(core.config()['Navigator']['Enabled']) core.workspace().setCurrentDocument(txt) core.workspace().setCurrentDocument(ruby) self.assertFalse(dock.isVisible()) self.keyClicks('N', Qt.AltModifier) self.assertTrue(dock.isVisible()) self.assertTrue(core.config()['Navigator']['Enabled']) core.workspace().setCurrentDocument(txt) core.workspace().setCurrentDocument(ruby) self.assertTrue(dock.isVisible())
def execute(self): path = self._clickedPath fullPath = os.path.join(core.project().path(), path) if self._line is None: core.workspace().goTo(fullPath) else: core.workspace().goTo(fullPath, line=self._line - 1)
def _saveSession(self, showWarnings=True): """Enki is going to be terminated. Save session """ fileList = [ document.filePath() for document in core.workspace().documents() if document.filePath() is not None and os.path.exists( document.filePath()) and not '/.git/' in document.filePath() and not (document.fileName().startswith('svn-commit') and document.fileName().endswith('.tmp')) ] if not fileList: return currentPath = None if core.workspace().currentDocument() is not None: currentPath = core.workspace().currentDocument().filePath() session = { 'current': currentPath, 'opened': fileList, 'project': core.project().path() } enki.core.json_wrapper.dump(_SESSION_FILE_PATH, 'session', session, showWarnings)
def execute(self): """Execute the command """ if self._isGlob(self._path): expandedPathes = [] for path in glob.iglob(os.path.expanduser(self._path)): try: path = os.path.abspath(path) except OSError: pass expandedPathes.append(path) # 2 loops, because we should open absolute pathes. When opening files, enki changes its current directory for path in expandedPathes: if self._line is None: core.workspace().goTo(path) else: core.workspace().goTo(path, line=self._line - 1) else: # file may be not existing path = os.path.expanduser(self._path) if os.path.isfile(path): path = os.path.abspath(path) if self._line is None: core.workspace().goTo(path) else: core.workspace().goTo(path, line=self._line - 1) else: core.workspace().createEmptyNotSavedDocument(path)
def setData(self, index, value, role=Qt.EditRole): document = self.document(index) newPath = value if newPath == document.filePath(): return False if newPath == '/dev/null': try: os.remove(document.filePath()) except (OSError, IOError) as ex: QMessageBox.critical(core.mainWindow(), 'Not this time', 'The OS thinks it needs the file') return False core.workspace().closeDocument(document) else: try: os.rename(document.filePath(), newPath) except (OSError, IOError) as ex: QMessageBox.critical(core.mainWindow(), 'Failed to rename file', str(ex)) return False else: document.setFilePath(newPath) document.saveFile() self.dataChanged.emit(index, index) return True
def __init__(self, plugin): QFrame.__init__(self, core.workspace()) self._mode = None self.plugin = plugin from PyQt4 import uic # lazy import for better startup performance uic.loadUi(os.path.join(os.path.dirname(__file__), "SearchWidget.ui"), self) self.cbSearch.setCompleter(None) self.cbReplace.setCompleter(None) self.cbMask.setCompleter(None) self.fsModel = QDirModel(self.cbPath.lineEdit()) self.fsModel.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot) self.cbPath.lineEdit().setCompleter(QCompleter(self.fsModel, self.cbPath.lineEdit())) # TODO QDirModel is deprecated but QCompleter does not yet handle # QFileSystemodel - please update when possible.""" self.cbSearch.setCompleter(None) self.pbSearchStop.setVisible(False) self.pbReplaceCheckedStop.setVisible(False) self._progress = QProgressBar(self) self._progress.setAlignment(Qt.AlignCenter) self._progress.setToolTip(self.tr("Search in progress...")) self._progress.setMaximumSize(QSize(80, 16)) core.mainWindow().statusBar().insertPermanentWidget(1, self._progress) self._progress.setVisible(False) # cd up action self.tbCdUp = QToolButton(self.cbPath.lineEdit()) self.tbCdUp.setIcon(QIcon(":/enkiicons/go-up.png")) self.tbCdUp.setCursor(Qt.ArrowCursor) self.tbCdUp.installEventFilter(self) # for drawing button self.cbSearch.installEventFilter(self) # for catching Tab and Shift+Tab self.cbReplace.installEventFilter(self) # for catching Tab and Shift+Tab self.cbPath.installEventFilter(self) # for catching Tab and Shift+Tab self.cbMask.installEventFilter(self) # for catching Tab and Shift+Tab self._closeShortcut = QShortcut(QKeySequence("Esc"), self) self._closeShortcut.setContext(Qt.WidgetWithChildrenShortcut) self._closeShortcut.activated.connect(self.hide) # connections self.cbSearch.lineEdit().textChanged.connect(self._onSearchRegExpChanged) self.cbSearch.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbReplace.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbPath.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbMask.lineEdit().returnPressed.connect(self._onReturnPressed) self.cbRegularExpression.stateChanged.connect(self._onSearchRegExpChanged) self.cbCaseSensitive.stateChanged.connect(self._onSearchRegExpChanged) self.tbCdUp.clicked.connect(self._onCdUpPressed) core.mainWindow().hideAllWindows.connect(self.hide) core.workspace().currentDocumentChanged.connect( lambda old, new: self.setVisible(self.isVisible() and new is not None) )
def terminate(self): """Explicitly called destructor """ self._cleanupActions() core.workspace().documentClosed.disconnect(self._onDocumentClosed) core.actionManager().removeAction(self._undoClose) enki.core.json_wrapper.dump(_FILE_PATH, 'recent file', self._recent)
def terminate(self): """Uninstall the plugin """ core.actionManager().removeAction('mTools/aSetSphinxPath') if self._dockInstalled: self._removeDock() if self._dock is not None: self._dock.terminate() core.workspace().currentDocumentChanged.disconnect( self._onDocumentChanged) core.workspace().languageChanged.disconnect(self._onDocumentChanged) core.uiSettingsManager().aboutToExecute.disconnect( self._onSettingsDialogAboutToExecute) core.uiSettingsManager().dialogAccepted.disconnect( self._onDocumentChanged) core.uiSettingsManager().dialogAccepted.disconnect( self._setSphinxActionVisibility) core.project().changed.disconnect(self.onFileBrowserPathChanged) if self._dock: self._dock.closed.disconnect(self._onDockClosed) self._dock.shown.disconnect(self._onDockShown) if haveWebkit: self._saveAction.triggered.disconnect(self._dock.onPreviewSave)
def _onRestoreSession(self): """Enki initialisation finished. Now restore session """ # if have documents except 'untitled' new doc, don't restore session if core.workspace().currentDocument() is not None: return if not os.path.exists(_SESSION_FILE_PATH): return session = enki.core.json_wrapper.load(_SESSION_FILE_PATH, 'session', None) if session is not None: for filePath in session['opened']: if os.path.exists(filePath): core.workspace().openFile(filePath) if session['current'] is not None: document = self._documentForPath(session['current']) if document is not None: # document might be already deleted core.workspace().setCurrentDocument(document) if 'project' in session: path = session['project'] if path is not None and os.path.isdir(path): core.project().open(path)
def __init__(self): DockWidget.__init__(self, core.mainWindow(), "&Preview", QIcon(':/enkiicons/internet.png'), "Alt+P") from PyQt4.QtWebKit import QWebView # delayed import, startup performance optimization self._view = QWebView(self) self._view.page().mainFrame().titleChanged.connect(self._updateTitle) self.setWidget(self._view) self.setFocusProxy(self._view) core.workspace().currentDocumentChanged.connect(self._onDocumentChanged) core.workspace().textChanged.connect(self._onTextChanged) self._scrollPos = {} self._vAtEnd = {} self._hAtEnd = {} self._thread = ConverterThread() self._thread.htmlReady.connect(self._setHtml) self._visiblePath = None # If we update Preview on every key pressing, freezes are sensible (GUI thread draws preview too slowly # This timer is used for drawing Preview 300 ms After user has stopped typing text self._typingTimer = QTimer() self._typingTimer.setInterval(300) self._typingTimer.timeout.connect(self._scheduleDocumentProcessing) self._scheduleDocumentProcessing()
def test_previewCheck23(self): """If the document is modified externally, then build on save will be automatically enabled. Calling scheduledocumentprocessing will not trigger a rebuild. """ self._doBasicSphinxConfig() core.config()['Sphinx']['BuildOnSave'] = False core.config().flush() self.codeText = """**** head **** """ self.masterText = """.. toctree:: code.rst""" codeDoc = self.createFile('code.rst', self.testText) masterDoc = self.createFile('index.rst', self.testText) self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(codeDoc), timeout=10000) # Modify this file externally. with open("code.rst", 'a') as f: f.write(".. mytag::") self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(masterDoc), timeout=10000) core.workspace().setCurrentDocument(codeDoc) # Modify this file internally, then wait for the typing timer to expire. qp = core.workspace().currentDocument().qutepart self.assertEmits(lambda: qp.appendPlainText('xxx'), self._dock()._typingTimer.timeout, timeoutMs=1000) # The typing timer invokes _scheduleDocumentProcessing. Make sure # it completes by waiting until all events are processed. base._processPendingEvents() # Make sure the file wasn't saved. self.assertTrue(qp.document().isModified())
def __init__(self): """Create and install the plugin """ QObject.__init__(self) self._action = None core.workspace().currentDocumentChanged.connect(self._updateAction) core.workspace().languageChanged.connect(self._updateAction)
def test_previewCheck18(self): """Switching between different files should update the log window accordingly. """ core.config()['CodeChat']['Enabled'] = True # First create a warning only test case, document1 = self.createFile('file1.py', '# `<>_') # then an error only case, document2 = self.createFile('file2.py', '# .. h::') # then an error free case. Wait for the HTML to be generated before # continuing, so that the next assertHtmlReady won't accidentally catch # the HTML ready generated here. with self._WaitForHtmlReady(): document3 = self.createFile('file3.py', '# <>_') base.waitForSignal(lambda: None, self._widget().webView.page().mainFrame().loadFinished, 200) # switch to document 1 self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document1)) base.waitForSignal(lambda: None, self._widget().webView.page().mainFrame().loadFinished, 200) ps = self._widget().prgStatus self.assertIn('#FF9955', ps.styleSheet()) self.assertIn('Error(s): 0, warning(s): 1', ps.text()) # switch to document 2 self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document2)) base.waitForSignal(lambda: None, self._widget().webView.page().mainFrame().loadFinished, 200) self.assertIn('red', ps.styleSheet()) self.assertIn('Error(s): 1, warning(s): 0', ps.text()) # switch to document 3 self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document3)) base.waitForSignal(lambda: None, self._widget().webView.page().mainFrame().loadFinished, 200) self.assertEqual(self._widget().prgStatus.styleSheet(), 'QLabel {}') self.assertEqual(self._logText(), '')
def __init__(self, *args): DockWidget.__init__(self, *args) self.setObjectName("PreviewDock") self.setWindowTitle(self.tr( "&Preview" )) self.setWindowIcon(QIcon(':/enkiicons/internet.png')) self.showAction().setShortcut("Alt+P") from PyQt4.QtWebKit import QWebView # delayed import, startup performance optimization self._view = QWebView(self) self._view.page().mainFrame().titleChanged.connect(self._updateTitle) self.setWidget(self._view) self.setFocusProxy(self._view) core.workspace().currentDocumentChanged.connect(self._onDocumentChanged) core.workspace().textChanged.connect(self._onTextChanged) self._scrollPos = {} self._vAtEnd = {} self._hAtEnd = {} self._thread = ConverterThread() self._thread.htmlReady.connect(self._setHtml) self._visiblePath = None self._onDocumentChanged(None, core.workspace().currentDocument())
def _searchWord(self, forward): """Do search in file operation. Will select next found item if updateWidget is True, search widget line edit will color will be set according to result """ document = core.workspace().currentDocument() cursor = document.qutepart.textCursor() if not cursor.hasSelection(): cursor.select(cursor.WordUnderCursor) word = cursor.selectedText() wordStartAbsPos = cursor.anchor() wordEndAbsPos = cursor.position() if not word: return regExp = re.compile('\\b%s\\b' % re.escape(word)) text = document.qutepart.text # avoid matching word under cursor if forward: startPoint = wordEndAbsPos else: startPoint = wordStartAbsPos self._updateFoundItemsHighlighting(regExp) match, matches = self._searchInText(regExp, document.qutepart.text, startPoint, forward) if match is not None: document.qutepart.absSelectedPosition = (match.start(), match.start() + len(match.group(0))) core.mainWindow().statusBar().showMessage('Match %d of %d' % \ (matches.index(match) + 1, len(matches)), 3000) else: core.workspace().currentDocument().qutepart.resetSelection()
def _onRename(self): """Handler for File->File System->Rename""" document = core.workspace().currentDocument() if document.qutepart.document().isModified() or \ document.isExternallyModified() or \ document.isExternallyRemoved() or \ document.isNeverSaved(): QMessageBox.warning(core.mainWindow(), 'Rename file', 'Save the file before renaming') return newPath, ok = QInputDialog.getText(core.mainWindow(), 'Rename file', 'New file name', text=document.filePath()) if not ok: return if newPath == document.filePath(): return if newPath == '/dev/null': try: os.remove(document.filePath()) except (OSError, IOError) as ex: QMessageBox.critical(core.mainWindow(), 'Not this time', 'The OS thinks it needs the file') else: core.workspace().closeDocument(document) else: try: os.rename(document.filePath(), newPath) except (OSError, IOError) as ex: QMessageBox.critical(core.mainWindow(), 'Failed to rename file', str(ex)) else: document.setFilePath(newPath) document.saveFile()
def execute(self): """Execute the command """ if self._isGlob(self._path): expandedPathes = [] for path in glob.iglob(os.path.expanduser(self._path)): try: path = os.path.abspath(path) except OSError: pass expandedPathes.append(path) # 2 loops, because we should open absolute pathes. When opening files, enki changes its current directory for path in expandedPathes: if self._line is None: core.workspace().goTo(path) else: core.workspace().goTo(path, line = self._line - 1) else: # file may be not existing path = os.path.expanduser(self._path) if os.path.isfile(path): path = os.path.abspath(path) if self._line is None: core.workspace().goTo(path) else: core.workspace().goTo(path, line = self._line - 1) else: core.workspace().createEmptyNotSavedDocument(path)
def _createSearchWidget(self): """ Create search widget. Called only when user requested it first time """ from . import searchwidget self._widget = searchwidget.SearchWidget(self) self._widget.searchInDirectoryStartPressed.connect(self._onSearchInDirectoryStartPressed) self._widget.searchInDirectoryStopPressed.connect(self._onSearchInDirectoryStopPressed) self._widget.replaceCheckedStartPressed.connect(self._onReplaceCheckedStartPressed) self._widget.replaceCheckedStopPressed.connect(self._onReplaceCheckedStopPressed) self._widget.visibilityChanged.connect(self._updateSearchWidgetFoundItemsHighlighting) self._widget.searchRegExpChanged.connect(self._updateFileActionsState) self._widget.searchRegExpChanged.connect(self._onRegExpChanged) self._widget.searchRegExpChanged.connect(self._updateSearchWidgetFoundItemsHighlighting) self._widget.searchNext.connect(self._onSearchNext) self._widget.searchPrevious.connect(self._onSearchPrevious) self._widget.replaceFileOne.connect(self._onReplaceFileOne) self._widget.replaceFileAll.connect(self._onReplaceFileAll) core.workspace().currentDocumentChanged.connect(self._updateFileActionsState) # always disabled, if no widget core.workspace().textChanged.connect(self._updateSearchWidgetFoundItemsHighlighting) core.mainWindow().centralLayout().addWidget(self._widget) self._widget.setVisible(False) self._updateFileActionsState()
def __init__(self): QObject.__init__(self) self._createdActions = [] self._createdSeparators = [] self._createdMenus = [] self._currentDocument = core.workspace().currentDocument() # probably None for menu in _MENUS: if menu[2]: menuObj = core.actionManager().addMenu(menu[0], menu[1], QIcon(':/enkiicons/' + menu[2])) else: menuObj = core.actionManager().addMenu(menu[0], menu[1]) menuObj.setEnabled(False) self._createdMenus.append(menuObj) for item in _ACTIONS: if isinstance(item, tuple): # action command, path, text, shortcut, icon = item actObject = QAction(text, self) if shortcut: actObject.setShortcut(shortcut) if icon: actObject.setIcon(QIcon(':/enkiicons/' + icon)) actObject.setData(command) actObject.setEnabled(False) actObject.triggered.connect(self.onAction) core.actionManager().addAction(path, actObject) self._createdActions.append(actObject) else: # separator menuPath = item menu = core.actionManager().menu(menuPath) self._createdSeparators.append(menu.addSeparator()) core.workspace().currentDocumentChanged.connect(self.onCurrentDocumentChanged)
def test_logWindowSplitter3a(self): """Feature 1,2,3. A combination of the above test cases. """ document1 = self.createFile('file1.rst', '.. file1::') document2 = self.createFile('file2.rst', '') document3 = self.createFile('file3.rst', '.. file3::') self._assertHtmlReady(lambda: None) self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document1)) # Wait for events to process. See qWait comment above. QTest.qWait(100) # Change splitter setting of document 1. newSplitterSize = [125, 124] self._widget().splitter.setSizes(newSplitterSize) self._widget().splitter.splitterMoved.emit(newSplitterSize[0], 1) # Assert log window and preview window are visible and are of almost # equal size. self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10) # Switch to an error-free document, assert log window hidden. self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document2)) # Wait for events to process. See qWait comment above. QTest.qWait(100) self.assertFalse(self._widget().splitter.sizes()[1]) # Switch to file3 which will cause build error, check splitter size. self._assertHtmlReady(lambda: core.workspace().setCurrentDocument(document3)) self.assertNotIn(0, self._widget().splitter.sizes()) self.assertAlmostEqual(self._widget().splitter.sizes()[0], self._widget().splitter.sizes()[1], delta=10)
def __init__(self, *args): QLabel.__init__(self, *args) self.setMinimumWidth(QFontMetrics(self.font()).width("Xreplace charX")) self.setAlignment(Qt.AlignCenter) core.workspace().currentDocumentChanged.connect(self._onCurrentDocumentChanged)
def main(): cmdLine = _parseCommandLine() profiler = _StartProfiler(cmdLine["profiling"]) try: _checkDependencies(profiler) except ImportError: sys.exit(-1) # Imports only here. Hack for ability to get help and version info even on system without PyQt. import PyQt5.QtGui import qutepart logging.basicConfig(level=logging.ERROR) logging.getLogger('qutepart').removeHandler(qutepart.consoleHandler) sys.excepthook = excepthook app = PyQt5.QtWidgets.QApplication(sys.argv) app.setApplicationName(enki.core.defines.PACKAGE_NAME) app.setOrganizationName(enki.core.defines.PACKAGE_ORGANISATION) app.setOrganizationDomain(enki.core.defines.PACKAGE_URL) app.lastWindowClosed.connect(app.quit) profiler.stepDone('Construct application') # init the core from enki.core.core import core core.init(profiler, cmdLine) _openFiles(core, cmdLine, profiler) profiler.stepDone('Open files') if core.workspace().currentDocument(): core.workspace().currentDocument().setFocus() core.mainWindow().loadState() profiler.stepDone('Load state') core.mainWindow().show() profiler.stepDone('Show main window') # execute application if profiler.enabled: core.workspace().forceCloseAllDocuments() result = 0 else: result = app.exec_() core.term() profiler.printInfo() profiler.stepDone('Terminate core') return result
def __init__(self, *args): QLabel.__init__(self, *args) self.setMinimumWidth(QFontMetrics(self.font()).width("Xreplace charX")) self.setAlignment(Qt.AlignCenter) core.workspace().currentDocumentChanged.connect( self._onCurrentDocumentChanged)
def _deactivate(self): """Destroy the dialog, remove actions from the main menu.""" self._fileswitcher = None self._removeActions() core.workspace().documentOpened.disconnect( self._onDocumentOpenedOrClosed) core.workspace().documentClosed.disconnect( self._onDocumentOpenedOrClosed)
def terminate(self): if self._timer.isActive(): self._timer.stop() core.workspace().currentDocumentChanged.disconnect( self._onCurrentDocumentChanged) core.workspace().cursorPositionChanged.disconnect( self._onCursorPositionChanged)
def _onFileOpenTriggered(self): """Handler of File->Open """ fileNames = QFileDialog.getOpenFileNames( core.mainWindow(), self.tr( "Classic open dialog. Main menu -> Navigation -> Locator is better" )) for path in fileNames: core.workspace().openFile(path)
def del_(self): """Uninstall the plugin """ core.workspace().currentDocumentChanged.disconnect(self._updateAction) core.workspace().languageChanged.disconnect(self._updateAction) if self._action is not None: core.actionManager().removeAction(self._action) del self._action
def test_same_path(self): core.workspace().openFile(self.EXISTING_FILE) _startEditCurrentFilePath() self.keyClicks(self.EXISTING_FILE) self.keyClick(Qt.Key_Return) self.assertEqual(QApplication.instance().activeWindow(), core.mainWindow()) # not messagebox with error
def __init__(self): QObject.__init__(self) core.workspace().currentDocumentChanged.connect( self._onCurrentDocumentChanged) document = core.workspace().currentDocument() if document: document.qutepart.installEventFilter(self)
def terminate(self): """Uninstall the plugin """ core.workspace().currentDocumentChanged.disconnect(self._updateAction) core.workspace().languageChanged.disconnect(self._updateAction) if self._action is not None: core.actionManager().removeAction(self._action) del self._action
def _applySettings(self): if core.config()['Lint']['Python']['Enabled']: self._install() if self._isSupported(core.workspace().currentDocument()): self._processDocument(core.workspace().currentDocument()) else: self._uninstall() for document in core.workspace().documents(): document.qutepart.lintMarks = {}
def execute(self): """Execute the command """ for path in glob.iglob(os.path.expanduser(self._path)): path = os.path.abspath(path) if self._line is None: core.workspace().goTo(path) else: core.workspace().goTo(path, line = self._line - 1)
def _onRegExpChanged(self, regExp): """Search regExp changed. Do incremental search """ if self._mode in (MODE_SEARCH, MODE_REPLACE) and \ core.workspace().currentDocument() is not None: if regExp.pattern: self._searchFile(forward=True, incremental=True ) else: # Clear selection core.workspace().currentDocument().qutepart.resetSelection()
def __init__(self, parent): QToolButton.__init__(self, parent) self.setToolTip(self.tr("Cursor position")) self.setEnabled(False) self._setCursorPosition(-1, -1) minWidth = QFontMetrics(self.font()).width("Line: xxxxx Column: xxx") minWidth += 30 # for the button borders self.setMinimumWidth(minWidth) # Avoid flickering when text width changed core.workspace().currentDocumentChanged.connect(self._onCurrentDocumentChanged)
def _onRegExpChanged(self, regExp): """Search regExp changed. Do incremental search """ if self._mode in (MODE_SEARCH, MODE_REPLACE) and \ core.workspace().currentDocument() is not None: if regExp.pattern: self._searchFile(forward=True, incremental=True) else: # Clear selection core.workspace().currentDocument().qutepart.resetSelection()
def _applySettings(self): if core.config()['Lint']['Python']['Enabled']: self._install() if core.workspace().currentDocument() is not None: self._processDocument(core.workspace().currentDocument()) else: self._uninstall() for document in core.workspace().documents(): document.qutepart.lintMarks = {}
def tearDown(self): self._finished = True for document in core.workspace().documents(): document.qutepart.text = '' # clear modified flag, avoid Save Files dialog core.workspace().closeAllDocuments() core.term() _processPendingEvents() self._cleanUpFs()
def blockingFunc(): try: core.workspace().forceCloseAllDocuments() core.term() finally: try: QApplication.instance().processEvents() except: pass QApplication.instance().quit()
def execute(self): """Execute command """ try: path = os.path.abspath(os.path.expanduser(self._path)) except OSError: # directory deleted return core.workspace().currentDocument().setFilePath(path) core.workspace().currentDocument().saveFile()
def test_6(self): """Test _firstLetterShortcut.""" # To access this function, create a dummy document so we can pull # up its containing dialog. self.createFile('file1.rb', 'asdf\nfdsa') uis = _UISaveFiles(core.workspace(), core.workspace().documents()) # Label one of the dialog buttons. s = uis._firstLetterShortcut(uis.buttonBox.Discard, 'Does &This work') self.assertEquals(s.key(), QKeySequence("T"))
def __init__(self): QMessageBox.information(core.mainWindow(), "Hello, world", "Plugin loaded") self._addAction() self._createDock() self._readSettings() core.workspace().currentDocumentChanged.connect(self._onDocumentChanged) core.uiSettingsManager().dialogAccepted.connect(self._applySettings) core.uiSettingsManager().aboutToExecute.connect(self._onSettingsDialogAboutToExecute)
def _openFiles(core, cmdLine, profiler): existingFiles = [] notExistingFiles = [] dirs = [] for filePath in cmdLine["files"]: if os.path.exists(filePath): if os.path.isdir(filePath): dirs.append(filePath) else: existingFiles.append(filePath) else: notExistingFiles.append(filePath) # open file by path and line number if "firstFileLineToGo" in cmdLine and \ len(existingFiles) == 1: line = cmdLine["firstFileLineToGo"] - 1 # convert from users to internal indexing core.workspace().goTo(existingFiles[0], line=line) elif existingFiles or notExistingFiles: core.workspace().openFiles(existingFiles) for filePath in notExistingFiles: core.workspace().createEmptyNotSavedDocument(filePath) elif dirs: try: os.chdir(dirs[0]) except: pass else: if not cmdLine["no-session"]: core.restoreSession.emit() profiler.stepDone('Restore session') if core.workspace().currentDocument() is None: core.workspace().createEmptyNotSavedDocument()
def __init__(self): QObject.__init__(self) self._recentFileActions = [] self._recent = enki.core.json_wrapper.load(_FILE_PATH, 'recent file list', []) self._undoClose = core.actionManager().addAction("mFile/mUndoClose/aUndoClose", "Undo close", shortcut = 'Shift+Ctrl+U') core.workspace().documentClosed.connect(self._onDocumentClosed) self._undoClose.triggered.connect(self._onUndoClose) menu = core.actionManager().action("mFile/mUndoClose").menu() menu.aboutToShow.connect(self._onMenuAboutToShow)
def _onActivated(self, idx): """File or directory doubleClicked """ index = self._filteredModel.mapToSource(idx) path = self._dirsModel.filePath(index) if os.path.isdir(path): self._fileBrowser.setCurrentPath(path) else: self._fileActivated.emit() core.workspace().openFile(path)