--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/Lexers/SubstyledLexer.py Sat Mar 09 17:36:44 2019 +0100 @@ -0,0 +1,285 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2003 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the lexer mixin class. +""" + +from __future__ import unicode_literals + +import copy + +from PyQt5.QtGui import QColor + +from .Lexer import Lexer + +import Preferences + + +class SubstyledLexer(Lexer): + """ + Class to implement the sub-styled lexer mixin class. + """ + def __init__(self): + """ + Constructor + """ + super(SubstyledLexer, self).__init__() + + self.baseStyles = [] # list of style numbers, that support + # sub-styling + self.defaultSubStyles = {} + # dictionary with sub-styling data + # main key: base style number, value : dictionary with + # 'SubStyleLength': int + # 'SubStyles': 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) + + self.subStyles = {} + self.__subStylesInitialized = False + + def loadSubstyles(self): + """ + Public method to load the sub-styles from the settings file + """ + settings = Preferences.Prefs.settings + + self.loadDefaultSubStyles() + + for baseStyle in self.baseStyles: + key = "Scintilla/{0}/style{1}/SubStyleLength".format( + self.language(), baseStyle) + if settings.contains(key): + subStyleLength = int(settings.value(key), 0) + self.subStyles[baseStyle] = {} + self.subStyles[baseStyle]["SubStyleLength"] = subStyleLength + if subStyleLength: + self.subStyles[baseStyle]["SubStyles"] = [] + for subStyle in range(subStyleLength): + baseKey = "Scintilla/{0}/style{1}/substyle{2}/".format( + self.language(), baseStyle, subStyle) + subStyleData = {} + subStyleData["Description"] = settings.value( + baseKey + "Description", "") + subStyleData["Words"] = settings.value( + baseKey + "Words", "") + style = {} + + key = baseKey + "fore" + if settings.contains(key): + style["fore"] = int(settings.value(key)) + key = baseKey + "paper" + if settings.contains(key): + style["paper"] = int(settings.value(key)) + key = baseKey + "eolfill" + if settings.contains(key): + style["eolfill"] = Preferences.toBool( + settings.value(key)) + key = baseKey + "font_family" + if settings.contains(key): + style["font_family"] = settings.value(key) + key = baseKey + "font_size" + if settings.contains(key): + style["font_size"] = int(settings.value(key)) + key = baseKey + "font_bold" + if settings.contains(key): + style["font_bold"] = Preferences.toBool( + settings.value(key)) + key = baseKey + "font_italic" + if settings.contains(key): + style["font_italic"] = Preferences.toBool( + settings.value(key)) + key = baseKey + "font_underline" + if settings.contains(key): + style["font_underline"] = Preferences.toBool( + settings.value(key)) + + subStyleData["Style"] = style + + def loadDefaultSubStyles(self): + """ + Public method to load the default sub-style definitions. + """ + self.subStyles = copy.deepcopy(self.defaultSubStyles) + + def readSubstyles(self, editor): + """ + Public method to load the sub-styles and configure the editor. + + @param editor reference to the editor object + @type QsciScintilla + """ + subStyleBasesLength = editor.SendScintilla( + editor.SCI_GETSUBSTYLEBASES, 0, None) + if not subStyleBasesLength: + # lexer does not support sub-styling + return + + self.loadSubstyles() + + # free existing sub-styles first + editor.SendScintilla(editor.SCI_FREESUBSTYLES) + subStyleBases = b"\00" * (subStyleBasesLength + 1) + editor.SendScintilla(editor.SCI_GETSUBSTYLEBASES, 0, subStyleBases) + distanceToSecondary = editor.SendScintilla( + editor.SCI_DISTANCETOSECONDARYSTYLES) + + subStyleBases = [b for b in bytearray(subStyleBases[:-1])] + if distanceToSecondary: + subStyleBases.extend(b + distanceToSecondary for b in subStyleBases[:]) + for baseStyleNo in subStyleBases: + if baseStyleNo in self.subStyles: + subStylesData = self.subStyles[baseStyleNo] + subStyleLength = subStylesData["SubStyleLength"] + subStyleStart = editor.SendScintilla( + editor.SCI_ALLOCATESUBSTYLES, baseStyleNo, subStyleLength) + if subStyleStart < 0: + subStyleLength = 0 + for subStyleIndex in range(subStyleLength): + subStyle = subStylesData["SubStyles"][subStyleIndex] + # set the words + editor.SendScintilla( + editor.SCI_SETIDENTIFIERS, + subStyleStart + subStyleIndex, + subStyle["Words"].encode()) + + # set the style + styleNo = subStyleStart + subStyleIndex + style = subStyle["Style"] + if "fore" in style: + color = QColor( + style["fore"] >> 16 & 0xff, + style["fore"] >> 8 & 0xff, + style["fore"] & 0xff, + ) + else: + color = self.color(baseStyleNo) + self.setColor(color, styleNo) + if "paper" in style: + color = QColor( + style["paper"] >> 16 & 0xff, + style["paper"] >> 8 & 0xff, + style["paper"] & 0xff, + ) + else: + color = self.paper(baseStyleNo) + self.setPaper(color, styleNo) + if "eolfill" in style: + eolFill = style["eolFill"] + else: + eolFill = self.eolFill(baseStyleNo) + self.setEolFill(eolFill, styleNo) + font = self.font(baseStyleNo) + if "font_family" in style: + font.setFamily(style["font_family"]) + if "font_size" in style: + font.setPointSize(style["font_size"]) + if "font_bold" in style: + font.setBold(style["font_bold"]) + if "font_italic" in style: + font.setItalic(style["font_italic"]) + if "font_underline" in style: + font.setUnderline(style["font_underline"]) + self.setFont(font, styleNo) + + def writeSubstyles(self): + """ + Public method to save the sub-styles. + """ + + def hasSubStyles(self): + """ + Public method to indicate the support of sub-styles. + + @return flag indicating sub-styling support + @rtype bool + """ + return True + + def setSubstyleDescription(self, description, style, substyle): + """ + + """ + + def substyleDescription(self, style, substyle): + """ + + """ + + def setSubstyleColor(self, color, style, substyle): + """ + + """ + + def substyleColor(self, style, substyle): + """ + + """ + + def setSubstylePaper(self, color, style, substyle): + """ + + """ + + def substylePaper(self, style, substyle): + """ + + """ + + def setSubstyleEolFill(self, eolFill, style, substyle): + """ + + """ + + def substyleEolFill(self, style, substyle): + """ + + """ + + def setSubstyleFont(self, font, style, substyle): + """ + + """ + + def substyleFont(self, style, substyle): + """ + + """ + + def substyleDefaultDescription(self, style, substyle): + """ + + """ + + def substyleDefaultColor(self, style, substyle): + """ + + """ + + def substyleDefaultPaper(self, style, substyle): + """ + + """ + + def substyleDefaultEolFill(self, style, substyle): + """ + + """ + + def substyleDefaultFont(self, style, substyle): + """ + + """