Sat, 09 Mar 2019 17:36:44 +0100
Lexer: implemented basic support for sub-styles.
# -*- 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): """ """