QScintilla/Lexers/SubstyledLexer.py

branch
sub_styles
changeset 6845
4680adb641e0
child 6846
6ca9ef2c0907
equal deleted inserted replaced
6844:d706eb5bc040 6845:4680adb641e0
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2003 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the lexer mixin class.
8 """
9
10 from __future__ import unicode_literals
11
12 import copy
13
14 from PyQt5.QtGui import QColor
15
16 from .Lexer import Lexer
17
18 import Preferences
19
20
21 class SubstyledLexer(Lexer):
22 """
23 Class to implement the sub-styled lexer mixin class.
24 """
25 def __init__(self):
26 """
27 Constructor
28 """
29 super(SubstyledLexer, self).__init__()
30
31 self.baseStyles = [] # list of style numbers, that support
32 # sub-styling
33 self.defaultSubStyles = {}
34 # dictionary with sub-styling data
35 # main key: base style number, value : dictionary with
36 # 'SubStyleLength': int
37 # 'SubStyles': list of dict with
38 # 'Description': string containing a short description
39 # 'Words': string of whitespace separated words to be styled
40 # 'Style': dictionary with styling data (only difference to the
41 # base style is required
42 # 'fore': foreground color (int containing RGB values)
43 # 'paper': background color (int containing RGB values)
44 # 'eolfill': fill to eol (bool)
45 # 'font_family': font family (str)
46 # 'font_size: point size (int)
47 # 'font_bold: bold font (bool)
48 # 'font_italic: italic font (bool)
49 # 'font_underline: underlined font (bool)
50
51 self.subStyles = {}
52 self.__subStylesInitialized = False
53
54 def loadSubstyles(self):
55 """
56 Public method to load the sub-styles from the settings file
57 """
58 settings = Preferences.Prefs.settings
59
60 self.loadDefaultSubStyles()
61
62 for baseStyle in self.baseStyles:
63 key = "Scintilla/{0}/style{1}/SubStyleLength".format(
64 self.language(), baseStyle)
65 if settings.contains(key):
66 subStyleLength = int(settings.value(key), 0)
67 self.subStyles[baseStyle] = {}
68 self.subStyles[baseStyle]["SubStyleLength"] = subStyleLength
69 if subStyleLength:
70 self.subStyles[baseStyle]["SubStyles"] = []
71 for subStyle in range(subStyleLength):
72 baseKey = "Scintilla/{0}/style{1}/substyle{2}/".format(
73 self.language(), baseStyle, subStyle)
74 subStyleData = {}
75 subStyleData["Description"] = settings.value(
76 baseKey + "Description", "")
77 subStyleData["Words"] = settings.value(
78 baseKey + "Words", "")
79 style = {}
80
81 key = baseKey + "fore"
82 if settings.contains(key):
83 style["fore"] = int(settings.value(key))
84 key = baseKey + "paper"
85 if settings.contains(key):
86 style["paper"] = int(settings.value(key))
87 key = baseKey + "eolfill"
88 if settings.contains(key):
89 style["eolfill"] = Preferences.toBool(
90 settings.value(key))
91 key = baseKey + "font_family"
92 if settings.contains(key):
93 style["font_family"] = settings.value(key)
94 key = baseKey + "font_size"
95 if settings.contains(key):
96 style["font_size"] = int(settings.value(key))
97 key = baseKey + "font_bold"
98 if settings.contains(key):
99 style["font_bold"] = Preferences.toBool(
100 settings.value(key))
101 key = baseKey + "font_italic"
102 if settings.contains(key):
103 style["font_italic"] = Preferences.toBool(
104 settings.value(key))
105 key = baseKey + "font_underline"
106 if settings.contains(key):
107 style["font_underline"] = Preferences.toBool(
108 settings.value(key))
109
110 subStyleData["Style"] = style
111
112 def loadDefaultSubStyles(self):
113 """
114 Public method to load the default sub-style definitions.
115 """
116 self.subStyles = copy.deepcopy(self.defaultSubStyles)
117
118 def readSubstyles(self, editor):
119 """
120 Public method to load the sub-styles and configure the editor.
121
122 @param editor reference to the editor object
123 @type QsciScintilla
124 """
125 subStyleBasesLength = editor.SendScintilla(
126 editor.SCI_GETSUBSTYLEBASES, 0, None)
127 if not subStyleBasesLength:
128 # lexer does not support sub-styling
129 return
130
131 self.loadSubstyles()
132
133 # free existing sub-styles first
134 editor.SendScintilla(editor.SCI_FREESUBSTYLES)
135 subStyleBases = b"\00" * (subStyleBasesLength + 1)
136 editor.SendScintilla(editor.SCI_GETSUBSTYLEBASES, 0, subStyleBases)
137 distanceToSecondary = editor.SendScintilla(
138 editor.SCI_DISTANCETOSECONDARYSTYLES)
139
140 subStyleBases = [b for b in bytearray(subStyleBases[:-1])]
141 if distanceToSecondary:
142 subStyleBases.extend(b + distanceToSecondary for b in subStyleBases[:])
143 for baseStyleNo in subStyleBases:
144 if baseStyleNo in self.subStyles:
145 subStylesData = self.subStyles[baseStyleNo]
146 subStyleLength = subStylesData["SubStyleLength"]
147 subStyleStart = editor.SendScintilla(
148 editor.SCI_ALLOCATESUBSTYLES, baseStyleNo, subStyleLength)
149 if subStyleStart < 0:
150 subStyleLength = 0
151 for subStyleIndex in range(subStyleLength):
152 subStyle = subStylesData["SubStyles"][subStyleIndex]
153 # set the words
154 editor.SendScintilla(
155 editor.SCI_SETIDENTIFIERS,
156 subStyleStart + subStyleIndex,
157 subStyle["Words"].encode())
158
159 # set the style
160 styleNo = subStyleStart + subStyleIndex
161 style = subStyle["Style"]
162 if "fore" in style:
163 color = QColor(
164 style["fore"] >> 16 & 0xff,
165 style["fore"] >> 8 & 0xff,
166 style["fore"] & 0xff,
167 )
168 else:
169 color = self.color(baseStyleNo)
170 self.setColor(color, styleNo)
171 if "paper" in style:
172 color = QColor(
173 style["paper"] >> 16 & 0xff,
174 style["paper"] >> 8 & 0xff,
175 style["paper"] & 0xff,
176 )
177 else:
178 color = self.paper(baseStyleNo)
179 self.setPaper(color, styleNo)
180 if "eolfill" in style:
181 eolFill = style["eolFill"]
182 else:
183 eolFill = self.eolFill(baseStyleNo)
184 self.setEolFill(eolFill, styleNo)
185 font = self.font(baseStyleNo)
186 if "font_family" in style:
187 font.setFamily(style["font_family"])
188 if "font_size" in style:
189 font.setPointSize(style["font_size"])
190 if "font_bold" in style:
191 font.setBold(style["font_bold"])
192 if "font_italic" in style:
193 font.setItalic(style["font_italic"])
194 if "font_underline" in style:
195 font.setUnderline(style["font_underline"])
196 self.setFont(font, styleNo)
197
198 def writeSubstyles(self):
199 """
200 Public method to save the sub-styles.
201 """
202
203 def hasSubStyles(self):
204 """
205 Public method to indicate the support of sub-styles.
206
207 @return flag indicating sub-styling support
208 @rtype bool
209 """
210 return True
211
212 def setSubstyleDescription(self, description, style, substyle):
213 """
214
215 """
216
217 def substyleDescription(self, style, substyle):
218 """
219
220 """
221
222 def setSubstyleColor(self, color, style, substyle):
223 """
224
225 """
226
227 def substyleColor(self, style, substyle):
228 """
229
230 """
231
232 def setSubstylePaper(self, color, style, substyle):
233 """
234
235 """
236
237 def substylePaper(self, style, substyle):
238 """
239
240 """
241
242 def setSubstyleEolFill(self, eolFill, style, substyle):
243 """
244
245 """
246
247 def substyleEolFill(self, style, substyle):
248 """
249
250 """
251
252 def setSubstyleFont(self, font, style, substyle):
253 """
254
255 """
256
257 def substyleFont(self, style, substyle):
258 """
259
260 """
261
262 def substyleDefaultDescription(self, style, substyle):
263 """
264
265 """
266
267 def substyleDefaultColor(self, style, substyle):
268 """
269
270 """
271
272 def substyleDefaultPaper(self, style, substyle):
273 """
274
275 """
276
277 def substyleDefaultEolFill(self, style, substyle):
278 """
279
280 """
281
282 def substyleDefaultFont(self, style, substyle):
283 """
284
285 """

eric ide

mercurial