|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2003 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the lexer mixin class. |
|
8 """ |
|
9 |
|
10 import copy |
|
11 |
|
12 from PyQt6.QtGui import QColor |
|
13 |
|
14 from .Lexer import Lexer |
|
15 |
|
16 import Preferences |
|
17 |
|
18 |
|
19 class SubstyledLexer(Lexer): |
|
20 """ |
|
21 Class to implement the sub-styled lexer mixin class. |
|
22 """ |
|
23 def __init__(self): |
|
24 """ |
|
25 Constructor |
|
26 """ |
|
27 super().__init__() |
|
28 |
|
29 self.baseStyles = [] |
|
30 # list of style numbers, that support sub-styling |
|
31 self.defaultSubStyles = {} |
|
32 # dictionary with sub-styling data |
|
33 # main key: base style number, value : dict with |
|
34 # key: sub-style number, value: dict with |
|
35 # 'Description': string containing a short description |
|
36 # 'Words': string of whitespace separated words to be styled |
|
37 # 'Style': dictionary with styling data (only difference to |
|
38 # the base style is required |
|
39 # 'fore': foreground color (int containing RGB values) |
|
40 # 'paper': background color (int containing RGB values) |
|
41 # 'eolfill': fill to eol (bool) |
|
42 # 'font_family': font family (str) |
|
43 # 'font_size: point size (int) |
|
44 # 'font_bold: bold font (bool) |
|
45 # 'font_italic: italic font (bool) |
|
46 # 'font_underline: underlined font (bool) |
|
47 |
|
48 self.__subStyles = {} |
|
49 self.__subStylesInitialized = False |
|
50 |
|
51 def loadAllDefaultSubStyles(self): |
|
52 """ |
|
53 Public method to load the default sub-style definitions. |
|
54 """ |
|
55 self.__subStyles = copy.deepcopy(self.defaultSubStyles) |
|
56 |
|
57 self.__subStylesInitialized = True |
|
58 |
|
59 def loadDefaultSubStyles(self, style): |
|
60 """ |
|
61 Public method to load the default sub-styles for a given base style. |
|
62 |
|
63 @param style style number |
|
64 @type int |
|
65 """ |
|
66 if style in self.defaultSubStyles: |
|
67 self.__subStyles[style] = copy.deepcopy( |
|
68 self.defaultSubStyles[style]) |
|
69 |
|
70 def loadSubstyles(self): |
|
71 """ |
|
72 Public method to load the sub-styles from the settings file. |
|
73 """ |
|
74 settings = Preferences.getSettings() |
|
75 |
|
76 # Step 1: check if sub-styles were defined and saved |
|
77 subStylesDefined = False |
|
78 for baseStyle in self.baseStyles: |
|
79 key = "Scintilla/{0}/style{1}/SubStyleLength".format( |
|
80 self.language(), baseStyle) |
|
81 subStylesDefined |= settings.contains(key) |
|
82 # Step 2.1: load default sub-styles, if none were defined |
|
83 if not subStylesDefined: |
|
84 self.loadAllDefaultSubStyles() |
|
85 |
|
86 # Step 2.2: load from settings file |
|
87 else: |
|
88 self.__subStyles = {} |
|
89 for baseStyle in self.baseStyles: |
|
90 key = "Scintilla/{0}/style{1}/SubStyleLength".format( |
|
91 self.language(), baseStyle) |
|
92 if settings.contains(key): |
|
93 subStyleLength = int(settings.value(key)) |
|
94 if subStyleLength: |
|
95 self.__subStyles[baseStyle] = {} |
|
96 for subStyle in range(subStyleLength): |
|
97 substyleKey = ( |
|
98 "Scintilla/{0}/style{1}/substyle{2}/" |
|
99 ).format(self.language(), baseStyle, subStyle) |
|
100 if settings.contains(substyleKey + "Description"): |
|
101 subStyleData = {} |
|
102 subStyleData["Description"] = settings.value( |
|
103 substyleKey + "Description", "") |
|
104 subStyleData["Words"] = settings.value( |
|
105 substyleKey + "Words", "") |
|
106 style = {} |
|
107 |
|
108 key = substyleKey + "fore" |
|
109 if settings.contains(key): |
|
110 style["fore"] = int(settings.value(key)) |
|
111 key = substyleKey + "paper" |
|
112 if settings.contains(key): |
|
113 style["paper"] = int(settings.value(key)) |
|
114 key = substyleKey + "eolfill" |
|
115 if settings.contains(key): |
|
116 style["eolfill"] = Preferences.toBool( |
|
117 settings.value(key)) |
|
118 key = substyleKey + "font_family" |
|
119 if settings.contains(key): |
|
120 style["font_family"] = settings.value(key) |
|
121 key = substyleKey + "font_size" |
|
122 if settings.contains(key): |
|
123 style["font_size"] = ( |
|
124 int(settings.value(key)) |
|
125 ) |
|
126 key = substyleKey + "font_bold" |
|
127 if settings.contains(key): |
|
128 style["font_bold"] = Preferences.toBool( |
|
129 settings.value(key)) |
|
130 key = substyleKey + "font_italic" |
|
131 if settings.contains(key): |
|
132 style["font_italic"] = Preferences.toBool( |
|
133 settings.value(key)) |
|
134 key = substyleKey + "font_underline" |
|
135 if settings.contains(key): |
|
136 style["font_underline"] = ( |
|
137 Preferences.toBool(settings.value(key)) |
|
138 ) |
|
139 |
|
140 subStyleData["Style"] = style |
|
141 |
|
142 self.__subStyles[baseStyle][subStyle] = ( |
|
143 subStyleData |
|
144 ) |
|
145 |
|
146 else: |
|
147 # initialize with default |
|
148 self.__subStyles[baseStyle][subStyle] = ( |
|
149 copy.deepcopy(self.defaultSubStyles |
|
150 [baseStyle][subStyle]) |
|
151 ) |
|
152 |
|
153 self.__subStylesInitialized = True |
|
154 |
|
155 def readSubstyles(self, editor): |
|
156 """ |
|
157 Public method to load the sub-styles and configure the editor. |
|
158 |
|
159 @param editor reference to the editor object |
|
160 @type QsciScintilla |
|
161 """ |
|
162 subStyleBasesLength = editor.SendScintilla( |
|
163 editor.SCI_GETSUBSTYLEBASES, 0, None) |
|
164 if not subStyleBasesLength: |
|
165 # lexer does not support sub-styling |
|
166 return |
|
167 |
|
168 self.loadSubstyles() |
|
169 |
|
170 # free existing sub-styles first |
|
171 editor.SendScintilla(editor.SCI_FREESUBSTYLES) |
|
172 subStyleBases = b"\00" * (subStyleBasesLength + 1) |
|
173 editor.SendScintilla(editor.SCI_GETSUBSTYLEBASES, 0, subStyleBases) |
|
174 distanceToSecondary = editor.SendScintilla( |
|
175 editor.SCI_DISTANCETOSECONDARYSTYLES) |
|
176 |
|
177 subStyleBases = [b for b in bytearray(subStyleBases[:-1])] |
|
178 if distanceToSecondary: |
|
179 subStyleBases.extend(b + distanceToSecondary |
|
180 for b in subStyleBases[:]) |
|
181 for baseStyleNo in subStyleBases: |
|
182 if baseStyleNo in self.__subStyles: |
|
183 subStylesData = self.__subStyles[baseStyleNo] |
|
184 subStyleLength = len(subStylesData) |
|
185 subStyleStart = editor.SendScintilla( |
|
186 editor.SCI_ALLOCATESUBSTYLES, baseStyleNo, subStyleLength) |
|
187 if subStyleStart < 0: |
|
188 continue |
|
189 |
|
190 for subStyleIndex, subStyleKey in enumerate( |
|
191 sorted(subStylesData.keys()) |
|
192 ): |
|
193 styleNo = subStyleStart + subStyleIndex |
|
194 subStyle = subStylesData[subStyleKey] |
|
195 # set the words |
|
196 editor.SendScintilla( |
|
197 editor.SCI_SETIDENTIFIERS, |
|
198 styleNo, |
|
199 subStyle["Words"].encode()) |
|
200 |
|
201 # set the style |
|
202 style = subStyle["Style"] |
|
203 color = ( |
|
204 QColor( |
|
205 style["fore"] >> 16 & 0xff, |
|
206 style["fore"] >> 8 & 0xff, |
|
207 style["fore"] & 0xff,) |
|
208 if "fore" in style else |
|
209 self.color(baseStyleNo) |
|
210 ) |
|
211 self.setColor(color, styleNo) |
|
212 |
|
213 color = ( |
|
214 QColor( |
|
215 style["paper"] >> 16 & 0xff, |
|
216 style["paper"] >> 8 & 0xff, |
|
217 style["paper"] & 0xff,) |
|
218 if "paper" in style else |
|
219 self.paper(baseStyleNo) |
|
220 ) |
|
221 self.setPaper(color, styleNo) |
|
222 |
|
223 eolFill = ( |
|
224 style["eolfill"] |
|
225 if "eolfill" in style else |
|
226 self.eolFill(baseStyleNo) |
|
227 ) |
|
228 self.setEolFill(eolFill, styleNo) |
|
229 |
|
230 font = self.font(baseStyleNo) |
|
231 if "font_family" in style: |
|
232 font.setFamily(style["font_family"]) |
|
233 if "font_size" in style: |
|
234 font.setPointSize(style["font_size"]) |
|
235 if "font_bold" in style: |
|
236 font.setBold(style["font_bold"]) |
|
237 if "font_italic" in style: |
|
238 font.setItalic(style["font_italic"]) |
|
239 if "font_underline" in style: |
|
240 font.setUnderline(style["font_underline"]) |
|
241 self.setFont(font, styleNo) |
|
242 |
|
243 def writeSubstyles(self): |
|
244 """ |
|
245 Public method to save the sub-styles. |
|
246 """ |
|
247 if not self.__subStylesInitialized: |
|
248 return |
|
249 |
|
250 settings = Preferences.getSettings() |
|
251 |
|
252 # Step 1: remove all sub-style definitions first |
|
253 for baseStyle in self.baseStyles: |
|
254 key = "Scintilla/{0}/style{1}/SubStyleLength".format( |
|
255 self.language(), baseStyle) |
|
256 if settings.contains(key): |
|
257 subStyleLength = int(settings.value(key)) |
|
258 if subStyleLength: |
|
259 for subStyle in range(subStyleLength): |
|
260 substyleKey = ( |
|
261 "Scintilla/{0}/style{1}/substyle{2}/" |
|
262 ).format(self.language(), baseStyle, subStyle) |
|
263 settings.remove(substyleKey) |
|
264 |
|
265 # Step 2: save the defined sub-styles |
|
266 for baseStyle in self.baseStyles: |
|
267 key = "Scintilla/{0}/style{1}/SubStyleLength".format( |
|
268 self.language(), baseStyle) |
|
269 settings.setValue(key, len(self.__subStyles[baseStyle])) |
|
270 for subStyleIndex, subStyle in enumerate( |
|
271 sorted(self.__subStyles[baseStyle].keys()) |
|
272 ): |
|
273 substyleKey = "Scintilla/{0}/style{1}/substyle{2}/".format( |
|
274 self.language(), baseStyle, subStyleIndex) |
|
275 subStyleData = self.__subStyles[baseStyle][subStyle] |
|
276 |
|
277 if ( |
|
278 not subStyleData["Description"] and |
|
279 not subStyleData["Words"] |
|
280 ): |
|
281 # invalid or incomplete sub-style definition |
|
282 continue |
|
283 |
|
284 settings.setValue(substyleKey + "Description", |
|
285 subStyleData["Description"]) |
|
286 settings.setValue(substyleKey + "Words", |
|
287 subStyleData["Words"]) |
|
288 |
|
289 style = subStyleData["Style"] |
|
290 if "fore" in style: |
|
291 color = style["fore"] |
|
292 else: |
|
293 col = self.color(baseStyle) |
|
294 color = col.red() << 16 | col.green() << 8 | col.blue() |
|
295 settings.setValue(substyleKey + "fore", color) |
|
296 if "paper" in style: |
|
297 color = style["paper"] |
|
298 else: |
|
299 col = self.paper(baseStyle) |
|
300 color = col.red() << 16 | col.green() << 8 | col.blue() |
|
301 settings.setValue(substyleKey + "paper", color) |
|
302 eolfill = style.get("eolfill", self.eolFill(baseStyle)) |
|
303 settings.setValue(substyleKey + "eolfill", eolfill) |
|
304 font = self.font(baseStyle) |
|
305 family = style.get("font_family", font.family()) |
|
306 settings.setValue(substyleKey + "font_family", family) |
|
307 size = style.get("font_size", font.pointSize()) |
|
308 settings.setValue(substyleKey + "font_size", size) |
|
309 bold = style.get("font_bold", font.bold()) |
|
310 settings.setValue(substyleKey + "font_bold", bold) |
|
311 italic = style.get("font_italic", font.italic()) |
|
312 settings.setValue(substyleKey + "font_italic", italic) |
|
313 underline = ( |
|
314 style["font_underline"] |
|
315 if "font_underline" in style else |
|
316 font.underline() |
|
317 ) |
|
318 settings.setValue(substyleKey + "font_underline", underline) |
|
319 |
|
320 def hasSubstyles(self): |
|
321 """ |
|
322 Public method to indicate the support of sub-styles. |
|
323 |
|
324 @return flag indicating sub-styling support |
|
325 @rtype bool |
|
326 """ |
|
327 return True |
|
328 |
|
329 def getBaseStyles(self): |
|
330 """ |
|
331 Public method to get the list of supported base styles. |
|
332 |
|
333 @return list of base styles |
|
334 @rtype list of int |
|
335 """ |
|
336 return self.baseStyles[:] |
|
337 |
|
338 def substylesCount(self, style): |
|
339 """ |
|
340 Public method to get the number of defined sub-styles. |
|
341 |
|
342 @param style base style number |
|
343 @type int |
|
344 @return number of defined sub-styles |
|
345 @rtype int |
|
346 """ |
|
347 count = (len(self.__subStyles[style]) if style in self.__subStyles |
|
348 else 0) |
|
349 |
|
350 return count |
|
351 |
|
352 def setSubstyleDescription(self, description, style, substyle): |
|
353 """ |
|
354 Public method to set the description for a sub-style. |
|
355 |
|
356 @param description description to be set |
|
357 @type str |
|
358 @param style base style number |
|
359 @type int |
|
360 @param substyle sub-style number |
|
361 @type int |
|
362 """ |
|
363 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
364 self.__subStyles[style][substyle]["Description"] = ( |
|
365 description.strip() |
|
366 ) |
|
367 |
|
368 def substyleDescription(self, style, substyle): |
|
369 """ |
|
370 Public method to get the description of a sub-style. |
|
371 |
|
372 @param style base style number |
|
373 @type int |
|
374 @param substyle sub-style number |
|
375 @type int |
|
376 @return sub-style description |
|
377 @rtype str |
|
378 """ |
|
379 desc = ( |
|
380 self.__subStyles[style][substyle]["Description"].strip() |
|
381 if (style in self.__subStyles and |
|
382 substyle in self.__subStyles[style]) else |
|
383 "" |
|
384 ) |
|
385 |
|
386 return desc |
|
387 |
|
388 def setSubstyleWords(self, words, style, substyle): |
|
389 """ |
|
390 Public method to set the words for a sub-style. |
|
391 |
|
392 @param words words to be set separated by white-space |
|
393 @type str |
|
394 @param style base style number |
|
395 @type int |
|
396 @param substyle sub-style number |
|
397 @type int |
|
398 """ |
|
399 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
400 self.__subStyles[style][substyle]["Words"] = words.strip() |
|
401 |
|
402 def substyleWords(self, style, substyle): |
|
403 """ |
|
404 Public method to get the words of a sub-style. |
|
405 |
|
406 @param style base style number |
|
407 @type int |
|
408 @param substyle sub-style number |
|
409 @type int |
|
410 @return white-space separated word list |
|
411 @rtype str |
|
412 """ |
|
413 words = ( |
|
414 self.__subStyles[style][substyle]["Words"].strip() |
|
415 if (style in self.__subStyles and |
|
416 substyle in self.__subStyles[style]) else |
|
417 "" |
|
418 ) |
|
419 |
|
420 return words |
|
421 |
|
422 def setSubstyleColor(self, color, style, substyle): |
|
423 """ |
|
424 Public method to set the foreground color of a sub-style. |
|
425 |
|
426 @param color foreground color to be set |
|
427 @type QColor |
|
428 @param style base style number |
|
429 @type int |
|
430 @param substyle sub-style number |
|
431 @type int |
|
432 """ |
|
433 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
434 self.__subStyles[style][substyle]["Style"]["fore"] = ( |
|
435 color.red() << 16 | color.green() << 8 | color.blue() |
|
436 ) |
|
437 |
|
438 def substyleColor(self, style, substyle): |
|
439 """ |
|
440 Public method to get the sub-style foreground color. |
|
441 |
|
442 @param style base style number |
|
443 @type int |
|
444 @param substyle sub-style number |
|
445 @type int |
|
446 @return foreground color |
|
447 @rtype QColor |
|
448 """ |
|
449 color = self.color(style) |
|
450 |
|
451 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
452 styleData = self.__subStyles[style][substyle]["Style"] |
|
453 if "fore" in styleData: |
|
454 color = QColor( |
|
455 styleData["fore"] >> 16 & 0xff, |
|
456 styleData["fore"] >> 8 & 0xff, |
|
457 styleData["fore"] & 0xff, |
|
458 ) |
|
459 |
|
460 return color |
|
461 |
|
462 def setSubstylePaper(self, color, style, substyle): |
|
463 """ |
|
464 Public method to set the background color of a sub-style. |
|
465 |
|
466 @param color background color to be set |
|
467 @type QColor |
|
468 @param style base style number |
|
469 @type int |
|
470 @param substyle sub-style number |
|
471 @type int |
|
472 """ |
|
473 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
474 self.__subStyles[style][substyle]["Style"]["paper"] = ( |
|
475 color.red() << 16 | color.green() << 8 | color.blue() |
|
476 ) |
|
477 |
|
478 def substylePaper(self, style, substyle): |
|
479 """ |
|
480 Public method to get the sub-style background color. |
|
481 |
|
482 @param style base style number |
|
483 @type int |
|
484 @param substyle sub-style number |
|
485 @type int |
|
486 @return background color |
|
487 @rtype QColor |
|
488 """ |
|
489 color = self.paper(style) |
|
490 |
|
491 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
492 styleData = self.__subStyles[style][substyle]["Style"] |
|
493 if "paper" in styleData: |
|
494 color = QColor( |
|
495 styleData["paper"] >> 16 & 0xff, |
|
496 styleData["paper"] >> 8 & 0xff, |
|
497 styleData["paper"] & 0xff, |
|
498 ) |
|
499 |
|
500 return color |
|
501 |
|
502 def setSubstyleEolFill(self, eolFill, style, substyle): |
|
503 """ |
|
504 Public method to set the eolfill flag of a sub-style. |
|
505 |
|
506 @param eolFill eolfill flag to be set |
|
507 @type bool |
|
508 @param style base style number |
|
509 @type int |
|
510 @param substyle sub-style number |
|
511 @type int |
|
512 """ |
|
513 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
514 self.__subStyles[style][substyle]["Style"]["eolfill"] = ( |
|
515 eolFill |
|
516 ) |
|
517 |
|
518 def substyleEolFill(self, style, substyle): |
|
519 """ |
|
520 Public method to get the eolfill flag. |
|
521 |
|
522 @param style base style number |
|
523 @type int |
|
524 @param substyle sub-style number |
|
525 @type int |
|
526 @return eolfill flag |
|
527 @rtype bool |
|
528 """ |
|
529 eolFill = self.eolFill(style) |
|
530 |
|
531 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
532 styleData = self.__subStyles[style][substyle]["Style"] |
|
533 eolFill = styleData.get("eolfill", self.eolFill(style)) |
|
534 |
|
535 return eolFill |
|
536 |
|
537 def setSubstyleFont(self, font, style, substyle): |
|
538 """ |
|
539 Public method to set the font of a sub-style. |
|
540 |
|
541 @param font font to be set |
|
542 @type QFont |
|
543 @param style base style number |
|
544 @type int |
|
545 @param substyle sub-style number |
|
546 @type int |
|
547 """ |
|
548 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
549 self.__subStyles[style][substyle]["Style"]["font_family"] = ( |
|
550 font.family() |
|
551 ) |
|
552 self.__subStyles[style][substyle]["Style"]["font_size"] = ( |
|
553 font.pointSize() |
|
554 ) |
|
555 self.__subStyles[style][substyle]["Style"]["font_bold"] = ( |
|
556 font.bold() |
|
557 ) |
|
558 self.__subStyles[style][substyle]["Style"]["font_italic"] = ( |
|
559 font.italic() |
|
560 ) |
|
561 self.__subStyles[style][substyle]["Style"]["font_underline"] = ( |
|
562 font.underline() |
|
563 ) |
|
564 |
|
565 def substyleFont(self, style, substyle): |
|
566 """ |
|
567 Public method to get the sub-style font. |
|
568 |
|
569 @param style base style number |
|
570 @type int |
|
571 @param substyle sub-style number |
|
572 @type int |
|
573 @return font |
|
574 @rtype QFont |
|
575 """ |
|
576 font = self.font(style) |
|
577 |
|
578 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
579 styleData = self.__subStyles[style][substyle]["Style"] |
|
580 if "font_family" in styleData: |
|
581 font.setFamily(styleData["font_family"]) |
|
582 if "font_size" in styleData: |
|
583 font.setPointSize(styleData["font_size"]) |
|
584 if "font_bold" in styleData: |
|
585 font.setBold(styleData["font_bold"]) |
|
586 if "font_italic" in styleData: |
|
587 font.setItalic(styleData["font_italic"]) |
|
588 if "font_underline" in styleData: |
|
589 font.setUnderline(styleData["font_underline"]) |
|
590 |
|
591 return font |
|
592 |
|
593 def substyleDefaultDescription(self, style, substyle): |
|
594 """ |
|
595 Public method to get the default description of a sub-style. |
|
596 |
|
597 @param style base style number |
|
598 @type int |
|
599 @param substyle sub-style number |
|
600 @type int |
|
601 @return sub-style default description |
|
602 @rtype str |
|
603 """ |
|
604 description = "" |
|
605 |
|
606 if ( |
|
607 style in self.defaultSubStyles and |
|
608 substyle in self.defaultSubStyles[style] |
|
609 ): |
|
610 substyleData = self.defaultSubStyles[style][substyle] |
|
611 description = substyleData["Description"].strip() |
|
612 |
|
613 return description |
|
614 |
|
615 def substyleDefaultWords(self, style, substyle): |
|
616 """ |
|
617 Public method to get the default words of a sub-style. |
|
618 |
|
619 @param style base style number |
|
620 @type int |
|
621 @param substyle sub-style number |
|
622 @type int |
|
623 @return white-space separated default word list |
|
624 @rtype str |
|
625 """ |
|
626 words = "" |
|
627 |
|
628 if ( |
|
629 style in self.defaultSubStyles and |
|
630 substyle in self.defaultSubStyles[style] |
|
631 ): |
|
632 substyleData = self.defaultSubStyles[style][substyle] |
|
633 words = substyleData["Words"].strip() |
|
634 |
|
635 return words |
|
636 |
|
637 def substyleDefaultColor(self, style, substyle): |
|
638 """ |
|
639 Public method to get the sub-style default foreground color. |
|
640 |
|
641 @param style base style number |
|
642 @type int |
|
643 @param substyle sub-style number |
|
644 @type int |
|
645 @return default foreground color |
|
646 @rtype QColor |
|
647 """ |
|
648 color = self.defaultColor(style) |
|
649 |
|
650 if ( |
|
651 style in self.defaultSubStyles and |
|
652 substyle in self.defaultSubStyles[style] |
|
653 ): |
|
654 styleData = self.defaultSubStyles[style][substyle]["Style"] |
|
655 if "fore" in styleData: |
|
656 color = QColor( |
|
657 styleData["fore"] >> 16 & 0xff, |
|
658 styleData["fore"] >> 8 & 0xff, |
|
659 styleData["fore"] & 0xff, |
|
660 ) |
|
661 |
|
662 return color |
|
663 |
|
664 def substyleDefaultPaper(self, style, substyle): |
|
665 """ |
|
666 Public method to get the sub-style default background color. |
|
667 |
|
668 @param style base style number |
|
669 @type int |
|
670 @param substyle sub-style number |
|
671 @type int |
|
672 @return default background color |
|
673 @rtype QColor |
|
674 """ |
|
675 color = self.defaultPaper(style) |
|
676 |
|
677 if ( |
|
678 style in self.defaultSubStyles and |
|
679 substyle in self.defaultSubStyles[style] |
|
680 ): |
|
681 styleData = self.defaultSubStyles[style][substyle]["Style"] |
|
682 if "paper" in styleData: |
|
683 color = QColor( |
|
684 styleData["paper"] >> 16 & 0xff, |
|
685 styleData["paper"] >> 8 & 0xff, |
|
686 styleData["paper"] & 0xff, |
|
687 ) |
|
688 |
|
689 return color |
|
690 |
|
691 def substyleDefaultEolFill(self, style, substyle): |
|
692 """ |
|
693 Public method to get the default eolfill flag. |
|
694 |
|
695 @param style base style number |
|
696 @type int |
|
697 @param substyle sub-style number |
|
698 @type int |
|
699 @return default eolfill flag |
|
700 @rtype bool |
|
701 """ |
|
702 eolFill = self.defaultEolFill(style) |
|
703 |
|
704 if ( |
|
705 style in self.defaultSubStyles and |
|
706 substyle in self.defaultSubStyles[style] |
|
707 ): |
|
708 styleData = self.defaultSubStyles[style][substyle]["Style"] |
|
709 eolFill = styleData.get("eolfill", self.defaultEolFill(style)) |
|
710 |
|
711 return eolFill |
|
712 |
|
713 def substyleDefaultFont(self, style, substyle): |
|
714 """ |
|
715 Public method to get the default sub-style font. |
|
716 |
|
717 @param style base style number |
|
718 @type int |
|
719 @param substyle sub-style number |
|
720 @type int |
|
721 @return default font |
|
722 @rtype QFont |
|
723 """ |
|
724 font = self.defaultFont(style) |
|
725 |
|
726 if ( |
|
727 style in self.defaultSubStyles and |
|
728 substyle in self.defaultSubStyles[style] |
|
729 ): |
|
730 styleData = self.defaultSubStyles[style][substyle]["Style"] |
|
731 if "font_family" in styleData: |
|
732 font.setFamily(styleData["font_family"]) |
|
733 if "font_size" in styleData: |
|
734 font.setPointSize(styleData["font_size"]) |
|
735 if "font_bold" in styleData: |
|
736 font.setBold(styleData["font_bold"]) |
|
737 if "font_italic" in styleData: |
|
738 font.setItalic(styleData["font_italic"]) |
|
739 if "font_underline" in styleData: |
|
740 font.setUnderline(styleData["font_underline"]) |
|
741 |
|
742 return font |
|
743 |
|
744 def addSubstyle(self, style): |
|
745 """ |
|
746 Public method to add an empty sub-style to a given base style. |
|
747 |
|
748 @param style base style number |
|
749 @type int |
|
750 @return allocated sub-style number or -1 to indicate an error |
|
751 @rtype int |
|
752 """ |
|
753 if style in self.__subStyles: |
|
754 lastSubStyle = sorted(self.__subStyles[style].keys())[-1] |
|
755 subStyle = lastSubStyle + 1 |
|
756 self.__subStyles[style][subStyle] = { |
|
757 "Description": "", |
|
758 "Words": "", |
|
759 "Style": {}, |
|
760 } |
|
761 else: |
|
762 subStyle = -1 |
|
763 |
|
764 return subStyle |
|
765 |
|
766 def delSubstyle(self, style, substyle): |
|
767 """ |
|
768 Public method to delete a given sub-style definition. |
|
769 |
|
770 @param style base style number |
|
771 @type int |
|
772 @param substyle sub-style number |
|
773 @type int |
|
774 @return flag indicating successful deletion |
|
775 @rtype bool |
|
776 """ |
|
777 ok = False |
|
778 |
|
779 if style in self.__subStyles and substyle in self.__subStyles[style]: |
|
780 del self.__subStyles[style][substyle] |
|
781 ok = True |
|
782 |
|
783 return ok |
|
784 |
|
785 def hasSubstyle(self, style, substyle): |
|
786 """ |
|
787 Public method to test for a given sub-style definition. |
|
788 |
|
789 @param style base style number |
|
790 @type int |
|
791 @param substyle sub-style number |
|
792 @type int |
|
793 @return flag indicating the existence of a sub-style definition |
|
794 @rtype bool |
|
795 """ |
|
796 return (style in self.__subStyles and |
|
797 substyle in self.__subStyles[style]) |
|
798 |
|
799 def isBaseStyle(self, style): |
|
800 """ |
|
801 Public method to test, if a given style may have sub-styles. |
|
802 |
|
803 @param style base style number |
|
804 @type int |
|
805 @return flag indicating that the style may have sub-styles |
|
806 @rtype bool |
|
807 """ |
|
808 return style in self.baseStyles |