Tue, 12 Mar 2019 20:00:30 +0100
SubstyledLexer: continued implementing the getter and setter methods.
--- a/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py Mon Mar 11 19:50:50 2019 +0100 +++ b/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py Tue Mar 12 20:00:30 2019 +0100 @@ -134,6 +134,7 @@ self.__styleAllItems() self.styleElementList.setCurrentRow(0) + # TODO: remove this once done def __styleForRow(self, row): """ Private method to get the style number of the item of a given row. @@ -146,16 +147,32 @@ itm = self.styleElementList.item(row) return itm.data(self.StyleRole) + def __stylesForRow(self, row): + """ + Private method to get the style and sub-style number of the item of + a given row. + + @param row row number + @type int + @return tuple containing the style and sub-style numbers + @rtype tuple of (int,int) + """ + itm = self.styleElementList.item(row) + style = itm.data(self.StyleRole) + substyle = itm.data(self.SubstyleRole) + + return (style, substyle) + def __styleAllItems(self): """ Private method to style all items of the style element list. """ for row in range(self.styleElementList.count()): - style = self.__styleForRow(row) - colour = self.lexer.color(style) - paper = self.lexer.paper(style) - font = self.lexer.font(style) - eolfill = self.lexer.eolFill(style) + style, substyle = self.__stylesForRow(row) + colour = self.lexer.color(style, substyle) + paper = self.lexer.paper(style, substyle) + font = self.lexer.font(style, substyle) + eolfill = self.lexer.eolFill(style, substyle) itm = self.styleElementList.item(row) itm.setFont(font) @@ -176,7 +193,7 @@ if row < 0: return - self.style = self.__styleForRow(row) + self.style = self.__styleForRow(row) # TODO: get rid of self.style colour = self.lexer.color(self.style) paper = self.lexer.paper(self.style) eolfill = self.lexer.eolFill(self.style)
--- a/Preferences/PreferencesLexer.py Mon Mar 11 19:50:50 2019 +0100 +++ b/Preferences/PreferencesLexer.py Tue Mar 12 20:00:30 2019 +0100 @@ -9,8 +9,8 @@ from __future__ import unicode_literals -from PyQt5.QtCore import QCoreApplication -from PyQt5.Qsci import QsciLexer, QsciScintillaBase +from PyQt5.QtCore import QCoreApplication, QObject +from PyQt5.Qsci import QsciScintillaBase import Preferences import Globals @@ -64,10 +64,10 @@ 'Unsupported Lexer Language: {0}').format(language) -class PreferencesLexer(QsciLexer): +class PreferencesLexer(QObject): """ - Subclass of QsciLexer to implement preferences specific lexer methods and - delegate some methods to the real lexer object. + Class implementing a Lexer facade for the highlighting styles + configuration. """ def __init__(self, language, parent=None): """ @@ -97,14 +97,16 @@ # read the last stored values from preferences file self.__lex.readSettings(Preferences.Prefs.settings, "Scintilla") - # TODO: add substyles + if self.__lex.hasSubStyles(): + self.__lex.loadSubstyles() def writeSettings(self): """ Public method to write the lexer settings. """ self.__lex.writeSettings(Preferences.Prefs.settings, "Scintilla") - # TODO: add substyles + if self.__lex.hasSubStyles(): + self.__lex.writeSubStyles() def getStyles(self): """ @@ -119,33 +121,51 @@ desc = self.__lex.description(i) if desc: styles.append((desc, i, -1)) - # TODO: add substyles + if self.__lex.hasSubStyles(): + for baseStyle in self.__lex.getBaseStyles(): + for subStyle in range(self.__lex.substylesCount(baseStyle)): + desc = self.__lex.substyleDescription(baseStyle, subStyle) + styles.append((desc, baseStyle, subStyle)) return styles - def defaultColor(self, style): + def defaultColor(self, style, substyle=-1): """ Public method to get the default color of a style. @param style style number @type int + @param substyle sub-style number + @type int @return default color @rtype QColor """ - return self.__lex.defaultColor(style) + if substyle >= 0: + color = self.__lex.substyleDefaultColor(style, substyle) + else: + color = self.__lex.defaultColor(style) + + return color - def color(self, style): + def color(self, style, substyle=-1): """ Public method to get the color of a style. @param style style number @type int + @param substyle sub-style number + @type int @return color @rtype QColor """ - return self.__lex.color(style) + if substyle >= 0: + color = self.__lex.substyleColor(style, substyle) + else: + color = self.__lex.color(style) + + return color - def setColor(self, c, style): + def setColor(self, c, style, substyle=-1): """ Public method to set the color for a style. @@ -153,32 +173,51 @@ @type QColor @param style style number @type int + @param substyle sub-style number + @type int """ - self.__lex.setColor(c, style) + if substyle >= 0: + self.__lex.setSubstyleColor(c, style, substyle) + else: + self.__lex.setColor(c, style) - def defaultPaper(self, style): + def defaultPaper(self, style, substyle=-1): """ Public method to get the default background for a style. @param style style number @type int + @param substyle sub-style number + @type int @return default background color @rtype QColor """ - return self.__lex.defaultPaper(style) + if substyle >= 0: + color = self.__lex.substyleDefaultPaper(style, substyle) + else: + color = self.__lex.defaultPaper(style) + + return color - def paper(self, style): + def paper(self, style, substyle=-1): """ Public method to get the background for a style. @param style the style number @type int + @param substyle sub-style number + @type int @return background color @rtype QColor """ - return self.__lex.paper(style) + if substyle >= 0: + color = self.__lex.substylePaper(style, substyle) + else: + color = self.__lex.paper(style) + + return color - def setPaper(self, c, style): + def setPaper(self, c, style, substyle=-1): """ Public method to set the background for a style. @@ -186,32 +225,51 @@ @type QColor @param style style number @type int + @param substyle sub-style number + @type int """ - self.__lex.setPaper(c, style) + if substyle >= 0: + self.__lex.setSubstylePaper(c, style, substyle) + else: + self.__lex.setPaper(c, style) - def defaulEolFill(self, style): + def defaulEolFill(self, style, substyle=-1): """ Public method to get the default eolFill flag for a style. @param style style number @type int + @param substyle sub-style number + @type int @return default eolFill flag @rtype bool """ - return self.__lex.defaultEolFill(style) + if substyle >= 0: + eolFill = self.__lex.substyleDefaultEolFill(style, substyle) + else: + eolFill = self.__lex.defaultEolFill(style) + + return eolFill - def eolFill(self, style): + def eolFill(self, style, substyle=-1): """ Public method to get the eolFill flag for a style. @param style style number @type int + @param substyle sub-style number + @type int @return eolFill flag @rtype bool """ - return self.__lex.eolFill(style) + if substyle >= 0: + eolFill = self.__lex.substyleEolFill(style, substyle) + else: + eolFill = self.__lex.eolFill(style) + + return eolFill - def setEolFill(self, eolfill, style): + def setEolFill(self, eolfill, style, substyle=-1): """ Public method to set the eolFill flag for a style. @@ -219,32 +277,51 @@ @type bool @param style style number @type int + @param substyle sub-style number + @type int """ - self.__lex.setEolFill(eolfill, style) + if substyle >= 0: + self.__lex.setSubstyleEolFill(eolfill, style, substyle) + else: + self.__lex.setEolFill(eolfill, style) - def defaultFont(self, style): + def defaultFont(self, style, substyle=-1): """ Public method to get the default font for a style. @param style style number @type int + @param substyle sub-style number + @type int @return default font @rtype QFont """ - return self.__lex.defaultFont(style) + if substyle >= 0: + font = self.__lex.substyleDefaultFont(style, substyle) + else: + font = self.__lex.defaultFont(style) + + return font - def font(self, style): + def font(self, style, substyle=-1): """ Public method to get the font for a style. @param style style number @type int + @param substyle sub-style number + @type int @return font @rtype QFont """ - return self.__lex.font(style) + if substyle >= 0: + font = self.__lex.substyleFont(style, substyle) + else: + font = self.__lex.font(style) + + return font - def setFont(self, f, style): + def setFont(self, f, style, substyle=-1): """ Public method to set the font for a style. @@ -252,8 +329,26 @@ @type QFont @param style style number @type int + @param substyle sub-style number + @type int """ - self.__lex.setFont(f, style) + if substyle >= 0: + self.__lex.setSubstyleFont(f, style, substyle) + else: + self.__lex.setFont(f, style) + + def description(self, style, substyle=-1): + """ + Public method to get a descriptive string for a style. + + @param style style number + @type int + @param substyle sub-style number + @type int + @return description of the style + @rtype str + """ + return self.__lex.description(style) def language(self): """ @@ -263,14 +358,3 @@ @rtype str """ return self.__lex.language() - - def description(self, style): - """ - Public method to get a descriptive string for a style. - - @param style style number - @type int - @return description of the style - @rtype str - """ - return self.__lex.description(style)
--- a/QScintilla/Lexers/LexerCPP.py Mon Mar 11 19:50:50 2019 +0100 +++ b/QScintilla/Lexers/LexerCPP.py Tue Mar 12 20:00:30 2019 +0100 @@ -50,8 +50,8 @@ self.baseStyles = [11, 17, 75, 81] self.defaultSubStyles = { - 11: [ - { + 11: { + 0: { "Description": QCoreApplication.translate( "LexerCPP", "Extra Identifiers"), "Words": "std map string vector", @@ -59,9 +59,9 @@ "fore": 0xEE00AA, } }, - ], - 17: [ - { + }, + 17: { + 0: { "Description": QCoreApplication.translate( "LexerCPP", "Extra Doc Comment Keywords"), "Words": "check", @@ -69,9 +69,9 @@ "fore": 0x00AAEE, } }, - ], - 75: [ - { + }, + 75: { + 0: { "Description": QCoreApplication.translate( "LexerCPP", "Inactive Extra Identifiers"), "Words": "std map string vector", @@ -79,9 +79,9 @@ "fore": 0xBB6666, } }, - ], - 81: [ - { + }, + 81: { + 0: { "Description": QCoreApplication.translate( "LexerCPP", "Inactive Extra Doc Comment Keywords"), "Words": "check", @@ -89,7 +89,7 @@ "fore": 0x6699AA, } }, - ], + }, } def initProperties(self):
--- a/QScintilla/Lexers/LexerPython.py Mon Mar 11 19:50:50 2019 +0100 +++ b/QScintilla/Lexers/LexerPython.py Tue Mar 12 20:00:30 2019 +0100 @@ -43,8 +43,8 @@ self.baseStyles = [11] self.defaultSubStyles = { - 11: [ - { + 11: { + 0: { "Description": QCoreApplication.translate( "LexerPython", "Standard Library Modules"), "Words": """ @@ -73,7 +73,7 @@ "font_bold": True, } }, - { + 1: { "Description": QCoreApplication.translate( "LexerPython", "__future__ Imports"), "Words": """ @@ -84,7 +84,7 @@ "font_italic": True, } } - ] + }, } def language(self):
--- a/QScintilla/Lexers/SubstyledLexer.py Mon Mar 11 19:50:50 2019 +0100 +++ b/QScintilla/Lexers/SubstyledLexer.py Tue Mar 12 20:00:30 2019 +0100 @@ -28,25 +28,26 @@ """ super(SubstyledLexer, self).__init__() - self.baseStyles = [] # list of style numbers, that support - # sub-styling + self.baseStyles = [] + # list of style numbers, that support sub-styling self.defaultSubStyles = {} # dictionary with sub-styling data - # main key: base style number, value : list of dict with - # 'Description': string containing a short description - # 'Words': string of whitespace separated words to be styled - # 'Style': dictionary with styling data (only difference to the - # base style is required - # 'fore': foreground color (int containing RGB values) - # 'paper': background color (int containing RGB values) - # 'eolfill': fill to eol (bool) - # 'font_family': font family (str) - # 'font_size: point size (int) - # 'font_bold: bold font (bool) - # 'font_italic: italic font (bool) - # 'font_underline: underlined font (bool) + # main key: base style number, value : dict with + # key: sub-style number, value: dict with + # 'Description': string containing a short description + # 'Words': string of whitespace separated words to be styled + # 'Style': dictionary with styling data (only difference to + # the base style is required + # 'fore': foreground color (int containing RGB values) + # 'paper': background color (int containing RGB values) + # 'eolfill': fill to eol (bool) + # 'font_family': font family (str) + # 'font_size: point size (int) + # 'font_bold: bold font (bool) + # 'font_italic: italic font (bool) + # 'font_underline: underlined font (bool) - self.subStyles = {} + self.__subStyles = {} self.__subStylesInitialized = False def loadSubstyles(self): @@ -62,9 +63,9 @@ self.language(), baseStyle) if settings.contains(key): subStyleLength = int(settings.value(key), 0) - self.subStyles[baseStyle] = {} + self.__subStyles[baseStyle] = {} if subStyleLength: - self.subStyles[baseStyle] = [] + self.__subStyles[baseStyle] = [] for subStyle in range(subStyleLength): baseKey = "Scintilla/{0}/style{1}/substyle{2}/".format( self.language(), baseStyle, subStyle) @@ -107,7 +108,8 @@ subStyleData["Style"] = style - self.subStyles[baseStyle].append(subStyleData) + self.__subStyles[baseStyle][subStyle] = \ + subStyleData self.__subStylesInitialized = True @@ -115,7 +117,7 @@ """ Public method to load the default sub-style definitions. """ - self.subStyles = copy.deepcopy(self.defaultSubStyles) + self.__subStyles = copy.deepcopy(self.defaultSubStyles) def readSubstyles(self, editor): """ @@ -144,8 +146,8 @@ subStyleBases.extend(b + distanceToSecondary for b in subStyleBases[:]) for baseStyleNo in subStyleBases: - if baseStyleNo in self.subStyles: - subStylesData = self.subStyles[baseStyleNo] + if baseStyleNo in self.__subStyles: + subStylesData = self.__subStyles[baseStyleNo] subStyleLength = len(subStylesData) subStyleStart = editor.SendScintilla( editor.SCI_ALLOCATESUBSTYLES, baseStyleNo, subStyleLength) @@ -183,7 +185,7 @@ self.setPaper(color, styleNo) if "eolfill" in style: - eolFill = style["eolFill"] + eolFill = style["eolfill"] else: eolFill = self.eolFill(baseStyleNo) self.setEolFill(eolFill, styleNo) @@ -214,11 +216,11 @@ for baseStyle in self.baseStyles: key = "Scintilla/{0}/style{1}/SubStyleLength".format( self.language(), baseStyle) - settings.setValue(key, len(self.subStyles[baseStyle])) - for subStyle in range(len(self.subStyles[baseStyle])): + settings.setValue(key, len(self.__subStyles[baseStyle])) + for subStyle in self.__subStyles[baseStyle]: baseKey = "Scintilla/{0}/style{1}/substyle{2}/".format( self.language(), baseStyle, subStyle) - subStyleData = self.subStyles[baseStyle][subStyle] + subStyleData = self.__subStyles[baseStyle][subStyle] settings.setValue(baseKey + "Description", subStyleData["Description"]) @@ -279,77 +281,424 @@ """ return True + def getBaseStyles(self): + """ + Public method to get the list of supported base styles. + + @return list of base styles + @rtype list of int + """ + return self.baseStyles[:] + + def substylesCount(self, style): + """ + Public method to get the number of defined sub-styles. + + @return number of defined sub-styles + @rtype int + """ + if style in self.__subStyles: + count = len(self.__subStyles[style]) + else: + count = 0 + + return count + def setSubstyleDescription(self, description, style, substyle): """ + Public method to set the description for a sub-style. + @param description description to be set + @type str + @param style base style number + @type int + @param substyle sub-style number + @type int """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Description"] = description def substyleDescription(self, style, substyle): """ + Public method to get the description of a sub-style. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return sub-style description + @rtype str """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + desc = self.__subStyles[style][substyle]["Description"] + else: + desc = "" + + return desc + + def setSubstyleWords(self, words, style, substyle): + """ + Public method to set the words for a sub-style. + + @param words words to be set separated by white-space + @type str + @param style base style number + @type int + @param substyle sub-style number + @type int + """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Words"] = words + + def substyleWords(self, style, substyle): + """ + Public method to get the words of a sub-style. + + @param style base style number + @type int + @param substyle sub-style number + @type int + @return white-space separated word list + @rtype str + """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + words = self.__subStyles[style][substyle]["Words"] + else: + words = "" + + return words def setSubstyleColor(self, color, style, substyle): """ + Public method to set the foreground color of a sub-style. + @param color foreground color to be set + @type QColor + @param style base style number + @type int + @param substyle sub-style number + @type int """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Style"]["fore"] = \ + color.red() << 16 | color.green() << 8 | color.blue() def substyleColor(self, style, substyle): """ + Public method to get the sub-style foreground color. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return foreground color + @rtype QColor """ + color = self.color(style) + + if style in self.__subStyles and substyle in self.__subStyles[style]: + styleData = self.__subStyles[style][substyle]["Style"] + if "fore" in styleData: + color = QColor( + styleData["fore"] >> 16 & 0xff, + styleData["fore"] >> 8 & 0xff, + styleData["fore"] & 0xff, + ) + + return color def setSubstylePaper(self, color, style, substyle): """ + Public method to set the background color of a sub-style. + @param color background color to be set + @type QColor + @param style base style number + @type int + @param substyle sub-style number + @type int """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Style"]["paper"] = \ + color.red() << 16 | color.green() << 8 | color.blue() def substylePaper(self, style, substyle): """ + Public method to get the sub-style background color. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return background color + @rtype QColor """ + color = self.paper(style) + + if style in self.__subStyles and substyle in self.__subStyles[style]: + styleData = self.__subStyles[style][substyle]["Style"] + if "paper" in styleData: + color = QColor( + styleData["paper"] >> 16 & 0xff, + styleData["paper"] >> 8 & 0xff, + styleData["paper"] & 0xff, + ) + + return color def setSubstyleEolFill(self, eolFill, style, substyle): """ + Public method to set the eolfill flag of a sub-style. + @param eolFill eolfill flag to be set + @type bool + @param style base style number + @type int + @param substyle sub-style number + @type int """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Style"]["eolfill"] = \ + eolFill def substyleEolFill(self, style, substyle): """ + Public method to get the eolfill flag. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return eolfill flag + @rtype bool """ + eolFill = self.eolFill(style) + + if style in self.__subStyles and substyle in self.__subStyles[style]: + styleData = self.__subStyles[style][substyle]["Style"] + if "eolfill" in styleData: + eolFill = styleData["eolfill"] + + return eolFill def setSubstyleFont(self, font, style, substyle): """ + Public method to set the font of a sub-style. + @param font font to be set + @type QFont + @param style base style number + @type int + @param substyle sub-style number + @type int """ + if style in self.__subStyles and substyle in self.__subStyles[style]: + self.__subStyles[style][substyle]["Style"]["font_family"] = \ + font.family() + self.__subStyles[style][substyle]["Style"]["font_size"] = \ + font.pointSize() + self.__subStyles[style][substyle]["Style"]["font_bold"] = \ + font.bold() + self.__subStyles[style][substyle]["Style"]["font_italic"] = \ + font.italic() + self.__subStyles[style][substyle]["Style"]["font_underline"] = \ + font.underline() def substyleFont(self, style, substyle): """ + Public method to get the sub-style font. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return font + @rtype QFont """ + font = self.font(style) + + if style in self.__subStyles and substyle in self.__subStyles[style]: + styleData = self.__subStyles[style][substyle]["Style"] + if "font_family" in styleData: + font.setFamily(styleData["font_family"]) + if "font_size" in styleData: + font.setPointSize(styleData["font_size"]) + if "font_bold" in styleData: + font.setBold(styleData["font_bold"]) + if "font_italic" in styleData: + font.setItalic(styleData["font_italic"]) + if "font_underline" in styleData: + font.setUnderline(styleData["font_underline"]) + + return font def substyleDefaultDescription(self, style, substyle): """ + Public method to get the default description of a sub-style. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return sub-style default description + @rtype str """ + description = "" + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + description = styleData["Description"] + + return description + + def substyleDefaultWords(self, style, substyle): + """ + Public method to get the default words of a sub-style. + + @param style base style number + @type int + @param substyle sub-style number + @type int + @return white-space separated default word list + @rtype str + """ + words = "" + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + words = styleData["Words"] + + return words def substyleDefaultColor(self, style, substyle): """ + Public method to get the sub-style default foreground color. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return default foreground color + @rtype QColor """ + color = self.defaultColor(style) + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + if "fore" in styleData: + color = QColor( + styleData["fore"] >> 16 & 0xff, + styleData["fore"] >> 8 & 0xff, + styleData["fore"] & 0xff, + ) + + return color def substyleDefaultPaper(self, style, substyle): """ + Public method to get the sub-style default background color. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return default background color + @rtype QColor """ + color = self.defaultPaper(style) + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + if "paper" in styleData: + color = QColor( + styleData["paper"] >> 16 & 0xff, + styleData["paper"] >> 8 & 0xff, + styleData["paper"] & 0xff, + ) + + return color def substyleDefaultEolFill(self, style, substyle): """ + Public method to get the default eolfill flag. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return default eolfill flag + @rtype bool """ + eolFill = self.defaultEolFill(style) + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + if "eolfill" in styleData: + eolFill = styleData["eolfill"] + + return eolFill def substyleDefaultFont(self, style, substyle): """ + Public method to get the default sub-style font. + @param style base style number + @type int + @param substyle sub-style number + @type int + @return default font + @rtype QFont """ + font = self.defaultFont(style) + + if style in self.defaultSubStyles and \ + substyle in self.defaultSubStyles[style]: + styleData = self.defaultSubStyles[style][substyle]["Style"] + if "font_family" in styleData: + font.setFamily(styleData["font_family"]) + if "font_size" in styleData: + font.setPointSize(styleData["font_size"]) + if "font_bold" in styleData: + font.setBold(styleData["font_bold"]) + if "font_italic" in styleData: + font.setItalic(styleData["font_italic"]) + if "font_underline" in styleData: + font.setUnderline(styleData["font_underline"]) + + return font + + def addSubstyle(self, style): + """ + Public method to add a sub-style to a given base style. + + @param style base style number + @type int + @return allocated sub-style number + @rtype int + """ + # TODO: implement this + # add empty sub-style definition + + def delSubstyle(self, style, substyle): + """ + Public method to delet a given sub-style definition. + + @param style base style number + @type int + @param substyle sub-style number + @type int + @return flag indicating successful deletion + @rtype bool + """ + ok = False + + if style in self.__subStyles and substyle in self.__subStyles[style]: + del self.__subStyles[style][substyle] + ok = True + + return ok