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 |GfHc8 QProgEdit/_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)
PK r\G7z z QProgEdit/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']
PK r\GlD QProgEdit/_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']
PK 5CMr QProgEdit/_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 ?{2 QProgEdit/_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["6 QProgEdit/_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)
PK HDǰ 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 |GfHS QProgEdit/_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 |GfH7 QProgEdit/_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)
PK mFH!tQ Q QProgEdit/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 ||H7L QProgEdit/__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 |GfHJa QProgEdit/_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\Ui i # 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()
PK r\Gg QProgEdit/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!BSM QProgEdit/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#C C QProgEdit/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))
PK r\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
PK r\GPn n QProgEdit/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"LH QProgEdit/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))
PK AV QProgEdit/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 эcDz z QProgEdit/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 .?,EWtY QProgEdit/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
PK r\G QProgEdit/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
PK r\Giv QProgEdit/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^-
0 python_qprogedit-4.0.0.dist-info/DESCRIPTION.rstUNKNOWN
PK |HF+m m . 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 |Hndn n &