diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/scripter.py b/plugins/extensions/pykrita/plugin/plugins/scripter/scripter.py --- a/plugins/extensions/pykrita/plugin/plugins/scripter/scripter.py +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/scripter.py @@ -1,7 +1,8 @@ from PyQt5.QtGui import * from PyQt5.QtWidgets import * +from PyQt5.QtCore import * from krita import * -from scripter import syntax, pythoneditor +from scripter import syntax, pythoneditor, settingsdialog, syntaxstyles import sys class docWrapper: @@ -44,19 +45,31 @@ sys.stdout = stdout sys.stderr = stderr + def openSettings(self): + self.settingsDialog = settingsdialog.SettingsDialog(self) + self.settingsDialog.setWindowModality(Qt.WindowModal) + self.settingsDialog.setFixedSize(400, 250) + self.settingsDialog.show() + self.settingsDialog.exec() + def showScripter(self): dialog = QDialog() dialog.setWindowModality(Qt.NonModal) self.editor = pythoneditor.CodeEditor() f = QFont("monospace", 10, QFont.Normal) f.setFixedPitch(True) self.editor.document().setDefaultFont(f) - highlight = syntax.PythonHighlighter(self.editor.document()) + self.highlight = syntax.PythonHighlighter(self.editor.document(), syntaxstyles.DefaultSyntaxStyle()) vbox = QVBoxLayout(dialog) vbox.addWidget(self.editor) - button = QPushButton("Execute") + buttonLayout = QHBoxLayout() + button = QPushButton("Run") + settingsButton = QPushButton("Settings") button.clicked.connect(self.execute) - vbox.addWidget(button) + settingsButton.clicked.connect(self.openSettings) + buttonLayout.addWidget(button) + buttonLayout.addWidget(settingsButton) + vbox.addLayout(buttonLayout) self.output = QPlainTextEdit() vbox.addWidget(self.output) dialog.resize(400, 500) diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/settingsdialog.py b/plugins/extensions/pykrita/plugin/plugins/scripter/settingsdialog.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/settingsdialog.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from PyQt5.QtWidgets import * +from scripter import syntaxstylescombobox + + +class SettingsDialog(QDialog): + + def __init__(self, scripter, parent=None): + super(SettingsDialog, self).__init__(parent) + + self.scripter = scripter + self.mainLayout = QFormLayout(self) + self.mainLayout.addRow('Syntax Highlither', syntaxstylescombobox.SyntaxStylesComboBox(scripter.highlight)) + self.mainLayout.addRow('Fonts', QComboBox()) + self.mainLayout.addRow('BackGoud Color', QComboBox()) diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/syntax.py b/plugins/extensions/pykrita/plugin/plugins/scripter/syntax.py --- a/plugins/extensions/pykrita/plugin/plugins/scripter/syntax.py +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/syntax.py @@ -2,37 +2,8 @@ import sys -from PyQt5.QtCore import QRegExp -from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter - -def format(color, style=''): - """Return a QTextCharFormat with the given attributes. - """ - _color = QColor() - _color.setNamedColor(color) - - _format = QTextCharFormat() - _format.setForeground(_color) - if 'bold' in style: - _format.setFontWeight(QFont.Bold) - if 'italic' in style: - _format.setFontItalic(True) - - return _format - - -# Syntax styles that can be shared by all languages -STYLES = { - 'keyword': format('cyan'), - 'operator': format('orange'), - 'brace': format('gray'), - 'defclass': format('black', 'bold'), - 'string': format('magenta'), - 'string2': format('darkMagenta'), - 'comment': format('darkGreen', 'italic'), - 'self': format('black', 'italic'), - 'numbers': format('brown'), -} +from PyQt5.QtCore import * +from PyQt5.QtGui import * class PythonHighlighter (QSyntaxHighlighter): @@ -65,47 +36,50 @@ braces = [ '\{', '\}', '\(', '\)', '\[', '\]', ] - def __init__(self, document): + def __init__(self, document, syntaxStyle): QSyntaxHighlighter.__init__(self, document) + self.syntaxStyle = syntaxStyle + self.document = document + # Multi-line strings (expression, flag, style) # FIXME: The triple-quotes in these two lines will mess up the # syntax highlighting from this point onward - self.tri_single = (QRegExp("'''"), 1, STYLES['string2']) - self.tri_double = (QRegExp('"""'), 2, STYLES['string2']) + self.tri_single = (QRegExp("'''"), 1, self.syntaxStyle['string2']) + self.tri_double = (QRegExp('"""'), 2, self.syntaxStyle['string2']) rules = [] # Keyword, operator, and brace rules - rules += [(r'\b%s\b' % w, 0, STYLES['keyword']) + rules += [(r'\b%s\b' % w, 0, self.syntaxStyle['keyword']) for w in PythonHighlighter.keywords] - rules += [(r'%s' % o, 0, STYLES['operator']) + rules += [(r'%s' % o, 0, self.syntaxStyle['operator']) for o in PythonHighlighter.operators] - rules += [(r'%s' % b, 0, STYLES['brace']) + rules += [(r'%s' % b, 0, self.syntaxStyle['brace']) for b in PythonHighlighter.braces] # All other rules rules += [ # 'self' - (r'\bself\b', 0, STYLES['self']), + (r'\bself\b', 0, self.syntaxStyle['self']), # Double-quoted string, possibly containing escape sequences - (r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']), + (r'"[^"\\]*(\\.[^"\\]*)*"', 0, self.syntaxStyle['string']), # Single-quoted string, possibly containing escape sequences - (r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']), + (r"'[^'\\]*(\\.[^'\\]*)*'", 0, self.syntaxStyle['string']), # 'def' followed by an identifier - (r'\bdef\b\s*(\w+)', 1, STYLES['defclass']), + (r'\bdef\b\s*(\w+)', 1, self.syntaxStyle['defclass']), # 'class' followed by an identifier - (r'\bclass\b\s*(\w+)', 1, STYLES['defclass']), + (r'\bclass\b\s*(\w+)', 1, self.syntaxStyle['defclass']), # From '#' until a newline - (r'#[^\n]*', 0, STYLES['comment']), + (r'#[^\n]*', 0, self.syntaxStyle['comment']), # Numeric literals - (r'\b[+-]?[0-9]+[lL]?\b', 0, STYLES['numbers']), - (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, STYLES['numbers']), - (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']), + (r'\b[+-]?[0-9]+[lL]?\b', 0, self.syntaxStyle['numbers']), + (r'\b[+-]?0[xX][0-9A-Fa-f]+[lL]?\b', 0, self.syntaxStyle['numbers']), + (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, self.syntaxStyle['numbers']), ] # Build a QRegExp for each pattern @@ -174,3 +148,10 @@ return True else: return False + + def getSyntaxStyle(self): + return self.syntaxStyle + + def setSyntaxStyle(self, syntaxStyle): + self.syntaxStyle = syntaxStyle + PythonHighlighter(self.document, self.syntaxStyle) diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstyles.py b/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstyles.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstyles.py @@ -0,0 +1,58 @@ +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +from PyQt5.QtGui import * + + +def format(color, style='', darker=100, lighter=100): + """Return a QTextCharFormat with the given attributes. + """ + _color = QColor(color) + _color = _color.darker(darker) + _color = _color.lighter(lighter) + + _format = QTextCharFormat() + _format.setForeground(_color) + if 'bold' in style: + _format.setFontWeight(QFont.Bold) + if 'italic' in style: + _format.setFontItalic(True) + + return _format + + +class DefaultSyntaxStyle(object): + + # Syntax styles that combines with dark backgrounds + STYLES = { + 'keyword': format('cyan'), + 'operator': format('orange'), + 'brace': format('gray'), + 'defclass': format('black', 'bold'), + 'string': format('magenta'), + 'string2': format('darkMagenta'), + 'comment': format('darkGreen', 'italic'), + 'self': format('black', 'italic'), + 'numbers': format('brown'), + } + + def __getitem__(self, key): + return self.STYLES[key] + + +class PythonVimSyntaxStyle(object): + """ It based in the colorschemme of the Vim editor for python code http://www.vim.org/scripts/script.php?script_id=790 """ + # Syntax styles that combines with dark backgrounds + STYLES = { + 'keyword': format('yellow', darker=125), + 'operator': format('magenta', darker=150), + 'brace': format('white'), + 'defclass': format('orange', 'bold'), + 'string': format('green', lighter=160), + 'string2': format('lightGray', 'italic', darker=120), + 'comment': format('gray', 'italic'), + 'self': format('blue', lighter=170), + 'numbers': format('yellow', lighter=130), + } + + def __getitem__(self, key): + return self.STYLES[key] diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstylescombobox.py b/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstylescombobox.py new file mode 100644 --- /dev/null +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/syntaxstylescombobox.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +from PyQt5.QtWidgets import * +from scripter import syntaxstyles +import importlib + + +class SyntaxStylesComboBox(QComboBox): + + def __init__(self, highlight, parent=None): + super(SyntaxStylesComboBox, self).__init__(parent) + + self.highlight = highlight + self.styleClasses = [syntaxstyles.DefaultSyntaxStyle, syntaxstyles.PythonVimSyntaxStyle] + + for styleClass in self.styleClasses: + className = styleClass.__name__ + self.addItem(className) + + if className == type(self.highlight.getSyntaxStyle()).__name__: + self.setCurrentIndex(self.findText(className)) + + self.currentIndexChanged.connect(self._currentIndexChanged) + + def _currentIndexChanged(self, index): + self.highlight.setSyntaxStyle(getattr(syntaxstyles, self.itemText(index))()) + self.highlight.rehighlight()