PK|GfHh\\QProgEdit/_qlangmenu.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from qtpy import QtGui, QtCore, QtWidgets from QProgEdit.py3compat import * from QProgEdit import QEditorConst class QLangMenu(QtWidgets.QMenu): """ desc: The language selection menu. """ def __init__(self, tabCornerWidget): """ desc: Constructor. arguments: tabCornerWidget: desc: The parent QTabCornerWidget. type: QTabCornerWidget """ super(QLangMenu, self).__init__(tabCornerWidget) self.tabCornerWidget = tabCornerWidget for lang in QEditorConst.languages: self.addAction(QtGui.QIcon.fromTheme(u'text-x-%s' % lang.lower(), QtGui.QIcon.fromTheme(u'text-plain')), lang) self.triggered.connect(self.setLang) @property def tabManager(self): return self.tabCornerWidget.tabManager def setLang(self, action): """ desc: Select a new language for the selected tab. arguments: action: type: QAction """ self.tabManager.tab().setLang(str(action.text())) self.tabCornerWidget.update() PK|GfHc8QProgEdit/_qeditorprefs.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os from qtpy import QtGui, QtCore, QtWidgets from QProgEdit.pyqt5compat import Qsci from QProgEdit.py3compat import * from QProgEdit import QColorScheme from QProgEdit import QUiLoader class QEditorPrefs(QtWidgets.QWidget, QUiLoader): """ desc: An editor preferences widget. """ # These options correspond to the names of checkboxes in the prefsWidget # UI definition. checkBoxCfgOptions = [u'AutoComplete', u'AutoIndent', u'HighlightCurrentLine', u'HighlightMatchingBrackets', u'LineNumbers', u'ShowEol', u'ShowFolding', u'ShowIndent', u'ShowWhitespace', u'WordWrap', u'Validate'] def __init__(self, qProgEdit): """ desc: Constructor. arguments: qProgEdit: desc: The parent QProgEdit. type: QProgEdit """ super(QEditorPrefs, self).__init__(qProgEdit) self.qProgEdit = qProgEdit self.loadUi(u'prefsWidget') self.bestHeight = self.height() self.lock = False # Make connections self.ui.fontComboBoxFontFamily.activated.connect(self.apply) self.ui.lineEditCommentShortcut.editingFinished.connect(self.apply) self.ui.lineEditUncommentShortcut.editingFinished.connect(self.apply) self.ui.comboBoxColorScheme.activated.connect(self.apply) self.ui.spinBoxFontSize.valueChanged.connect(self.apply) self.ui.spinBoxTabWidth.valueChanged.connect(self.apply) self.ui.checkBoxWordWrapMarker.toggled.connect(self.apply) for cfg in self.checkBoxCfgOptions: checkBox = getattr(self.ui, 'checkBox%s' % cfg) checkBox.stateChanged.connect(self.apply) def refresh(self): """ desc: Refreshes the controls. """ self.lock = True index = self.ui.fontComboBoxFontFamily.findText( self.qProgEdit.cfg.qProgEditFontFamily) # Fill the shortcut fields self.ui.lineEditCommentShortcut.setText( self.qProgEdit.cfg.qProgEditCommentShortcut) self.ui.lineEditUncommentShortcut.setText( self.qProgEdit.cfg.qProgEditUncommentShortcut) # Fill the color scheme combobox and select the current color scheme self.ui.comboBoxColorScheme.clear() i = 0 for scheme in QColorScheme.schemes: self.ui.comboBoxColorScheme.addItem(scheme) if scheme == self.qProgEdit.cfg.qProgEditColorScheme: self.ui.comboBoxColorScheme.setCurrentIndex(i) i += 1 self.ui.fontComboBoxFontFamily.setCurrentIndex(index) self.ui.spinBoxFontSize.setValue(self.qProgEdit.cfg.qProgEditFontSize) self.ui.spinBoxTabWidth.setValue(self.qProgEdit.cfg.qProgEditTabWidth) self.ui.checkBoxWordWrapMarker.setChecked( self.qProgEdit.cfg.qProgEditWordWrapMarker is not None) for cfg in self.checkBoxCfgOptions: checked = getattr(self.qProgEdit.cfg, u'qProgEdit%s' % cfg) checkBox = getattr(self.ui, u'checkBox%s' % cfg) checkBox.setChecked(checked) self.lock = False def apply(self, dummy=None): """ desc: Applies the controls. """ if self.lock: return self.qProgEdit.cfg.qProgEditFontFamily = str( self.ui.fontComboBoxFontFamily.currentText()) self.qProgEdit.cfg.qProgEditColorScheme = str( self.ui.comboBoxColorScheme.currentText()) self.qProgEdit.cfg.qProgEditCommentShortcut = str( self.ui.lineEditCommentShortcut.text()) self.qProgEdit.cfg.qProgEditUncommentShortcut = str( self.ui.lineEditUncommentShortcut.text()) self.qProgEdit.cfg.qProgEditFontSize = self.ui.spinBoxFontSize.value() self.qProgEdit.cfg.qProgEditTabWidth = self.ui.spinBoxTabWidth.value() if self.ui.checkBoxWordWrapMarker.isChecked(): self.qProgEdit.cfg.qProgEditWordWrapMarker = 80 else: self.qProgEdit.cfg.qProgEditWordWrapMarker = None for cfg in self.checkBoxCfgOptions: checkBox = getattr(self.ui, u'checkBox%s' % cfg) checked = checkBox.isChecked() setattr(self.qProgEdit.cfg, u'qProgEdit%s' % cfg, checked) if self.qProgEdit.tabManager is not None: self.qProgEdit.tabManager.applyCfg() else: self.qProgEdit.applyCfg() PK|GfH:Dm==QProgEdit/_qeditor.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.py3compat import * from qtpy import QtGui, QtCore, QtWidgets from QProgEdit.pyqt5compat import Qsci from QProgEdit import QLexer, QColorScheme, QSymbolTreeWidgetItem, symbols, \ validate, clean, _ class QEditor(Qsci.QsciScintilla): """ desc: A single editor widget, which is embedded in a QProgEdit widget. """ invalidMarker = 8 cursorRowChanged = QtCore.pyqtSignal(int, int) # (Old row, new row) focusLost = QtCore.pyqtSignal() focusReceived = QtCore.pyqtSignal() handlerButtonClicked = QtCore.pyqtSignal() def __init__(self, qProgEdit): """ desc: Constructor. arguments: qProgEdit: desc: The parent QProgEdit. type: QProgEdit """ super(QEditor, self).__init__(qProgEdit) self.setKeyBindings() self.setEolMode(self.EolUnix) self.setUtf8(True) self.qProgEdit = qProgEdit self.validationErrors = {} self.setLang() self.commentShortcut = QtWidgets.QShortcut(QtGui.QKeySequence( self.cfg.qProgEditCommentShortcut), self, context=QtCore.Qt.WidgetWithChildrenShortcut) self.uncommentShortcut = QtWidgets.QShortcut(QtGui.QKeySequence( self.cfg.qProgEditUncommentShortcut), self, context=QtCore.Qt.WidgetWithChildrenShortcut) self.commentShortcut.activated.connect(self.commentSelection) self.uncommentShortcut.activated.connect(self.uncommentSelection) self.applyCfg() self.linesChanged.connect(self.updateMarginWidth) self.selectionChanged.connect(self.highlightSelection) self.cursorPositionChanged.connect(self.cursorMoved) self.marginClicked.connect(self.onMarginClick) self.setMarginSensitivity(1, True) self.cursorRow = 0 self.symbolTree = None self.symbolTreeWidgetItemClass = QSymbolTreeWidgetItem self._symbols = [] @property def tabManager(self): return self.qProgEdit.tabManager @property def cfg(self): return self.qProgEdit.cfg @property def focusTab(self): return self.qProgEdit.focusTab @property def tabIndex(self): return self.qProgEdit.tabIndex def setKeyBindings(self): """ desc: Sets keybindings so that they don't interfere with the default keybindings of OpenSesame, and are more atom-like. """ c = self.standardCommands() # Disable Ctrl+Slash and Ctrl+T cmd = c.boundTo(QtCore.Qt.Key_Slash | QtCore.Qt.ControlModifier) cmd.setKey(0) cmd = c.boundTo(QtCore.Qt.Key_T | QtCore.Qt.ControlModifier) cmd.setKey(0) # Use Ctrl+Shift+D for line duplication cmd = c.boundTo(QtCore.Qt.Key_D | QtCore.Qt.ControlModifier) cmd.setKey(QtCore.Qt.Key_D | QtCore.Qt.ControlModifier \ | QtCore.Qt.ShiftModifier) # Use Ctrl+Shift+K for line deletion cmd = c.boundTo(QtCore.Qt.Key_L | QtCore.Qt.ControlModifier) cmd.setKey(QtCore.Qt.Key_K | QtCore.Qt.ControlModifier \ | QtCore.Qt.ShiftModifier) def applyCfg(self): """ desc: Applies the configuration. """ if hasattr(QColorScheme, self.cfg.qProgEditColorScheme): colorScheme = getattr(QColorScheme, \ self.cfg.qProgEditColorScheme) else: colorScheme = QColorScheme.Default # Define indicator for selection matching self.indicatorDefine(self.INDIC_STRAIGHTBOX, 0) indicatorColor = QtGui.QColor(colorScheme[u'Highlight']) indicatorColor.setAlpha(64) self.setIndicatorForegroundColor(indicatorColor, 0) self.markerDefine(Qsci.QsciScintilla.RightArrow, self.invalidMarker) self.setMarkerBackgroundColor(QtGui.QColor( colorScheme[u'Invalid']), self.invalidMarker) self.setMarkerForegroundColor(QtGui.QColor( colorScheme[u'Invalid']), self.invalidMarker) self.commentShortcut.setKey(QtGui.QKeySequence( self.cfg.qProgEditCommentShortcut)) self.uncommentShortcut.setKey(QtGui.QKeySequence( self.cfg.qProgEditUncommentShortcut)) font = QtGui.QFont(self.cfg.qProgEditFontFamily, self.cfg.qProgEditFontSize) self.setFont(font) self.setTabWidth(self.cfg.qProgEditTabWidth) self.setAutoIndent(self.cfg.qProgEditAutoIndent) self.setEolVisibility(self.cfg.qProgEditShowEol) self.setIndentationGuides(self.cfg.qProgEditShowIndent) self.setCaretLineVisible( self.cfg.qProgEditHighlightCurrentLine) if self.cfg.qProgEditShowFolding: self.setFolding(Qsci.QsciScintilla.PlainFoldStyle) else: self.setFolding(Qsci.QsciScintilla.NoFoldStyle) self.setMarginLineNumbers(0, self.cfg.qProgEditLineNumbers) if u'Fold margin' in colorScheme: color = QtGui.QColor(colorScheme[u'Fold margin']) self.setFoldMarginColors(color, color) if self.cfg.qProgEditShowWhitespace: self.setWhitespaceVisibility(Qsci.QsciScintilla.WsVisible) else: self.setWhitespaceVisibility(Qsci.QsciScintilla.WsInvisible) if self.cfg.qProgEditWordWrap: self.setWrapMode(Qsci.QsciScintilla.WrapWord) else: self.setWrapMode(Qsci.QsciScintilla.WrapNone) if self.cfg.qProgEditWordWrapMarker is not None: self.setEdgeColumn(self.cfg.qProgEditWordWrapMarker) self.setEdgeMode(Qsci.QsciScintilla.EdgeLine) else: self.setEdgeMode(Qsci.QsciScintilla.EdgeNone) if self.cfg.qProgEditAutoComplete: self.setAutoCompletionSource(Qsci.QsciScintilla.AcsAll) else: self.setAutoCompletionSource(Qsci.QsciScintilla.AcsNone) if self.cfg.qProgEditHighlightMatchingBrackets: self.setBraceMatching(Qsci.QsciScintilla.StrictBraceMatch) else: self.setBraceMatching(Qsci.QsciScintilla.NoBraceMatch) self.setLang(self.lang()) self.cfgVersion = self.cfg.version() def commentSelection(self): """ desc: Comments out the currently selected text. """ self.beginUndoAction() cl, ci = self.getCursorPosition() if not self.hasSelectedText(): select = False # If there is no selection, use the current line fl = self.getCursorPosition()[0] tl = fl fi = 0 ti = self.lineLength(tl) else: select = True fl, fi, tl, ti = self.getSelection() if fi > 0: fi += 1 ti += 1 for l in range(fl, tl+1): self.insertAt(u'#', l, 0) ci += 1 self.setCursorPosition(cl, ci) if select: self.setSelection(fl, fi, tl, ti) self.endUndoAction() def cursorMoved(self): """ desc: Is called whenever the cursor moves, checks whether the cursor has jumped from one line to the next, and, if so, calls the relevant functions. """ row, col = self.getCursorPosition() if self.cursorRow != row: self.validate() self.updateSymbolTree() self.cursorRowChanged.emit(self.cursorRow, row) self.tabManager.cursorRowChanged.emit(self.tabIndex(), self.cursorRow, row) self.cursorRow = row def focusOutEvent(self, e): """ desc: Called when the editor loses focus. """ if e.reason() == QtCore.Qt.PopupFocusReason: e.ignore() return self.validate() self.updateSymbolTree() if self.isModified(): self.setModified(False) super(QEditor, self).focusOutEvent(e) self.focusLost.emit() self.tabManager.focusLost.emit(self.tabIndex()) def focusInEvent(self, e): """ desc: Called when the editor receives focus. """ if self.tabManager.cfg.version() != self.cfgVersion: self.applyCfg() super(QEditor, self).focusInEvent(e) self.focusReceived.emit() self.tabManager.focusReceived.emit(self.tabIndex()) def highlightSelection(self): """ desc: Highlights all parts of the text that match the current selection. """ text = self.text() selection = self.selectedText() length = len(selection) self.clearIndicatorRange(0, 0, self.lines(), 0, 0) if length < 3 or u'\n' in selection: return self.qProgEdit.find.setFindText(selection) indexList = [] i = -1 line, index = self.getCursorPosition() currentPos = self.positionFromLineIndex(line, index) while True: i = text.find(selection, i+1) if i < 0: break if i <= currentPos and i+length >= currentPos: continue line, index = self.lineIndexFromPosition(i) self.fillIndicatorRange(line, index, line, index+length, 0) def keyPressEvent(self, event): """ desc: Intercepts certain keypress events to implement custom copy-pasting and zooming. arguments: event: type: QKeyPressEvent """ key = event.key() ctrl = event.modifiers() & QtCore.Qt.ControlModifier shift = event.modifiers() & QtCore.Qt.ShiftModifier # Zoom in/out if ((key == QtCore.Qt.Key_Plus) and ctrl) \ or ((key == QtCore.Qt.Key_Equal) and shift and ctrl): self.zoomIn() event.accept() elif (key == QtCore.Qt.Key_Minus) and ctrl: self.zoomOut() event.accept() elif (key == QtCore.Qt.Key_V) and ctrl: self.paste() event.accept() else: Qsci.QsciScintilla.keyPressEvent(self, event) def onMarginClick(self, margin, line, state): """ desc: Shows validation errors when the margin symbol is clicked. arguments: margin: desc: The margin number. type: int line: desc: The line number. type: int state: desc: The keyboard state. type: int """ if margin != 1: return if line in self.validationErrors: err = self.validationErrors[line] QtWidgets.QToolTip.showText(QtGui.QCursor().pos(), err) def uncommentSelection(self): """ desc: Uncomments the currently selected text. """ self.beginUndoAction() cl, ci = self.getCursorPosition() if not self.hasSelectedText(): select = False # If there is no selection, use the current line fl = self.getCursorPosition()[0] tl = fl fi = 0 ti = self.lineLength(tl)-1 else: select = True fl, fi, tl, ti = self.getSelection() stripped = False for l in range(fl, tl+1): l = self.setSelection(l, 0, l, self.lineLength(l)) s = self.selectedText() _s = s.strip() if len(_s) == 0 or _s[0] != u'#': continue stripped = True i = s.find(u'#') s = s[:i]+s[i+1:] self.replaceSelectedText(s) # If a comment character has been stripped, we need to jump back one # position, but not below 0 if stripped: ci = max(0, ci-1) ti = max(0, ti-1) self.setCursorPosition(cl, ci) if select: self.setSelection(fl, fi, tl, ti) self.endUndoAction() def lang(self): """ returns: desc: The language of the editor. type: unicode """ return self._lang def paste(self): """ desc: Re-implements the paste method to allow modification of paste content. """ text = QtWidgets.QApplication.clipboard().text() if hasattr(clean, self.lang().lower()): msg, cleanText = getattr(clean, self.lang().lower())(text) if msg is not None: resp = QtGui.QMessageBox.question(self, _(u'Pasting content'), msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if resp == QtGui.QMessageBox.Yes: text = cleanText self.replaceSelectedText(text) def selectedText(self, currentLineFallback=False): """ desc: Returns the selected text. keywords: currentLineFallback: desc: Indicates whether the current line should be returned if no text has been selected. Otherwise, an empty string is returned. type: bool returns: desc: The selected text. type: str """ if self.hasSelectedText() or not currentLineFallback: return super(QEditor, self).selectedText() line, index = self.getCursorPosition() return self.text().split(u'\n')[line] def setLang(self, lang=u'text'): """ desc: Sets the editor language. keywords: lang: desc: A language, used to select a lexer for syntax highlighting, validation, cleaning, etc. if an appropriate lexer isn't found, no error is generated, but syntax highlighting is disabled. For a list of available lexers, refer to theQsci.QsciScintilla documentation. """ self._lexer = QLexer(self, lang=lang, colorScheme=self.cfg.qProgEditColorScheme) self._lang = lang self.SendScintilla(Qsci.QsciScintillaBase.SCI_CLEARDOCUMENTSTYLE) self.setLexer(self._lexer) self.validate() def setSymbolTree(self, symbolTree, symbolTreeWidgetItemClass=QSymbolTreeWidgetItem): """ desc: Sets the symbol-tree widget. arguments: symbolTree: desc: A symbol-tree widget. type: QTreeWidgetItem keywords: symbolTreeWidgetItemClass: desc: The class to use for symbol-tree widgets. This should derive from QSymbolTreeWidgetItem. type: type """ self.symbolTree = symbolTree self.symbolTreeWidgetItemClass = symbolTreeWidgetItemClass self._symbols = [] self.updateSymbolTree() def setText(self, text): """ desc: Sets the editor contents. arguments: text: desc: A text string. This can be a str object or unicode object. type: [str, unicode] """ if isinstance(text, basestring): text = safe_decode(text) else: raise Exception(u'Expecting a str or unicode object') super(QEditor, self).setText(text) self.setModified(False) self.updateSymbolTree() self.validate() def text(self): """ desc: Retrieves the editor contents. returns: desc: The editor contents. type: unicode """ return str(super(QEditor, self).text()) def updateMarginWidth(self): """ desc: Updates the width of the margin containing the line numbers. """ self.setMarginWidth(0, u' %s' % self.lines()) def updateSymbolTree(self): """ desc: Updates the symbol tree, if any has been specified and a symbol parser is available for the langauage. """ if self.symbolTree is None: return _symbols = self.symbols() if _symbols == self._symbols: return self.symbolTree.takeChildren() for lineNo, _type, name, argSpec in self.symbols(): self.symbolTree.addChild(self.symbolTreeWidgetItemClass(self, lineNo, _type, name, argSpec)) self._symbols = _symbols def symbols(self): """ desc: Returns an up-to-date list of symbols. returns: desc: A list of symbols. type: list """ if not hasattr(symbols, self.lang().lower()): return [] parser = getattr(symbols, self.lang().lower()) return parser(self.text()) def validate(self): """ desc: Validates the content. """ self.highlightSelection() cl = self.getCursorPosition()[0] validateCurrentLine = cl in self.validationErrors self.validationErrors = {} self.markerDeleteAll() if not self.cfg.qProgEditValidate or not hasattr(validate, \ self.lang().lower()): return validator = getattr(validate, self.lang().lower()) for l, s in validator(self.text()): # Do not validate negative positions or the current line, unless the # current line already had a negative validation before. if l < 0 or (not validateCurrentLine and l == cl): continue self.validationErrors[l] = s self.markerAdd(l, self.invalidMarker) def setInvalid(self, l, msg): """ desc: Mark a specific line as invalid. Resets all other invalid messages. arguments: l: The line to mark. msg: The error messsage. """ self.markerDeleteAll() self.validationErrors = {l-1 : msg} self.markerAdd(l-1, self.invalidMarker) def wheelEvent(self, event): """ desc: Implements scroll-to-zoom functionality. arguments: event: type: QWheelEvent """ if QtCore.Qt.ControlModifier == event.modifiers(): event.ignore() if event.delta() > 0: self.zoomIn() else: self.zoomOut() else: super(QEditor, self).wheelEvent(event) PKr\G7zzQProgEdit/py3compat.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import sys if sys.version_info >= (3,0,0): py3 = True basestring = str else: bytes = str str = unicode py3 = False def safe_decode(s, enc='utf-8', errors='strict'): if isinstance(s, str): return s return s.decode(enc, errors) def safe_encode(s, enc='utf-8', errors='strict'): if isinstance(s, bytes): return s return s.encode(enc, errors) __all__ = ['py3', 'safe_decode', 'safe_encode'] if not py3: __all__ += ['str', 'bytes'] else: __all__ += ['basestring'] PKr\GlDQProgEdit/_qcolorscheme.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ black = u'#000000' white = u'#FFFFFF' # Tango colors butter = ['#fce94f', '#edd400', '#c4a000'] orange = ['#fcaf3e', '#f57900', '#ce5c00'] chocolate = ['#e9b96e', '#c17d11', '#8f5902'] chameleon = ['#8ae234', '#73d216', '#4e9a06'] skyBlue = ['#729fcf', '#3465a4', '#204a87'] plum = ['#ad7fa8', '#75507b', '#5c3566'] scarletRed = ['#ef2929', '#cc0000', '#a40000'] aluminium = ['#eeeeec', '#d3d7cf', '#babdb6', '#888a85', '#555753', '#2e3436'] SolarizedPalette = { u'Base03' : u'#002b36', u'Base02' : u'#073642', u'Base01' : u'#586e75', u'Base00' : u'#657b83', u'Base0' : u'#839496', u'Base1' : u'#93a1a1', u'Base2' : u'#eee8d5', u'Base3' : u'#fdf6e3', u'Yellow' : u'#b58900', u'Orange' : u'#cb4b16', u'Red' : u'#dc322f', u'Magenta' : u'#d33682', u'Violet' : u'#6c71c4', u'Blue' : u'#268bd2', u'Cyan' : u'#2aa198', u'Green' : u'#859900' } SolarizedDark = { u'Prompt in' : SolarizedPalette[u'Violet'], u'Prompt out' : SolarizedPalette[u'Red'], u'Background' : SolarizedPalette[u'Base02'], u'Default' : SolarizedPalette[u'Base1'], u'Selection background' : SolarizedPalette[u'Base2'], u'Selection foreground' : SolarizedPalette[u'Base01'], u'Caret-line background' : SolarizedPalette[u'Base03'], u'Identifier' : SolarizedPalette[u'Base1'], u'Comment' : SolarizedPalette[u'Base00'], u'Comment block' : SolarizedPalette[u'Base00'], u'Number' : SolarizedPalette[u'Blue'], u'Double-quoted string' : SolarizedPalette[u'Cyan'], u'Single-quoted string' : SolarizedPalette[u'Cyan'], u'Triple-quoted string' : SolarizedPalette[u'Cyan'], u'Triple single-quoted string' : SolarizedPalette[u'Cyan'], u'Triple double-quoted string' : SolarizedPalette[u'Cyan'], u'Keyword' : SolarizedPalette[u'Yellow'], u'Operator' : SolarizedPalette[u'Base1'], u'Class name' : SolarizedPalette[u'Magenta'], u'Function or method name' : SolarizedPalette[u'Magenta'], u'Unclosed string' : SolarizedPalette[u'Red'], u'Highlighted identifier' : SolarizedPalette[u'Cyan'], u'Decorator' : SolarizedPalette[u'Orange'], u'Invalid' : SolarizedPalette[u'Orange'], u'Highlight' : SolarizedPalette[u'Orange'], } MonokaiYellow = '#E6DB74'; MonokaiBlue = '#66D9EF'; MonokaiGreen = '#A6E22E'; MonokaiPink = '#F92672'; MonokaiPurple = '#AE81FF'; MonokaiOrange = '#FD971F' MonokaiGray = '#75715E'; MonokaiLightGray = '#F8F8F2'; MonokaiDarkGray = '#49483E'; MonokaiVeryDarkGray = '#282828'; MonokaiBlack = '#000000' Monokai = { u'Prompt in' : MonokaiBlue, u'Prompt out' : MonokaiPink, u'Caret-line background' : MonokaiBlack, u'Background' : MonokaiVeryDarkGray, u'Selection background' : MonokaiDarkGray, u'Default' : MonokaiLightGray, u'Selection foreground' : MonokaiLightGray, u'Identifier' : MonokaiLightGray, u'Comment' : (MonokaiGray, False, True), u'Comment block' : (MonokaiGray, False, True), u'Double-quoted string' : MonokaiYellow, u'Single-quoted string' : MonokaiYellow, u'Triple-quoted string' : MonokaiYellow, u'Triple single-quoted string' : MonokaiYellow, u'Triple double-quoted string' : MonokaiYellow, u'Unclosed string' : MonokaiYellow, u'Keyword' : MonokaiBlue, u'Class name' : MonokaiGreen, u'Function or method name' : MonokaiGreen, u'Decorator' : MonokaiGreen, u'Number' : MonokaiPurple, u'Highlighted identifier' : MonokaiOrange, u'Operator' : MonokaiPink, u'Invalid' : MonokaiPink, u'Highlight' : MonokaiPink, } Default = {u'Invalid' : u'red', u'Highlight' : u'yellow'} # A list of available themes schemes = ['Default', 'SolarizedDark', 'Monokai'] PK5CMrQProgEdit/_qeditorconst.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ languages = [ u'Text', u'Python', u'OpenSesame' ] PK`y|H QProgEdit/_qlexer.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.py3compat import * from qtpy import QtGui, QtCore from QProgEdit.pyqt5compat import Qsci from QProgEdit import QColorScheme python_builtins = (' abs dict help min setattr all dir hex next slice any ' 'id object sorted ascii enumerate input oct staticmethod bin eval int open str ' 'bool exec isinstance ord sum bytearray filter issubclass pow super bytes ' 'float iter print tuple callable format len property type chr frozenset list ' 'range vars classmethod getattr locals repr zip compile globals map reversed ' '__import__ complex hasattr max round delattr hash memoryview set divmod') opensesame_builtins = ' exp win self var pool items items clock log' class QBaseLexer(object): """ desc: A base object for custom lexers. """ def setTheme(self, editor, colorScheme): """ desc: Applies the colorscheme to the lexer. arguments: editor: desc: An editor object. type:Qsci.QsciScintilla colorScheme: desc: A colorscheme. type: dict """ self.editor = editor # Set the font based on the configuration font = QtGui.QFont(self.editor.cfg.qProgEditFontFamily, self.editor.cfg.qProgEditFontSize) self.setFont(font) # Apply the color theme if hasattr(QColorScheme, colorScheme): colorScheme = getattr(QColorScheme, colorScheme) else: colorScheme = QColorScheme.Default if u'Background' in colorScheme: self.setPaper(QtGui.QColor(colorScheme[u'Background'])) self.setDefaultPaper(QtGui.QColor(colorScheme[u'Background'])) if u'Default' in colorScheme: self.editor.setCaretForegroundColor(QtGui.QColor( colorScheme[u'Default'])) self.setDefaultColor(QtGui.QColor(colorScheme[u'Default'])) if u'Selection background' in colorScheme: self.editor.setSelectionBackgroundColor(QtGui.QColor( colorScheme[u'Selection background'])) if u'Selection foreground' in colorScheme: self.editor.setSelectionForegroundColor(QtGui.QColor( colorScheme[u'Selection foreground'])) if u'Caret-line background' in colorScheme: self.editor.setCaretLineBackgroundColor(QtGui.QColor( colorScheme[u'Caret-line background'])) for style in range(50): styleName = safe_decode(self.description(style), errors=u'ignore') if styleName != u'' and styleName in colorScheme: if isinstance(colorScheme[styleName], tuple): color, bold, italic = colorScheme[styleName] self.setColor(QtGui.QColor(color), style) _font = QtGui.QFont(font) _font.setBold(bold) _font.setItalic(italic) self.setFont(_font, style) else: color = colorScheme[styleName] self.setColor(QtGui.QColor(color), style) class QPythonLexer(QBaseLexer, Qsci.QsciLexerPython): """ desc: A custom Python lexer. """ def keywords(self, keyset): """ desc: Specifies keywords. arguments: keyset: desc: The keyword set. type: int returns: desc: A space-separated list of keywords. type: str """ if keyset == 1: return Qsci.QsciLexerPython.keywords(self, keyset).replace( ' None', '') + python_builtins + opensesame_builtins elif keyset == 2: return 'None True False' return Qsci.QsciLexerPython.keywords(self, keyset) class QOpenSesameLexer(QBaseLexer, Qsci.QsciLexerPython): """ desc: A lexer for OpenSesame script. """ def keywords(self, keyset): """ desc: Specifies keywords. arguments: keyset: desc: The keyword set. type: int returns: desc: A space-separated list of keywords. type: str """ if keyset == 1: return (b'set define draw setcycle log run widget shuffle ' b'shuffle_horiz fullfactorial slice sort sortby reverse roll ' b'weight constrain maxrep mindist') if keyset == 2: return (b'ellipse circle line arrow textline image gabore noise ' b'fixdot label checkbox button image image_button rating_scale ' b'text_input') return Qsci.QsciLexerPython.keywords(self, keyset) class QFallbackLexer(QBaseLexer, Qsci.QsciLexer): """ desc: A fallback lexer for plain text. """ def description(self, style): """ desc: Gives a style description for the generic Lexer. arguments: style: desc: The style number. type: int returns: desc: The 'Default' str for style 0 and empty str for all other styles. type: str """ if style == 0: return u'Default' else: return u'' def QLexer(editor, lang=u'text', colorScheme=u'Default'): """ desc: A factory for a lexer. arguments: editor: desc: The parent QEditor. type: QEditor keywords: lang: desc: The language. type: unicode colorScheme: desc: The color scheme. type: unicode """ if lang.lower() == u'opensesame': lexer = QOpenSesameLexer(editor) elif lang.lower() == u'python': lexer = QPythonLexer(editor) else: lexer = QFallbackLexer(editor) lexer.setTheme(editor, colorScheme) return lexer PK|GfH?{2QProgEdit/_qeditorfind.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os from qtpy import QtGui, QtCore, QtWidgets from QProgEdit.pyqt5compat import Qsci, uic from QProgEdit.py3compat import * from QProgEdit import QUiLoader class QEditorFind(QtWidgets.QWidget, QUiLoader): """ desc: A find/ replace widget. """ def __init__(self, qProgEdit): """ desc: Constructor. arguments: qProgEdit: desc: The parent QProgEdit. type: QProgEdit """ super(QEditorFind, self).__init__(qProgEdit) self.qProgEdit = qProgEdit self.loadUi(u'findWidget') self.ui.pushButtonFind.clicked.connect(self.find) self.ui.lineEditFind.returnPressed.connect(self.find) self.ui.pushButtonReplace.clicked.connect(self.replace) self.ui.pushButtonReplaceAll.clicked.connect(self.replaceAll) self.bestHeight = self.height() self.matchNr = None self._locked = False @property def editor(self): return self.qProgEdit.editor def caseSensitive(self): """ returns: desc: True or False, depending on whether we should search case sensitive. type: bool """ return self.ui.checkBoxCaseSensitive.isChecked() def findText(self): """ returns: desc: The find text. type: unicode """ return str(self.ui.lineEditFind.text()) def find(self): """ desc: Finds the current text in the document. returns: desc: True if matching text has been found, False otherwise. type: bool """ return self.editor.findFirst(self.findText(), False, self.caseSensitive(), self.matchWhole(), True) def lock(self): """ desc: Locks the editor and find widget, so that we don't get into recursion problems during replace actions. """ self._locked = True self.editor.selectionChanged.disconnect() def matchWhole(self): """ returns: desc: True or False, depending on whether we should match whole words only. type: bool """ return self.ui.checkBoxMatchWhole.isChecked() def replace(self): """ desc: Replaces the first occurence in the document. returns: desc: True if text has been replaced, False otherwise. type: bool """ self.lock() if self.editor.hasSelectedText(): row1, line1, row2, line2 = self.editor.getSelection() self.editor.setCursorPosition(row1, line1) self.find() self.editor.replace(self.replaceText()) self.unlock() return True def replaceAll(self): """ desc: Replaces all occurences in the document. """ self.lock() self.editor.beginUndoAction() text = self.editor.text() if self.caseSensitive(): cs = QtCore.Qt.CaseSensitive else: cs = QtCore.Qt.CaseInsensitive n = text.count(self.findText(), cs) for i in range(n): self.find() self.editor.replace(self.replaceText()) self.editor.endUndoAction() self.unlock() def replaceText(self): """ returns: desc: The replace text. type: unicode """ return str(self.ui.lineEditReplace.text()) def setFindText(self, txt=u''): """ desc: Sets the text of the find widget. keywords: txt: desc: The text to set. type: unicode """ if self._locked: return self.ui.lineEditFind.setText(txt) def unlock(self): """ desc: Unlocks the editor and find widget, to resume normal operations after replacing. """ self._locked = False self.editor.selectionChanged.connect(self.editor.highlightSelection) def unshow(self): """ desc: Hides the widget. """ self.qProgEdit.toggleFind(False) PK|GfH["6QProgEdit/_qeditorcfg.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os from qtpy import QtGui, QtCore class QEditorCfg(QtCore.QObject): """ desc: A non-persistent configuration object. """ def __init__(self, parent=None): """ desc: Constructor. keywords: parent: desc: The parent widget. type: [QWidget, NoneType] """ super(QEditorCfg, self).__init__(parent) if os.name == u'nt': self.qProgEditFontFamily = u'Courier New' else: self.qProgEditFontFamily = u'Ubuntu Mono' self.qProgEditFontSize = 13 self.qProgEditLineNumbers = True self.qProgEditHighlightCurrentLine = False self.qProgEditHighlightMatchingBrackets = True self.qProgEditWordWrapMarker = 80 self.qProgEditWordWrap = True self.qProgEditTabWidth = 4 self.qProgEditAutoIndent = True self.qProgEditShowEol = False self.qProgEditShowWhitespace = False self.qProgEditShowIndent = False self.qProgEditShowFolding = True self.qProgEditAutoComplete = True self.qProgEditValidate = True self.qProgEditColorScheme = u'Monokai' self.qProgEditCommentShortcut = u'Ctrl+M' self.qProgEditUncommentShortcut = u'Ctrl+Shift+M' self.qProgEditSwitchLeftShortcut = u'Alt+Left' self.qProgEditSwitchRightShortcut = u'Alt+Right' self.qProgEditShowFindShortcut = u'Ctrl+F' self.qProgEditHideFindShortcut = u'Escape' self.qProgEditTogglePrefsShortcut = u'Ctrl+Shift+P' self.qProgEditRunSelectedShortcut = u'Alt+R' self.qProgEditRunAllShortcut = u'Shift+Alt+R' self.qProgEditSymbolTreeWidgetItemIcon = u'text-x-script' def version(self): """ desc: Returns the config version. """ return 0 PK|GfH,.QProgEdit/_qprogedit.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from qtpy import QtGui, QtCore, QtWidgets from QProgEdit import QEditor, QEditorPrefs, QEditorFind class QProgEdit(QtWidgets.QWidget): """ desc: A single editor window, with preferences widget and search functionality. """ cursorRowChanged = QtCore.pyqtSignal() focusLost = QtCore.pyqtSignal() focusReceived = QtCore.pyqtSignal() handlerButtonClicked = QtCore.pyqtSignal() def __init__(self, tabManager, dPrint=None, title=u'Empty document', **editorParams): """ desc: Constructor. arguments: tabManager: desc: A tab manager. type: QTabManager keywords: dPrint: A function to be used for debug printing. Should accept a single parameter, which is the debug message. If no debug function is specified, the standard output is used. title: A title for the document. keyword-dict: editorParams: A dictionary with keywords to be passed to QEditor. """ super(QProgEdit, self).__init__(tabManager) self.tabManager = tabManager self.title = title if dPrint is not None: self.dPrint = dPrint self.editor = QEditor(self, **editorParams) self.prefs = QEditorPrefs(self) self.prefs.hide() self.find = QEditorFind(self) self.find.hide() self.mainBox = QtWidgets.QVBoxLayout(self) self.mainBox.setContentsMargins(4,4,4,4) self.mainBox.setSpacing(4) self.mainBox.addWidget(self.prefs) self.mainBox.addWidget(self.find) self.mainBox.addWidget(self.editor) self.setLayout(self.mainBox) if self.tabManager is not None: self.editor.cursorPositionChanged.connect( self.tabManager.cornerWidget().statusWidget.updateCursorPos) # Properties provide direct access to the relevant editor functions. @property def cfg(self): return self.tabManager.cfg @property def applyCfg(self): return self.editor.applyCfg @property def isModified(self): return self.editor.isModified @property def lang(self): return self.editor.lang @property def text(self): return self.editor.text @property def setLang(self): return self.editor.setLang @property def setSymbolTree(self): return self.editor.setSymbolTree @property def setFocus(self): return self.editor.setFocus @property def setText(self): return self.editor.setText @property def setInvalid(self): return self.editor.setInvalid @property def selectedText(self): return self.editor.selectedText @property def setCursorPosition(self): return self.editor.setCursorPosition @property def symbols(self): return self.editor.symbols @property def updateSymbolTree(self): return self.editor.updateSymbolTree @property def cursorPositionChanged(self): return self.editor.cursorPositionChanged @property def focusLost(self): return self.editor.focusLost @property def focusReceived(self): return self.editor.focusReceived @property def handlerButtonClicked(self): return self.editor.handlerButtonClicked def dPrint(self, msg): """ desc: Prints a debug message. arguments: msg: desc: A debug message. type: [unicode, str] """ print(u'debug: %s' % msg) def focusTab(self): """ desc: Focuses the current tab. """ self.tabManager.setCurrentWidget(self) self.editor.setFocus() def tabIndex(self): """ desc: Gets the index of the current tab. returns: desc: The tab index. type: int """ return self.tabManager.indexOf(self) def toggle(self, widget, visible): """ desc: Toggles the visibility of a widget with a smooth animation. arguments: widget: A QWidget. visible: A boolean indicating the visibility of the widget. """ if visible and widget.isVisible() and \ widget.maximumHeight() == widget.bestHeight: return if not visible and \ (not widget.isVisible() or widget.maximumHeight() == 0): return if not visible: widget.setMaximumHeight(0) else: widget.setMaximumHeight(widget.bestHeight) widget.show() a = QtCore.QPropertyAnimation(widget, u'maximumHeight', widget) if not visible: a.setStartValue(widget.bestHeight) a.setEndValue(0) else: a.setStartValue(0) a.setEndValue(widget.bestHeight) a.setDuration(100) a.start() def toggleFind(self, visible): """ desc: Toggles the visibility of the find widget. arguments: visible: A boolean indicating the visibility of the widget. """ self.toggle(self.find, visible) self.tabManager.cornerWidget().findButton.setChecked(visible) if visible: self.find.ui.lineEditFind.setFocus() else: self.editor.setFocus() def togglePrefs(self, visible): """ desc: Toggles the visibility of the preferences widget arguments: visible: A boolean indicating the visibility of the widget. """ if visible: self.prefs.ui.fontComboBoxFontFamily.setFocus() self.prefs.refresh() self.toggle(self.prefs, visible) PKHDǰQProgEdit/.directory[Dolphin] GroupedSorting=true SortRole=type Timestamp=2014,4,29,11,5,14 Version=3 ViewMode=1 VisibleRoles=Details_text,Details_size,Details_date,Details_type,CustomizedDetails PK|GfH+&QProgEdit/_quiloader.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os import sys from qtpy import QtCore from QProgEdit.pyqt5compat import uic class QUiLoader(QtCore.QObject): """ desc: A simple base class that implements dynamic UI loading for widgets. """ def loadUi(self, name): """ desc: Load a UI. arguments: name: desc: The name of the UI file, without the .ui extension. type: unicode """ dirPath = os.path.dirname(__file__) try: dirPath = dirPath.decode(sys.getfilesystemencoding()) except: # This fails on Python 3 pass # We pass an open file object, because loadUi otherwise tries to str() # the filename, which causes encoding trouble. path = os.path.join(dirPath, u'ui', u'%s.ui' % name) with open(path) as fd: self.ui = uic.loadUi(fd, self) PK|GfHSQProgEdit/_qeditorshortcut.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.py3compat import * from qtpy import QtGui, QtCore, QtWidgets class QEditorShortcut(QtWidgets.QShortcut): def __init__(self, parent, keySequence, target, context=QtCore.Qt.WidgetWithChildrenShortcut): super(QEditorShortcut, self).__init__(QtGui.QKeySequence(keySequence), parent, context=context) self.activated.connect(target) PK|GfH7QProgEdit/_qlineeditfind.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from qtpy import QtGui, QtCore, QtWidgets class QLineEditFind(QtWidgets.QLineEdit): """ desc: Implements a line-edit widget that selects the highlighted text when receiving focus. """ def focusInEvent(self, e): """ desc: Selects the contents on focus. arguments: e: type: QFocusEvent """ self.selectAll() e.accept() PK|GfH$$QProgEdit/_qtabmanager.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os import sys from qtpy import QtGui, QtCore, QtWidgets from QProgEdit.pyqt5compat import Qsci from QProgEdit.py3compat import * from QProgEdit import QEditorCfg, QProgEdit, QTabCornerWidget, \ QEditorShortcut, _ class QTabManager(QtWidgets.QTabWidget): """ desc: A tab manager that contains multiple QProgEdit tabs. """ cursorRowChanged = QtCore.pyqtSignal(int, int, int) focusLost = QtCore.pyqtSignal(int) focusReceived = QtCore.pyqtSignal(int) handlerButtonClicked = QtCore.pyqtSignal(int) execute = QtCore.pyqtSignal(str) def __init__(self, parent=None, cfg=QEditorCfg(), tabsClosable=False, tabsMovable=False, msg=None, handlerButtonText=None, runButton=False): """ desc: Constructor. keywords: parent: desc: The parent widget. type: QWidget cfg: desc: A configuration backend. By default QEditorCfg is used. Custom backends must have the same API for getting and setting options. tabsClosable: desc: Indicates whether a close button should be shown on tabs. type: bool tabsMovable: desc: Indicates whether tabs can be re-ordered. type: bool msg: desc: An informative message for the corner widget. type: [str, unicode, NoneType] handlerButtonText: desc: Text for a top-right button, which can be clicked to call the handler, or None for no button. type: [str, unicode, NoneType] runButton: desc: Indicates whether a run-selected-text button should be shown. type: bool """ super(QTabManager, self).__init__(parent) self.cfg = cfg self.setDocumentMode(True) self.setTabsClosable(tabsClosable) self.setMovable(tabsMovable) self.currentChanged.connect(self.tabChanged) self.tabCloseRequested.connect(self.closeTab) self.setCornerWidget(QTabCornerWidget(self, msg=msg, handlerButtonText=handlerButtonText, runButton=runButton)) # Keyboard shortcuts QEditorShortcut(self, self.cfg.qProgEditSwitchLeftShortcut, self.switchTabLeft) QEditorShortcut(self, self.cfg.qProgEditSwitchRightShortcut, self.switchTabRight) QEditorShortcut(self, self.cfg.qProgEditShowFindShortcut, self.showFind) QEditorShortcut(self, self.cfg.qProgEditHideFindShortcut, self.hideFind) QEditorShortcut(self, self.cfg.qProgEditTogglePrefsShortcut, self.togglePrefs) if runButton: QEditorShortcut(self, self.cfg.qProgEditRunSelectedShortcut, self.runSelectedText) QEditorShortcut(self, self.cfg.qProgEditRunAllShortcut, self.runText) # Under Windows, the tab bar is too small for the icons. Forcing the # tab-bar height looks funny on Linux. Mac OS not tested. if os.name == u'nt': self.setStyleSheet(u'QTabBar::tab { min-height: 32px; }') def addTab(self, title=u'Empty document', select=True): """ desc: Adds an empty document tab. keywords: title: desc: A tab title. type: [unicode, str] select: desc: Indicates whether the newly created tab should be selected. type: bool returns: desc: The newly added tab widget. type: QProgEdit """ progEdit = QProgEdit(self, title=title) index = super(QTabManager, self).addTab(progEdit, progEdit.title) if select: self.setCurrentIndex(index) self.cornerWidget().update() return progEdit def applyCfg(self): """ desc: Applies the configuration. """ for index in range(self.count()): progEdit = self.widget(index) progEdit.applyCfg() def closeTab(self, index=None): """ desc: Closes a tab. keywords: index: A tab index (see [tabIndex]). """ index = self.tabIndex(index) if index is None: return self.removeTab(index) if self.count() == 0: self.addTab(_(u'Empty document')) def isAnyModified(self): """ desc: Checks if one or more of the tabs have been modified. returns: desc: True if (one of) the tab(s) is modified, False otherwise. type: bool """ for tab in self.tabs(): if tab.isModified(): return True return False def runSelectedText(self): """ desc: Emits the execute signal with the selected text. """ self.execute.emit(self.selectedText(currentLineFallback=True)) def runText(self): """ desc: Emits the execute signal with the current text. """ self.execute.emit(self.text()) def selectedText(self, index=None, currentLineFallback=False): """ desc: Returns the selected text for a specific tab. For details, see `QProgEdit.QEditor`. keywords: index: A tab index, as understood by [tabIndex]. returns: The selected text. """ tab = self.tab(index) if tab is None: return None return tab.selectedText(currentLineFallback=currentLineFallback) def selectTab(self, index): """ desc: Switches to a specific tab. arguments: index: A tab index, as understood by [tabIndex]. """ index = self.tabIndex(index) if index is not None: self.setCurrentIndex(index) def setFocus(self, index=None): """ desc: Focuses a specific tab. keywords: index: A tab index, as understood by [tabIndex]. """ tab = self.tab(index) tab.setFocus() def setText(self, text, index=None): """ desc: Sets the text on a specific tab. arguments: text: The new text. keywords: index: A tab index, as understood by [tabIndex]. """ tab = self.tab(index) if tab is not None: tab.setText(text) def setInvalid(self, l, msg, index=None): """ desc: Set an invalid marker on a specific tab. arguments: l: The line to mark. msg: The error messsage. keywords: index: A tab index, as understood by [tabIndex]. """ tab = self.tab(index) if tab is not None: tab.setInvalid(l, msg) def switchTabLeft(self): """ desc: Switches to the tab on the left. """ newIndex = (self.currentIndex() - 1) % self.count() self.setCurrentIndex(newIndex) def switchTabRight(self): """ desc: Switches to the tab on the left. """ newIndex = (self.currentIndex() + 1) % self.count() self.setCurrentIndex(newIndex) def tab(self, index=None): """ desc: Returns the QProgEdit instance for a given tab. keywords: index: desc: Specifies the tab, either by a name (i.e. the name on a tab), an index, or None to get the current tab. type: [int, str, unicode, NoneType] returns: desc: A tab, or None if no matching tab was found. type: [QProgEdit, NoneType] """ index = self.tabIndex(index) if index is None: return None return self.widget(index) def tabIndex(self, index=None): """ desc: Returns the index for a given tab. keywords: index: desc: Specifies the tab, either by a name (i.e. the name on a tab), an index, or None to get the current tab. type: [int, str, unicode, NoneType] returns: desc: A tab index, or None if no matching tab was found. type: [int, NoneType] """ if isinstance(index, int): if index >= 0 and index < self.count(): return index elif isinstance(index, basestring): for i in range(self.count()): if self.tabText(i) == index: return i elif index is None: if self.count() > 0: return self.currentIndex() else: raise Exception(u'index should be int, str, unicode, or None') return None def tabs(self): """ desc: Gets all tabs. returns: desc: A list of all tab widgets. type: list """ return [self.widget(i) for i in range(self.count())] def text(self, index=None): """ desc: Gets the text on a specific tab. keywords: index: A tab index, as understood by [tabIndex]. returns: The text or None if the tab does not exist. """ tab = self.tab(index) if tab is None: return None return tab.text() def toggleFind(self, visible): """ desc: Toggle the visibility of the find widget. arguments: visible: desc: Visibility status. type: bool """ self.currentWidget().toggleFind(visible) def showFind(self): self.currentWidget().toggleFind(True) def hideFind(self): self.currentWidget().toggleFind(False) def togglePrefs(self, visible): """ desc: Toggle the visibility of the preferences widget. arguments: visible: desc: Visibility status. type: bool """ self.currentWidget().togglePrefs(visible) def tabChanged(self, index): """ desc: Is called when the current tab must be updated, for example because a new tab is selected. arguments: index: desc: The index of the newly selected tab. type: int """ if self.count() == 0: return self.cornerWidget().update() self.currentWidget().find.hide() self.currentWidget().prefs.hide() self.setWindowTitle(self.currentWidget().title) PKmFH!tQQQProgEdit/pyqt5compat.py#-*- coding:utf-8 -*- """ This file is part of OpenSesame. OpenSesame is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenSesame is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSesame. If not, see . """ import os if os.environ[u'QT_API'] == u'pyqt5': from PyQt5 import Qsci from PyQt5 import uic else: from PyQt4 import Qsci from PyQt4 import uic __all__ = [u'uic', u'Qsci'] PK||H7LQProgEdit/__init__.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . --- desc: | # QProgEdit v%--python: from QProgEdit import __version__; print(__version__)--% QProgEdit is a PyQt4 widget that implements a full-featured text editor component. It's primary target at the moment is [OpenSesame](http://osdoc.cogsci.nl), a graphical experiment builder. Copyright (2013-2015) Sebastiaan Mathôt ## Overview %-- toc: mindepth: 2 maxdepth: 3 exclude: [Overview] --% ## Dependencies - `PyQt4` - `Qscintilla2` ## Example ~~~ python %--include: example.py--% ~~~ license: | `QProgEdit` is released under the terms of the [General Public License v3](http://www.gnu.org/licenses/gpl-3.0.txt). --- """ version = __version__ = u'4.0.0' from QProgEdit.py3compat import * # A simple wrapper around the translate function from qtpy.QtCore import QCoreApplication _ = lambda s: QCoreApplication.translate(u'qprogedit', s) import QProgEdit._qeditorconst as QEditorConst import QProgEdit._qcolorscheme as QColorScheme from QProgEdit._quiloader import QUiLoader from QProgEdit._qsymboltreewidgetitem import QSymbolTreeWidgetItem from QProgEdit._qeditorcfg import QEditorCfg from QProgEdit._qeditorshortcut import QEditorShortcut from QProgEdit._qlexer import QLexer from QProgEdit._qlangmenu import QLangMenu from QProgEdit._qeditor import QEditor from QProgEdit._qeditorprefs import QEditorPrefs from QProgEdit._qeditorfind import QEditorFind from QProgEdit._qeditorstatus import QEditorStatus from QProgEdit._qprogedit import QProgEdit from QProgEdit._qtabcornerwidget import QTabCornerWidget from QProgEdit._qtabmanager import QTabManager PK|GfHJaQProgEdit/_qtabcornerwidget.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os from qtpy import QtGui, QtCore, QtWidgets from QProgEdit import QLangMenu, QEditorStatus, _ class QTabCornerWidget(QtWidgets.QWidget): """ desc: Contains a number of buttons that are displayed in the tab bar. """ def __init__(self, tabManager, msg=None, handlerButtonText=None, runButton=False): """ desc: Constructor. arguments: tabManager: desc: A tab manager. type: QTabManager keywords: msg: desc: An informative text message. type: [str, unicode, NoneType] handlerButtonText: desc: Text for a top-right button, which can be clicked to call the handler, or None for no button. type: [str, unicode, NoneType] runButton: desc: Indicates whether a run-selected-text button should be shown. type: bool """ super(QTabCornerWidget, self).__init__(tabManager) self.tabManager = tabManager # Run button if runButton: self.runButton = QtWidgets.QPushButton(QtGui.QIcon.fromTheme( u'system-run'), u'', self) self.runButton.setToolTip(_(u'Run selected text')) self.runButton.setCheckable(False) self.runButton.clicked.connect(self.tabManager.runSelectedText) # Preferences button self.prefsButton = QtWidgets.QPushButton(QtGui.QIcon.fromTheme( u'preferences-desktop'), u'', self) self.prefsButton.setCheckable(True) self.prefsButton.toggled.connect(self.tabManager.togglePrefs) # Find button self.findButton = QtWidgets.QPushButton(QtGui.QIcon.fromTheme( u'edit-find'), u'', self) self.findButton.setCheckable(True) self.findButton.toggled.connect(self.tabManager.toggleFind) # Language button (filled by update()) self.langButton = QtWidgets.QPushButton(self) self.langButton.setMenu(QLangMenu(self)) self.langShortcut = QtWidgets.QShortcut(QtGui.QKeySequence(u'Ctrl+Shift+L'), self.tabManager, context=QtCore.Qt.WidgetWithChildrenShortcut) self.langShortcut.activated.connect(self.langButton.click) # Handler button if handlerButtonText is not None: self.handlerButton = QtWidgets.QPushButton(QtGui.QIcon.fromTheme( u'document-save'), handlerButtonText, self) self.handlerButton.clicked.connect(self.handlerButtonClicked) else: self.handlerButton = None # Editor status self.statusWidget = QEditorStatus(self) # Message if msg is not None: self.msgLabel = QtWidgets.QLabel(u'%s' % msg, parent= \ self) self.hBox = QtWidgets.QHBoxLayout(self) self.hBox.setSpacing(2) self.hBox.setContentsMargins(2,2,2,2) if msg is not None: self.hBox.addWidget(self.msgLabel) self.hBox.addWidget(self.statusWidget) if runButton: self.hBox.addWidget(self.runButton) self.hBox.addWidget(self.prefsButton) self.hBox.addWidget(self.findButton) self.hBox.addWidget(self.langButton) if self.handlerButton is not None: self.hBox.addWidget(self.handlerButton) self.setLayout(self.hBox) # Set the tab order for keyboard navigation self.setTabOrder(self.prefsButton, self.findButton) self.setTabOrder(self.findButton, self.langButton) self.setTabOrder(self.langButton, self.handlerButton) def handlerButtonClicked(self): """ desc: Is called when the handler button is clicked and emits the relevant signals. """ self.tabManager.handlerButtonClicked.emit( self.tabManager.currentIndex()) self.tabManager.tab().handlerButtonClicked.emit() def update(self): """ desc: Updates widget to reflect document contents. """ self.langButton.setIcon(QtGui.QIcon.fromTheme( u'text-x-%s' % self.tabManager.tab().lang().lower(), QtGui.QIcon.fromTheme(u'text-plain'))) self.findButton.setChecked(False) self.prefsButton.setChecked(False) PK|GfHےQProgEdit/_qeditorstatus.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import os from qtpy import QtGui, QtCore, QtWidgets class QEditorStatus(QtWidgets.QLabel): """ desc: A simple widget that indicates the editor status, which currently corresponds only to the cursor position. """ def __init__(self, qProgEdit): """ desc: Constructor. arguments: qProgEdit: desc: The parent QProgEdit. type: QProgEdit """ super(QEditorStatus, self).__init__(qProgEdit) self.qProgEdit = qProgEdit if os.name == u'nt': self.setFont(QtGui.QFont(u'courier new', pointSize=8)) else: self.setFont(QtGui.QFont(u'monospace', pointSize=8)) def updateCursorPos(self, line=0, index=0): """ desc: Updates the cursor position. keywords: line: desc: The line number. type: int index: desc: The column number. type: int """ self.setText(u'(%.3d, %.3d)' % (index+1, line+1)) PK|GfH\Uii#QProgEdit/_qsymboltreewidgetitem.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from qtpy import QtCore, QtWidgets, QtGui class QSymbolTreeWidgetItem(QtWidgets.QTreeWidgetItem): """ desc: A symbol-tree widget item to use for symbol overviews. """ def __init__(self, editor, lineNo, _type, name, argSpec): """ desc: Constructor. arguments: editor: desc: The editor widget. type: QEditor lineNo: desc: A line number. type: int _type: desc: The symbol type, such as 'class' or 'def' type: unicode name: desc: The symbol name type: unicode argSpec: desc: The symbol's argument specification. type: unicode """ super(QSymbolTreeWidgetItem, self).__init__([name]) self.editor = editor self.setIcon(0, QtGui.QIcon.fromTheme( self.cfg.qProgEditSymbolTreeWidgetItemIcon)) self.lineNo = lineNo self._type = _type self.name = name self.argSpec = argSpec self.setToolTip(0, u'Type: %s
Line: %d
Extra: %s' \ % (_type, lineNo, argSpec)) @property def cfg(self): return self.editor.cfg def activate(self): """ desc: Is called when the symbol is activated, to focus the symbol in the editor. """ self.editor.setCursorPosition(self.lineNo-1, 0) self.editor.focusTab() PKr\GgQProgEdit/symbols/_python.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import re def python(script): """ desc: Extracts the symbols from a Python script. arguments: script: desc: A Python script. type: unicode returns: desc: A list of symbols, where each symbol is a (lineNr, type, name, argSpec) tuple. Type is always 'class' or 'def'. type: list """ regexp = \ r'\s*(?Pdef|class)\s+(?P\w+)\((?P[^\)]*)\){0,1}\s*:{0,1}' symbols = [] for lineNo, line in enumerate(script.split(u'\n')): m = re.match(regexp, line) if m is not None: symbols.append( (lineNo+1, m.group(u'type'), m.group(u'name'), m.group(u'argspec')) ) return symbols PK.?,E!BSMQProgEdit/symbols/__init__.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.symbols._python import python PK N[Cs#CCQProgEdit/ui/_widgetprefs.py# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'resources/ui/prefsWidget.ui' # # Created: Sun Oct 27 10:48:20 2013 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_widgetPrefs(object): def setupUi(self, widgetPrefs): widgetPrefs.setObjectName(_fromUtf8("widgetPrefs")) widgetPrefs.resize(573, 267) widgetPrefs.setAutoFillBackground(True) self.gridLayout = QtGui.QGridLayout(widgetPrefs) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.checkBoxWordWrapMarker = QtGui.QCheckBox(widgetPrefs) self.checkBoxWordWrapMarker.setObjectName(_fromUtf8("checkBoxWordWrapMarker")) self.gridLayout.addWidget(self.checkBoxWordWrapMarker, 13, 1, 1, 1) self.labelTabWidth = QtGui.QLabel(widgetPrefs) self.labelTabWidth.setObjectName(_fromUtf8("labelTabWidth")) self.gridLayout.addWidget(self.labelTabWidth, 2, 0, 1, 1) self.spinBoxTabWidth = QtGui.QSpinBox(widgetPrefs) self.spinBoxTabWidth.setObjectName(_fromUtf8("spinBoxTabWidth")) self.gridLayout.addWidget(self.spinBoxTabWidth, 2, 1, 1, 1) self.labelFontFamily = QtGui.QLabel(widgetPrefs) self.labelFontFamily.setObjectName(_fromUtf8("labelFontFamily")) self.gridLayout.addWidget(self.labelFontFamily, 0, 0, 1, 1) self.checkBoxShowWhitespace = QtGui.QCheckBox(widgetPrefs) self.checkBoxShowWhitespace.setObjectName(_fromUtf8("checkBoxShowWhitespace")) self.gridLayout.addWidget(self.checkBoxShowWhitespace, 6, 1, 1, 1) self.checkBoxLineNumbers = QtGui.QCheckBox(widgetPrefs) self.checkBoxLineNumbers.setObjectName(_fromUtf8("checkBoxLineNumbers")) self.gridLayout.addWidget(self.checkBoxLineNumbers, 4, 1, 1, 1) self.checkBoxWordWrap = QtGui.QCheckBox(widgetPrefs) self.checkBoxWordWrap.setObjectName(_fromUtf8("checkBoxWordWrap")) self.gridLayout.addWidget(self.checkBoxWordWrap, 7, 0, 1, 1) self.checkBoxShowFolding = QtGui.QCheckBox(widgetPrefs) self.checkBoxShowFolding.setObjectName(_fromUtf8("checkBoxShowFolding")) self.gridLayout.addWidget(self.checkBoxShowFolding, 13, 0, 1, 1) self.checkBoxAutoComplete = QtGui.QCheckBox(widgetPrefs) self.checkBoxAutoComplete.setObjectName(_fromUtf8("checkBoxAutoComplete")) self.gridLayout.addWidget(self.checkBoxAutoComplete, 14, 0, 1, 1) self.fontComboBoxFontFamily = QtGui.QFontComboBox(widgetPrefs) self.fontComboBoxFontFamily.setObjectName(_fromUtf8("fontComboBoxFontFamily")) self.gridLayout.addWidget(self.fontComboBoxFontFamily, 0, 1, 1, 1) self.checkBoxShowEol = QtGui.QCheckBox(widgetPrefs) self.checkBoxShowEol.setObjectName(_fromUtf8("checkBoxShowEol")) self.gridLayout.addWidget(self.checkBoxShowEol, 5, 1, 1, 1) self.checkBoxShowIndent = QtGui.QCheckBox(widgetPrefs) self.checkBoxShowIndent.setObjectName(_fromUtf8("checkBoxShowIndent")) self.gridLayout.addWidget(self.checkBoxShowIndent, 7, 1, 1, 1) self.labelFontSize = QtGui.QLabel(widgetPrefs) self.labelFontSize.setObjectName(_fromUtf8("labelFontSize")) self.gridLayout.addWidget(self.labelFontSize, 1, 0, 1, 1) self.spinBoxFontSize = QtGui.QSpinBox(widgetPrefs) self.spinBoxFontSize.setObjectName(_fromUtf8("spinBoxFontSize")) self.gridLayout.addWidget(self.spinBoxFontSize, 1, 1, 1, 1) self.checkBoxHighlightCurrentLine = QtGui.QCheckBox(widgetPrefs) self.checkBoxHighlightCurrentLine.setObjectName(_fromUtf8("checkBoxHighlightCurrentLine")) self.gridLayout.addWidget(self.checkBoxHighlightCurrentLine, 4, 0, 1, 1) self.checkBoxHighlightMatchingBrackets = QtGui.QCheckBox(widgetPrefs) self.checkBoxHighlightMatchingBrackets.setObjectName(_fromUtf8("checkBoxHighlightMatchingBrackets")) self.gridLayout.addWidget(self.checkBoxHighlightMatchingBrackets, 5, 0, 1, 1) self.checkBoxAutoIndent = QtGui.QCheckBox(widgetPrefs) self.checkBoxAutoIndent.setObjectName(_fromUtf8("checkBoxAutoIndent")) self.gridLayout.addWidget(self.checkBoxAutoIndent, 6, 0, 1, 1) self.comboBoxColorScheme = QtGui.QComboBox(widgetPrefs) self.comboBoxColorScheme.setObjectName(_fromUtf8("comboBoxColorScheme")) self.gridLayout.addWidget(self.comboBoxColorScheme, 3, 1, 1, 1) self.labelColorScheme = QtGui.QLabel(widgetPrefs) self.labelColorScheme.setObjectName(_fromUtf8("labelColorScheme")) self.gridLayout.addWidget(self.labelColorScheme, 3, 0, 1, 1) self.retranslateUi(widgetPrefs) QtCore.QMetaObject.connectSlotsByName(widgetPrefs) def retranslateUi(self, widgetPrefs): widgetPrefs.setWindowTitle(_translate("widgetPrefs", "Form", None)) self.checkBoxWordWrapMarker.setText(_translate("widgetPrefs", "Show 80 character word-wrap marker", None)) self.labelTabWidth.setText(_translate("widgetPrefs", "Tab width", None)) self.spinBoxTabWidth.setSuffix(_translate("widgetPrefs", " characters", None)) self.labelFontFamily.setText(_translate("widgetPrefs", "Font family", None)) self.checkBoxShowWhitespace.setText(_translate("widgetPrefs", "Show whitespace", None)) self.checkBoxLineNumbers.setText(_translate("widgetPrefs", "Show line numbers", None)) self.checkBoxWordWrap.setText(_translate("widgetPrefs", "Enable word wrapping", None)) self.checkBoxShowFolding.setText(_translate("widgetPrefs", "Enable block folding", None)) self.checkBoxAutoComplete.setText(_translate("widgetPrefs", "Enable automatic completion", None)) self.checkBoxShowEol.setText(_translate("widgetPrefs", "Show end-of-lines", None)) self.checkBoxShowIndent.setText(_translate("widgetPrefs", "Show indentation", None)) self.labelFontSize.setText(_translate("widgetPrefs", "Font size", None)) self.spinBoxFontSize.setSuffix(_translate("widgetPrefs", " pt", None)) self.checkBoxHighlightCurrentLine.setText(_translate("widgetPrefs", "Highlight current line", None)) self.checkBoxHighlightMatchingBrackets.setText(_translate("widgetPrefs", "Highlight matching brackets", None)) self.checkBoxAutoIndent.setText(_translate("widgetPrefs", "Enable automatic indentation", None)) self.labelColorScheme.setText(_translate("widgetPrefs", "Color scheme", None)) PKr\GQProgEdit/ui/findWidget.ui widgetFind 0 0 625 154 Form true 2 2 Replace: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter Find: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 2 0 Search Replace Replace all 2 0 Case sensitive Match whole words QLineEditFind QLineEdit
QProgEdit/_qlineeditfind.h
lineEditFind lineEditReplace pushButtonFind pushButtonReplace pushButtonReplaceAll checkBoxCaseSensitive checkBoxMatchWhole
PKr\GPnnQProgEdit/ui/prefsWidget.ui widgetPrefs 0 0 867 224 Form true 2 2 Enable word wrapping A color scheme for the editor component The tab width for the editor component characters Font family Show indentation The font size for the editor component pt Show end-of-lines Tab width Enable automatic indentation Show line numbers The font font the editor component Font size Highlight current line Highlight matching brackets Comment shortcut A keyboard shortcut, such as Ctrl+Shift+M Show whitespace Enable block folding A keyboard shortcut, such as Ctrl+M Color scheme Enable automatic completion Uncomment shortcut Show 80 character word-wrap marker Validate content fontComboBoxFontFamily spinBoxFontSize spinBoxTabWidth lineEditCommentShortcut lineEditUncommentShortcut comboBoxColorScheme checkBoxHighlightCurrentLine checkBoxHighlightMatchingBrackets checkBoxAutoIndent checkBoxWordWrap checkBoxShowFolding checkBoxAutoComplete checkBoxLineNumbers checkBoxShowEol checkBoxValidate checkBoxShowIndent checkBoxShowWhitespace checkBoxWordWrapMarker PK N[Cu"LHQProgEdit/ui/_widgetfind.py# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'resources/ui/findWidget.ui' # # Created: Sun Oct 27 10:48:19 2013 # by: PyQt4 UI code generator 4.10.3 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_widgetFind(object): def setupUi(self, widgetFind): widgetFind.setObjectName(_fromUtf8("widgetFind")) widgetFind.resize(625, 128) widgetFind.setAutoFillBackground(True) self.gridLayout = QtGui.QGridLayout(widgetFind) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.labelReplace = QtGui.QLabel(widgetFind) self.labelReplace.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.labelReplace.setObjectName(_fromUtf8("labelReplace")) self.gridLayout.addWidget(self.labelReplace, 1, 0, 1, 1) self.labelFind = QtGui.QLabel(widgetFind) self.labelFind.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) self.labelFind.setObjectName(_fromUtf8("labelFind")) self.gridLayout.addWidget(self.labelFind, 0, 0, 1, 1) self.widget = QtGui.QWidget(widgetFind) self.widget.setObjectName(_fromUtf8("widget")) self.horizontalLayout = QtGui.QHBoxLayout(self.widget) self.horizontalLayout.setMargin(0) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.pushButtonFind = QtGui.QPushButton(self.widget) icon = QtGui.QIcon.fromTheme(_fromUtf8("edit-find")) self.pushButtonFind.setIcon(icon) self.pushButtonFind.setObjectName(_fromUtf8("pushButtonFind")) self.horizontalLayout.addWidget(self.pushButtonFind) self.pushButtonReplace = QtGui.QPushButton(self.widget) icon = QtGui.QIcon.fromTheme(_fromUtf8("edit-find-replace")) self.pushButtonReplace.setIcon(icon) self.pushButtonReplace.setObjectName(_fromUtf8("pushButtonReplace")) self.horizontalLayout.addWidget(self.pushButtonReplace) self.pushButtonReplaceAll = QtGui.QPushButton(self.widget) icon = QtGui.QIcon.fromTheme(_fromUtf8("edit-find-replace")) self.pushButtonReplaceAll.setIcon(icon) self.pushButtonReplaceAll.setObjectName(_fromUtf8("pushButtonReplaceAll")) self.horizontalLayout.addWidget(self.pushButtonReplaceAll) self.gridLayout.addWidget(self.widget, 6, 0, 1, 3) self.widget_2 = QtGui.QWidget(widgetFind) self.widget_2.setObjectName(_fromUtf8("widget_2")) self.horizontalLayout_2 = QtGui.QHBoxLayout(self.widget_2) self.horizontalLayout_2.setMargin(0) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.checkBoxCaseSensitive = QtGui.QCheckBox(self.widget_2) self.checkBoxCaseSensitive.setObjectName(_fromUtf8("checkBoxCaseSensitive")) self.horizontalLayout_2.addWidget(self.checkBoxCaseSensitive) self.checkBoxMatchWhole = QtGui.QCheckBox(self.widget_2) self.checkBoxMatchWhole.setObjectName(_fromUtf8("checkBoxMatchWhole")) self.horizontalLayout_2.addWidget(self.checkBoxMatchWhole) self.gridLayout.addWidget(self.widget_2, 3, 0, 1, 2) self.lineEditReplace = QtGui.QLineEdit(widgetFind) self.lineEditReplace.setObjectName(_fromUtf8("lineEditReplace")) self.gridLayout.addWidget(self.lineEditReplace, 1, 1, 1, 1) self.lineEditFind = QtGui.QLineEdit(widgetFind) self.lineEditFind.setObjectName(_fromUtf8("lineEditFind")) self.gridLayout.addWidget(self.lineEditFind, 0, 1, 1, 1) self.retranslateUi(widgetFind) QtCore.QMetaObject.connectSlotsByName(widgetFind) def retranslateUi(self, widgetFind): widgetFind.setWindowTitle(_translate("widgetFind", "Form", None)) self.labelReplace.setText(_translate("widgetFind", "Replace:", None)) self.labelFind.setText(_translate("widgetFind", "Find:", None)) self.pushButtonFind.setText(_translate("widgetFind", "Search", None)) self.pushButtonReplace.setText(_translate("widgetFind", "Replace", None)) self.pushButtonReplaceAll.setText(_translate("widgetFind", "Replace all", None)) self.checkBoxCaseSensitive.setText(_translate("widgetFind", "Case sensitive", None)) self.checkBoxMatchWhole.setText(_translate("widgetFind", "Match whole words", None)) PKAVQProgEdit/ui/__init__.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from _widgetfind import Ui_widgetFind from _widgetprefs import Ui_widgetPrefsPKэcDzzQProgEdit/clean/_python.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit import _ def python(script): """ Cleans a Python script. Essentially, this means changing leading spaces into tabs, to avoid indentation issues. Arguments: script -- A piece of Python script. Returns: A (msg, script) tuple, where the msg describes the changes to the text and script is the cleaned script. If no changes have been performed, msg is None. """ cleanLines = [] for l in script.split(u'\n'): indent = 0 while l.startswith(u' '): indent += 1 l = l[4:] cleanLines.append(u'\t'*indent + l) cleanScript = u'\n'.join(cleanLines) if cleanScript != script: msg = \ _(u'Convert space-based indentation to tab-based indentation?') else: msg = None return msg, cleanScript PK.?,EWtYQProgEdit/clean/__init__.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.clean._python import python PKr\GQProgEdit/validate/_python.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ import _ast try: from pyflakes.checker import Checker # Check whether PyFlakes supports the builtins keyword try: Checker(compile(u'', u'', u'exec', _ast.PyCF_ONLY_AST), \ builtins=None) pyflakesBuiltins = True except TypeError: pyflakesBuiltins = False except: Checker = None _builtins = [] _filter = None def addPythonBuiltins(builtins): """ Adds a number of names that should be interpreted as builtins, and not trigger a warning. Argument: builtins -- A list of names. """ global _builtins _builtins += builtins def setPyFlakesFilter(func): """ Set a filter for PyFlake warning messages. This filter should be a function that takes a single message, and returns False if the message should be ignored (True otherwise.) Argument: func -- The filter function. """ global _filter _filter = func def python(script): """ Validates a Python script using pyflakes. Arguments: script -- The script to validate. Returns: A list of (line number, message) tuples contain all warnings. """ l = [] try: c = compile(script, u'', u'exec', _ast.PyCF_ONLY_AST) except SyntaxError as e: return [ (e.lineno-1, e.args[0]) ] else: if Checker is None: return [] # Older version of PyFlakes don't support the builtins keyword, and # we don't want to crash on that. if pyflakesBuiltins: messages = Checker(c, builtins=_builtins).messages else: messages = Checker(c).messages for msg in messages: if _filter is None or not _filter(msg): l.append((msg.lineno-1, msg.message % msg.message_args)) return l PKr\GivQProgEdit/validate/__init__.py#-*- coding:utf-8 -*- """ This file is part of QProgEdit. QProgEdit is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QProgEdit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QProgEdit. If not, see . """ from QProgEdit.validate._python import python, addPythonBuiltins, \ setPyFlakesFilter PK|H^- 0python_qprogedit-4.0.0.dist-info/DESCRIPTION.rstUNKNOWN PK|HF+mm.python_qprogedit-4.0.0.dist-info/metadata.json{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: End Users/Desktop", "Topic :: Text Editors", "Environment :: MacOS X", "Environment :: Win32 (MS Windows)", "Environment :: X11 Applications", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3"], "extensions": {"python.details": {"contacts": [{"email": "s.mathot@cogsci.nl", "name": "Sebastiaan Mathot", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/smathot/QProgEdit"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "license": "GNU GPL Version 3", "metadata_version": "2.0", "name": "python-qprogedit", "run_requires": [{"requires": ["qtpy"]}], "summary": "A QScintilla-based text-editor component", "version": "4.0.0"}PK|H[C .python_qprogedit-4.0.0.dist-info/top_level.txtQProgEdit PK|Hndnn&python_qprogedit-4.0.0.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PK|HU)python_qprogedit-4.0.0.dist-info/METADATAMetadata-Version: 2.0 Name: python-qprogedit Version: 4.0.0 Summary: A QScintilla-based text-editor component Home-page: https://github.com/smathot/QProgEdit Author: Sebastiaan Mathot Author-email: s.mathot@cogsci.nl License: GNU GPL Version 3 Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: End Users/Desktop Classifier: Topic :: Text Editors Classifier: Environment :: MacOS X Classifier: Environment :: Win32 (MS Windows) Classifier: Environment :: X11 Applications Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 Requires-Dist: qtpy UNKNOWN PK|H1k? ? 'python_qprogedit-4.0.0.dist-info/RECORDQProgEdit/.directory,sha256=MJ2UjJgvaTOGPAs3vOeJD2UNJenZ429CfeVhT8DXwus,176 QProgEdit/__init__.py,sha256=g7yWt7sJMEdM-EHIGrNkf7CAYfOhoj4fan57FEJnQ0U,2291 QProgEdit/_qcolorscheme.py,sha256=mPc1s0Fexi4VGjlx7lE9JCNzedJHXZkMOOGJ8pep-pc,4326 QProgEdit/_qeditor.py,sha256=vyMUQHv5lqW_BmK6FV63sFSP40tl-_hzLge2zRyhGko,15814 QProgEdit/_qeditorcfg.py,sha256=GQWcqltpnpTXHy4v-x1EtPJbqvUdpruvfYMzaL_PVbI,2243 QProgEdit/_qeditorconst.py,sha256=5GRtWY3reP-DSYsXf8oN-uICffzFeREhIV0-is0_KVw,722 QProgEdit/_qeditorfind.py,sha256=OY_KJvWVNxCkFrvRBNI91y844kWv29zTR7OzKpG7Rwo,4096 QProgEdit/_qeditorprefs.py,sha256=JRJywY1BFe6XEbW6iF6RNX2dwK6Tgnj5ie5IDyedudg,4520 QProgEdit/_qeditorshortcut.py,sha256=TRQ-stXgm9M9DqdmRzLx8WBYgtZ0npFaE3mA8D-i5MM,1023 QProgEdit/_qeditorstatus.py,sha256=CqidbeiAOSViXKOCZo3sVG4dI_Cb56AhIz8EmujCneI,1531 QProgEdit/_qlangmenu.py,sha256=Ckvuk7pN8u2FMlOy9F6VFw2vr230Ww_fpyT3g7PXFic,1628 QProgEdit/_qlexer.py,sha256=U_vGtA766SCJnyxgCFcv7IVDsheoojcZ-KVfOoi7ZBM,5538 QProgEdit/_qlineeditfind.py,sha256=qRBuq1pXpvHsOQvBU25CS0URvwbdfX12AnQ5ajE0SRw,1020 QProgEdit/_qprogedit.py,sha256=BclBl06cpGr82RUSHdTI3UW3CRY5jWGqjfiApUBMvtw,5531 QProgEdit/_qsymboltreewidgetitem.py,sha256=C1-K-AlwZfkUQmQXgWo2y9V3kfhYUlDzZeF_-qFTZpI,1897 QProgEdit/_qtabcornerwidget.py,sha256=zV1Tu0GrogGnWw5sbBMlcghW8XBmmXao4qZ4oQN4mZc,4347 QProgEdit/_qtabmanager.py,sha256=g56-kePak3p_rEojToO8OPwq8Ef_q74zTOgO2TQTBmg,9379 QProgEdit/_quiloader.py,sha256=qH71zKqVSES8X-QwPgHqJ9hlL_knKlnGur84s9y1smE,1422 QProgEdit/py3compat.py,sha256=AOATFryHQiJlUibJFknalxIGsZK_7L0hMX94H7Pq80U,1146 QProgEdit/pyqt5compat.py,sha256=Dxc4YRFMqaLs_2vFHiPXImbvLf43H1JXgwdxBeOkn4A,849 QProgEdit/clean/__init__.py,sha256=SQrLugJkfPuwwF8dKRviEVCxfrBkM_xFsXVtkljPXa4,711 QProgEdit/clean/_python.py,sha256=mMFTidFhALfsymJDpm3uS88cyu5EfCJlaQB9pgTuPEw,1402 QProgEdit/symbols/__init__.py,sha256=5NVITfdWvIr1L7OY-OsrHiK_T3UNSc9yknIZs7LU4VE,713 QProgEdit/symbols/_python.py,sha256=FtukC-Hm72FNpQXlZMJUGLM2c9VoiG0hgtmBGwbpAes,1298 QProgEdit/ui/__init__.py,sha256=dVGfwHBIPHRIUsHpFyUdzu-FVdiEJh_woF-NN4qCtWw,745 QProgEdit/ui/_widgetfind.py,sha256=WwQXXOdFEXTOGOWIRvJEHinaGjL5mn0GUmDnFvKV5Sc,4871 QProgEdit/ui/_widgetprefs.py,sha256=1WC0fzmsgZEvjXD8kWsRV1maHYvptgIVXFa85lLq-Sw,6979 QProgEdit/ui/findWidget.ui,sha256=RInYDzuLmtBkuM69MJEdrrX9CxDGmv4oMH8c8ilL6tg,3989 QProgEdit/ui/prefsWidget.ui,sha256=_2rfrbUUA4ubDlrRhybh4Tsivstt0Fs-WUSyboeDQWg,6510 QProgEdit/validate/__init__.py,sha256=90sGixXo4q0n2JNrGfvQnouffkAB8BO8y1QGzANhMJM,755 QProgEdit/validate/_python.py,sha256=2NpURUavrdV5U_WGMWsTXd9DMq6cb8i16ibQ9_SjrbM,2256 python_qprogedit-4.0.0.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 python_qprogedit-4.0.0.dist-info/METADATA,sha256=wM9YFtrsPdBeS_jNVnoE6GWumSZF-XXojFDYYpIRxRg,729 python_qprogedit-4.0.0.dist-info/RECORD,, python_qprogedit-4.0.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 python_qprogedit-4.0.0.dist-info/metadata.json,sha256=hO4jX-0slAYg9GYoUISkMgV8zsnd5zH_7Vh3swBTulE,877 python_qprogedit-4.0.0.dist-info/top_level.txt,sha256=SbznSmwEiBXkEKFeXkHLReBc4aUo08_pNZ4FPTLGxgU,10 PK|GfHh\\QProgEdit/_qlangmenu.pyPK|GfHc8QProgEdit/_qeditorprefs.pyPK|GfH:Dm==qQProgEdit/_qeditor.pyPKr\G7zzjVQProgEdit/py3compat.pyPKr\GlD[QProgEdit/_qcolorscheme.pyPK5CMr6lQProgEdit/_qeditorconst.pyPK`y|H @oQProgEdit/_qlexer.pyPK|GfH?{2QProgEdit/_qeditorfind.pyPK|GfH["6KQProgEdit/_qeditorcfg.pyPK|GfH,.DQProgEdit/_qprogedit.pyPKHDǰQProgEdit/.directoryPK|GfH+&QProgEdit/_quiloader.pyPK|GfHSQProgEdit/_qeditorshortcut.pyPK|GfH7QProgEdit/_qlineeditfind.pyPK|GfH$$(QProgEdit/_qtabmanager.pyPKmFH!tQQQProgEdit/pyqt5compat.pyPK||H7LQProgEdit/__init__.pyPK|GfHJaQProgEdit/_qtabcornerwidget.pyPK|GfHےQProgEdit/_qeditorstatus.pyPK|GfH\Uii# QProgEdit/_qsymboltreewidgetitem.pyPKr\GgQProgEdit/symbols/_python.pyPK.?,E!BSMQProgEdit/symbols/__init__.pyPK N[Cs#CCQProgEdit/ui/_widgetprefs.pyPKr\G7QProgEdit/ui/findWidget.uiPKr\GPnn^GQProgEdit/ui/prefsWidget.uiPK N[Cu"LHaQProgEdit/ui/_widgetfind.pyPKAVEtQProgEdit/ui/__init__.pyPKэcDzzdwQProgEdit/clean/_python.pyPK.?,EWtY}QProgEdit/clean/__init__.pyPKr\GQProgEdit/validate/_python.pyPKr\Giv!QProgEdit/validate/__init__.pyPK|H^- 0Ppython_qprogedit-4.0.0.dist-info/DESCRIPTION.rstPK|HF+mm.python_qprogedit-4.0.0.dist-info/metadata.jsonPK|H[C .apython_qprogedit-4.0.0.dist-info/top_level.txtPK|Hndnn&python_qprogedit-4.0.0.dist-info/WHEELPK|HU)ipython_qprogedit-4.0.0.dist-info/METADATAPK|H1k? ? 'python_qprogedit-4.0.0.dist-info/RECORDPK%%