22 from EricWidgets import EricMessageBox, EricFileDialog |
27 from EricWidgets import EricMessageBox, EricFileDialog |
23 |
28 |
24 import UI.PixmapCache |
29 import UI.PixmapCache |
25 |
30 |
26 |
31 |
27 class EditorHighlightingStylesPage(ConfigurationPageBase, |
32 class EditorHighlightingStylesPage( |
28 Ui_EditorHighlightingStylesPage): |
33 ConfigurationPageBase, Ui_EditorHighlightingStylesPage |
|
34 ): |
29 """ |
35 """ |
30 Class implementing the Editor Highlighting Styles configuration page. |
36 Class implementing the Editor Highlighting Styles configuration page. |
31 """ |
37 """ |
|
38 |
32 FAMILYONLY = 0 |
39 FAMILYONLY = 0 |
33 SIZEONLY = 1 |
40 SIZEONLY = 1 |
34 FAMILYANDSIZE = 2 |
41 FAMILYANDSIZE = 2 |
35 FONT = 99 |
42 FONT = 99 |
36 |
43 |
37 StyleRole = Qt.ItemDataRole.UserRole + 1 |
44 StyleRole = Qt.ItemDataRole.UserRole + 1 |
38 SubstyleRole = Qt.ItemDataRole.UserRole + 2 |
45 SubstyleRole = Qt.ItemDataRole.UserRole + 2 |
39 |
46 |
40 def __init__(self, lexers): |
47 def __init__(self, lexers): |
41 """ |
48 """ |
42 Constructor |
49 Constructor |
43 |
50 |
44 @param lexers reference to the lexers dictionary |
51 @param lexers reference to the lexers dictionary |
45 """ |
52 """ |
46 super().__init__() |
53 super().__init__() |
47 self.setupUi(self) |
54 self.setupUi(self) |
48 self.setObjectName("EditorHighlightingStylesPage") |
55 self.setObjectName("EditorHighlightingStylesPage") |
49 |
56 |
50 self.defaultSubstylesButton.setIcon(UI.PixmapCache.getIcon("editUndo")) |
57 self.defaultSubstylesButton.setIcon(UI.PixmapCache.getIcon("editUndo")) |
51 self.addSubstyleButton.setIcon(UI.PixmapCache.getIcon("plus")) |
58 self.addSubstyleButton.setIcon(UI.PixmapCache.getIcon("plus")) |
52 self.deleteSubstyleButton.setIcon(UI.PixmapCache.getIcon("minus")) |
59 self.deleteSubstyleButton.setIcon(UI.PixmapCache.getIcon("minus")) |
53 self.editSubstyleButton.setIcon(UI.PixmapCache.getIcon("edit")) |
60 self.editSubstyleButton.setIcon(UI.PixmapCache.getIcon("edit")) |
54 self.copySubstyleButton.setIcon(UI.PixmapCache.getIcon("editCopy")) |
61 self.copySubstyleButton.setIcon(UI.PixmapCache.getIcon("editCopy")) |
55 |
62 |
56 self.__fontButtonMenu = QMenu() |
63 self.__fontButtonMenu = QMenu() |
57 act = self.__fontButtonMenu.addAction(self.tr("Font")) |
64 act = self.__fontButtonMenu.addAction(self.tr("Font")) |
58 act.setData(self.FONT) |
65 act.setData(self.FONT) |
59 self.__fontButtonMenu.addSeparator() |
66 self.__fontButtonMenu.addSeparator() |
60 act = self.__fontButtonMenu.addAction( |
67 act = self.__fontButtonMenu.addAction(self.tr("Family and Size only")) |
61 self.tr("Family and Size only")) |
|
62 act.setData(self.FAMILYANDSIZE) |
68 act.setData(self.FAMILYANDSIZE) |
63 act = self.__fontButtonMenu.addAction(self.tr("Family only")) |
69 act = self.__fontButtonMenu.addAction(self.tr("Family only")) |
64 act.setData(self.FAMILYONLY) |
70 act.setData(self.FAMILYONLY) |
65 act = self.__fontButtonMenu.addAction(self.tr("Size only")) |
71 act = self.__fontButtonMenu.addAction(self.tr("Size only")) |
66 act.setData(self.SIZEONLY) |
72 act.setData(self.SIZEONLY) |
67 self.__fontButtonMenu.triggered.connect(self.__fontButtonMenuTriggered) |
73 self.__fontButtonMenu.triggered.connect(self.__fontButtonMenuTriggered) |
68 self.fontButton.setMenu(self.__fontButtonMenu) |
74 self.fontButton.setMenu(self.__fontButtonMenu) |
69 |
75 |
70 self.__allFontsButtonMenu = QMenu() |
76 self.__allFontsButtonMenu = QMenu() |
71 act = self.__allFontsButtonMenu.addAction(self.tr("Font")) |
77 act = self.__allFontsButtonMenu.addAction(self.tr("Font")) |
72 act.setData(self.FONT) |
78 act.setData(self.FONT) |
73 self.__allFontsButtonMenu.addSeparator() |
79 self.__allFontsButtonMenu.addSeparator() |
74 act = self.__allFontsButtonMenu.addAction( |
80 act = self.__allFontsButtonMenu.addAction(self.tr("Family and Size only")) |
75 self.tr("Family and Size only")) |
|
76 act.setData(self.FAMILYANDSIZE) |
81 act.setData(self.FAMILYANDSIZE) |
77 act = self.__allFontsButtonMenu.addAction(self.tr("Family only")) |
82 act = self.__allFontsButtonMenu.addAction(self.tr("Family only")) |
78 act.setData(self.FAMILYONLY) |
83 act.setData(self.FAMILYONLY) |
79 act = self.__allFontsButtonMenu.addAction(self.tr("Size only")) |
84 act = self.__allFontsButtonMenu.addAction(self.tr("Size only")) |
80 act.setData(self.SIZEONLY) |
85 act.setData(self.SIZEONLY) |
81 self.__allFontsButtonMenu.triggered.connect( |
86 self.__allFontsButtonMenu.triggered.connect(self.__allFontsButtonMenuTriggered) |
82 self.__allFontsButtonMenuTriggered) |
|
83 self.allFontsButton.setMenu(self.__allFontsButtonMenu) |
87 self.allFontsButton.setMenu(self.__allFontsButtonMenu) |
84 |
88 |
85 self.lexer = None |
89 self.lexer = None |
86 self.lexers = lexers |
90 self.lexers = lexers |
87 |
91 |
88 # set initial values |
92 # set initial values |
89 import QScintilla.Lexers |
93 import QScintilla.Lexers |
90 languages = sorted([''] + list(self.lexers.keys())) |
94 |
|
95 languages = sorted([""] + list(self.lexers.keys())) |
91 for language in languages: |
96 for language in languages: |
92 self.lexerLanguageComboBox.addItem( |
97 self.lexerLanguageComboBox.addItem( |
93 QScintilla.Lexers.getLanguageIcon(language, False), |
98 QScintilla.Lexers.getLanguageIcon(language, False), language |
94 language) |
99 ) |
95 self.on_lexerLanguageComboBox_activated(0) |
100 self.on_lexerLanguageComboBox_activated(0) |
96 |
101 |
97 def save(self): |
102 def save(self): |
98 """ |
103 """ |
99 Public slot to save the Editor Highlighting Styles configuration. |
104 Public slot to save the Editor Highlighting Styles configuration. |
100 """ |
105 """ |
101 for lexer in list(self.lexers.values()): |
106 for lexer in list(self.lexers.values()): |
102 lexer.writeSettings() |
107 lexer.writeSettings() |
103 |
108 |
104 @pyqtSlot(int) |
109 @pyqtSlot(int) |
105 def on_lexerLanguageComboBox_activated(self, index): |
110 def on_lexerLanguageComboBox_activated(self, index): |
106 """ |
111 """ |
107 Private slot to fill the style combo of the source page. |
112 Private slot to fill the style combo of the source page. |
108 |
113 |
109 @param index index of the selected entry |
114 @param index index of the selected entry |
110 @type int |
115 @type int |
111 """ |
116 """ |
112 language = self.lexerLanguageComboBox.itemText(index) |
117 language = self.lexerLanguageComboBox.itemText(index) |
113 |
118 |
114 self.styleElementList.clear() |
119 self.styleElementList.clear() |
115 self.styleGroup.setEnabled(False) |
120 self.styleGroup.setEnabled(False) |
116 self.lexer = None |
121 self.lexer = None |
117 |
122 |
118 if not language: |
123 if not language: |
119 return |
124 return |
120 |
125 |
121 try: |
126 try: |
122 self.lexer = self.lexers[language] |
127 self.lexer = self.lexers[language] |
123 except KeyError: |
128 except KeyError: |
124 return |
129 return |
125 |
130 |
126 self.styleGroup.setEnabled(True) |
131 self.styleGroup.setEnabled(True) |
127 for description, styleNo, subStyleNo in self.lexer.getStyles(): |
132 for description, styleNo, subStyleNo in self.lexer.getStyles(): |
128 if subStyleNo >= 0: |
133 if subStyleNo >= 0: |
129 parent = self.styleElementList.findItems( |
134 parent = self.styleElementList.findItems( |
130 self.lexer.description(styleNo), |
135 self.lexer.description(styleNo), Qt.MatchFlag.MatchExactly |
131 Qt.MatchFlag.MatchExactly)[0] |
136 )[0] |
132 parent.setExpanded(True) |
137 parent.setExpanded(True) |
133 else: |
138 else: |
134 parent = self.styleElementList |
139 parent = self.styleElementList |
135 itm = QTreeWidgetItem(parent, [description]) |
140 itm = QTreeWidgetItem(parent, [description]) |
136 itm.setData(0, self.StyleRole, styleNo) |
141 itm.setData(0, self.StyleRole, styleNo) |
137 itm.setData(0, self.SubstyleRole, subStyleNo) |
142 itm.setData(0, self.SubstyleRole, subStyleNo) |
138 self.__styleAllItems() |
143 self.__styleAllItems() |
139 self.styleElementList.setCurrentItem( |
144 self.styleElementList.setCurrentItem(self.styleElementList.topLevelItem(0)) |
140 self.styleElementList.topLevelItem(0)) |
145 |
141 |
|
142 def __stylesForItem(self, itm): |
146 def __stylesForItem(self, itm): |
143 """ |
147 """ |
144 Private method to get the style and sub-style number of the given item. |
148 Private method to get the style and sub-style number of the given item. |
145 |
149 |
146 @param itm reference to the item to extract the styles from |
150 @param itm reference to the item to extract the styles from |
147 @type QTreeWidgetItem |
151 @type QTreeWidgetItem |
148 @return tuple containing the style and sub-style numbers |
152 @return tuple containing the style and sub-style numbers |
149 @rtype tuple of (int, int) |
153 @rtype tuple of (int, int) |
150 """ |
154 """ |
151 style = itm.data(0, self.StyleRole) |
155 style = itm.data(0, self.StyleRole) |
152 substyle = itm.data(0, self.SubstyleRole) |
156 substyle = itm.data(0, self.SubstyleRole) |
153 |
157 |
154 return (style, substyle) |
158 return (style, substyle) |
155 |
159 |
156 def __currentStyles(self): |
160 def __currentStyles(self): |
157 """ |
161 """ |
158 Private method to get the styles of the current item. |
162 Private method to get the styles of the current item. |
159 |
163 |
160 @return tuple containing the style and sub-style numbers |
164 @return tuple containing the style and sub-style numbers |
161 @rtype tuple of (int, int) |
165 @rtype tuple of (int, int) |
162 """ |
166 """ |
163 itm = self.styleElementList.currentItem() |
167 itm = self.styleElementList.currentItem() |
164 # return default style, if no current item |
168 # return default style, if no current item |
165 styles = (0, -1) if itm is None else self.__stylesForItem(itm) |
169 styles = (0, -1) if itm is None else self.__stylesForItem(itm) |
166 |
170 |
167 return styles |
171 return styles |
168 |
172 |
169 def __styleOneItem(self, item, style, substyle): |
173 def __styleOneItem(self, item, style, substyle): |
170 """ |
174 """ |
171 Private method to style one item of the style element list. |
175 Private method to style one item of the style element list. |
172 |
176 |
173 @param item reference to the item to be styled |
177 @param item reference to the item to be styled |
174 @type QTreeWidgetItem |
178 @type QTreeWidgetItem |
175 @param style base style number |
179 @param style base style number |
176 @type int |
180 @type int |
177 @param substyle sub-style number |
181 @param substyle sub-style number |
179 """ |
183 """ |
180 colour = self.lexer.color(style, substyle) |
184 colour = self.lexer.color(style, substyle) |
181 paper = self.lexer.paper(style, substyle) |
185 paper = self.lexer.paper(style, substyle) |
182 font = self.lexer.font(style, substyle) |
186 font = self.lexer.font(style, substyle) |
183 eolfill = self.lexer.eolFill(style, substyle) |
187 eolfill = self.lexer.eolFill(style, substyle) |
184 |
188 |
185 item.setFont(0, font) |
189 item.setFont(0, font) |
186 item.setBackground(0, paper) |
190 item.setBackground(0, paper) |
187 item.setForeground(0, colour) |
191 item.setForeground(0, colour) |
188 if eolfill: |
192 if eolfill: |
189 item.setCheckState(0, Qt.CheckState.Checked) |
193 item.setCheckState(0, Qt.CheckState.Checked) |
190 else: |
194 else: |
191 item.setCheckState(0, Qt.CheckState.Unchecked) |
195 item.setCheckState(0, Qt.CheckState.Unchecked) |
192 |
196 |
193 def __styleAllItems(self): |
197 def __styleAllItems(self): |
194 """ |
198 """ |
195 Private method to style all items of the style element list. |
199 Private method to style all items of the style element list. |
196 """ |
200 """ |
197 itm = self.styleElementList.topLevelItem(0) |
201 itm = self.styleElementList.topLevelItem(0) |
198 while itm is not None: |
202 while itm is not None: |
199 style, substyle = self.__stylesForItem(itm) |
203 style, substyle = self.__stylesForItem(itm) |
200 self.__styleOneItem(itm, style, substyle) |
204 self.__styleOneItem(itm, style, substyle) |
201 itm = self.styleElementList.itemBelow(itm) |
205 itm = self.styleElementList.itemBelow(itm) |
202 |
206 |
203 def __styleSample(self, color, paper, font=None): |
207 def __styleSample(self, color, paper, font=None): |
204 """ |
208 """ |
205 Private method to style the sample text. |
209 Private method to style the sample text. |
206 |
210 |
207 @param color foreground color for the sample |
211 @param color foreground color for the sample |
208 @type QColor |
212 @type QColor |
209 @param paper background color for the sample |
213 @param paper background color for the sample |
210 @type QColor |
214 @type QColor |
211 @param font font for the sample (defaults to None) |
215 @param font font for the sample (defaults to None) |
212 @type QFont (optional) |
216 @type QFont (optional) |
213 """ |
217 """ |
214 if font: |
218 if font: |
215 self.sampleText.setFont(font) |
219 self.sampleText.setFont(font) |
216 |
220 |
217 self.sampleText.setStyleSheet( |
221 self.sampleText.setStyleSheet( |
218 "QLineEdit {{ color: {0}; background-color: {1}; }}".format( |
222 "QLineEdit {{ color: {0}; background-color: {1}; }}".format( |
219 color.name(), paper.name() |
223 color.name(), paper.name() |
220 ) |
224 ) |
221 ) |
225 ) |
222 |
226 |
223 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
227 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
224 def on_styleElementList_currentItemChanged(self, current, previous): |
228 def on_styleElementList_currentItemChanged(self, current, previous): |
225 """ |
229 """ |
226 Private method to handle a change of the current row. |
230 Private method to handle a change of the current row. |
227 |
231 |
228 @param current reference to the current item |
232 @param current reference to the current item |
229 @type QTreeWidgetItem |
233 @type QTreeWidgetItem |
230 @param previous reference to the previous item |
234 @param previous reference to the previous item |
231 @type QTreeWidgetItem |
235 @type QTreeWidgetItem |
232 """ |
236 """ |
233 if current is None: |
237 if current is None: |
234 return |
238 return |
235 |
239 |
236 style, substyle = self.__stylesForItem(current) |
240 style, substyle = self.__stylesForItem(current) |
237 colour = self.lexer.color(style, substyle) |
241 colour = self.lexer.color(style, substyle) |
238 paper = self.lexer.paper(style, substyle) |
242 paper = self.lexer.paper(style, substyle) |
239 eolfill = self.lexer.eolFill(style, substyle) |
243 eolfill = self.lexer.eolFill(style, substyle) |
240 font = self.lexer.font(style, substyle) |
244 font = self.lexer.font(style, substyle) |
241 |
245 |
242 self.__styleSample(colour, paper, font=font) |
246 self.__styleSample(colour, paper, font=font) |
243 self.eolfillCheckBox.setChecked(eolfill) |
247 self.eolfillCheckBox.setChecked(eolfill) |
244 |
248 |
245 selectedOne = len(self.styleElementList.selectedItems()) == 1 |
249 selectedOne = len(self.styleElementList.selectedItems()) == 1 |
246 self.defaultSubstylesButton.setEnabled( |
250 self.defaultSubstylesButton.setEnabled( |
247 selectedOne and substyle < 0 and self.lexer.isBaseStyle(style)) |
251 selectedOne and substyle < 0 and self.lexer.isBaseStyle(style) |
|
252 ) |
248 self.addSubstyleButton.setEnabled( |
253 self.addSubstyleButton.setEnabled( |
249 selectedOne and substyle < 0 and self.lexer.isBaseStyle(style)) |
254 selectedOne and substyle < 0 and self.lexer.isBaseStyle(style) |
|
255 ) |
250 self.deleteSubstyleButton.setEnabled(selectedOne and substyle >= 0) |
256 self.deleteSubstyleButton.setEnabled(selectedOne and substyle >= 0) |
251 self.editSubstyleButton.setEnabled(selectedOne and substyle >= 0) |
257 self.editSubstyleButton.setEnabled(selectedOne and substyle >= 0) |
252 self.copySubstyleButton.setEnabled(selectedOne and substyle >= 0) |
258 self.copySubstyleButton.setEnabled(selectedOne and substyle >= 0) |
253 |
259 |
254 @pyqtSlot() |
260 @pyqtSlot() |
255 def on_foregroundButton_clicked(self): |
261 def on_foregroundButton_clicked(self): |
256 """ |
262 """ |
257 Private method used to select the foreground colour of the selected |
263 Private method used to select the foreground colour of the selected |
258 style and lexer. |
264 style and lexer. |
377 for selItem in self.styleElementList.selectedItems(): |
385 for selItem in self.styleElementList.selectedItems(): |
378 style, substyle = self.__stylesForItem(selItem) |
386 style, substyle = self.__stylesForItem(selItem) |
379 setFont(font, style, substyle, familyOnly, sizeOnly) |
387 setFont(font, style, substyle, familyOnly, sizeOnly) |
380 itmFont = self.lexer.font(style, substyle) |
388 itmFont = self.lexer.font(style, substyle) |
381 selItem.setFont(0, itmFont) |
389 selItem.setFont(0, itmFont) |
382 |
390 |
383 def __fontButtonMenuTriggered(self, act): |
391 def __fontButtonMenuTriggered(self, act): |
384 """ |
392 """ |
385 Private slot used to select the font of the selected style and lexer. |
393 Private slot used to select the font of the selected style and lexer. |
386 |
394 |
387 @param act reference to the triggering action (QAction) |
395 @param act reference to the triggering action (QAction) |
388 """ |
396 """ |
389 if act is None: |
397 if act is None: |
390 return |
398 return |
391 |
399 |
392 familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] |
400 familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] |
393 sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] |
401 sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] |
394 self.__changeFont(False, familyOnly, sizeOnly) |
402 self.__changeFont(False, familyOnly, sizeOnly) |
395 |
403 |
396 def __allFontsButtonMenuTriggered(self, act): |
404 def __allFontsButtonMenuTriggered(self, act): |
397 """ |
405 """ |
398 Private slot used to change the font of all styles of a selected lexer. |
406 Private slot used to change the font of all styles of a selected lexer. |
399 |
407 |
400 @param act reference to the triggering action (QAction) |
408 @param act reference to the triggering action (QAction) |
401 """ |
409 """ |
402 if act is None: |
410 if act is None: |
403 return |
411 return |
404 |
412 |
405 familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] |
413 familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] |
406 sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] |
414 sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] |
407 self.__changeFont(True, familyOnly, sizeOnly) |
415 self.__changeFont(True, familyOnly, sizeOnly) |
408 |
416 |
409 @pyqtSlot(bool) |
417 @pyqtSlot(bool) |
410 def on_eolfillCheckBox_clicked(self, on): |
418 def on_eolfillCheckBox_clicked(self, on): |
411 """ |
419 """ |
412 Private method used to set the eolfill for the selected style and |
420 Private method used to set the eolfill for the selected style and |
413 lexer. |
421 lexer. |
414 |
422 |
415 @param on flag indicating enabled or disabled state (boolean) |
423 @param on flag indicating enabled or disabled state (boolean) |
416 """ |
424 """ |
417 style, substyle = self.__currentStyles() |
425 style, substyle = self.__currentStyles() |
418 checkState = Qt.CheckState.Checked if on else Qt.CheckState.Unchecked |
426 checkState = Qt.CheckState.Checked if on else Qt.CheckState.Unchecked |
419 for selItem in self.styleElementList.selectedItems(): |
427 for selItem in self.styleElementList.selectedItems(): |
420 style, substyle = self.__stylesForItem(selItem) |
428 style, substyle = self.__stylesForItem(selItem) |
421 self.lexer.setEolFill(on, style, substyle) |
429 self.lexer.setEolFill(on, style, substyle) |
422 selItem.setCheckState(0, checkState) |
430 selItem.setCheckState(0, checkState) |
423 |
431 |
424 @pyqtSlot() |
432 @pyqtSlot() |
425 def on_allEolFillButton_clicked(self): |
433 def on_allEolFillButton_clicked(self): |
426 """ |
434 """ |
427 Private method used to set the eolfill for all styles of a selected |
435 Private method used to set the eolfill for all styles of a selected |
428 lexer. |
436 lexer. |
467 while itm is not None: |
478 while itm is not None: |
468 style, substyle = self.__stylesForItem(itm) |
479 style, substyle = self.__stylesForItem(itm) |
469 self.__setToDefault(style, substyle) |
480 self.__setToDefault(style, substyle) |
470 itm = self.styleElementList.itemBelow(itm) |
481 itm = self.styleElementList.itemBelow(itm) |
471 self.on_styleElementList_currentItemChanged( |
482 self.on_styleElementList_currentItemChanged( |
472 self.styleElementList.currentItem(), None) |
483 self.styleElementList.currentItem(), None |
|
484 ) |
473 self.__styleAllItems() |
485 self.__styleAllItems() |
474 |
486 |
475 def __setToDefault(self, style, substyle): |
487 def __setToDefault(self, style, substyle): |
476 """ |
488 """ |
477 Private method to set a specific style to its default values. |
489 Private method to set a specific style to its default values. |
478 |
490 |
479 @param style style number |
491 @param style style number |
480 @type int |
492 @type int |
481 @param substyle sub-style number |
493 @param substyle sub-style number |
482 @type int |
494 @type int |
483 """ |
495 """ |
484 self.lexer.setColor(self.lexer.defaultColor(style, substyle), |
496 self.lexer.setColor(self.lexer.defaultColor(style, substyle), style, substyle) |
485 style, substyle) |
497 self.lexer.setPaper(self.lexer.defaultPaper(style, substyle), style, substyle) |
486 self.lexer.setPaper(self.lexer.defaultPaper(style, substyle), |
498 self.lexer.setFont(self.lexer.defaultFont(style, substyle), style, substyle) |
487 style, substyle) |
499 self.lexer.setEolFill( |
488 self.lexer.setFont(self.lexer.defaultFont(style, substyle), |
500 self.lexer.defaultEolFill(style, substyle), style, substyle |
489 style, substyle) |
501 ) |
490 self.lexer.setEolFill(self.lexer.defaultEolFill(style, substyle), |
502 |
491 style, substyle) |
|
492 |
|
493 ####################################################################### |
503 ####################################################################### |
494 ## Importing and exporting of styles |
504 ## Importing and exporting of styles |
495 ####################################################################### |
505 ####################################################################### |
496 |
506 |
497 @pyqtSlot() |
507 @pyqtSlot() |
498 def on_importButton_clicked(self): |
508 def on_importButton_clicked(self): |
499 """ |
509 """ |
500 Private slot to import styles to be selected. |
510 Private slot to import styles to be selected. |
501 """ |
511 """ |
502 self.__importStyles(importAll=False) |
512 self.__importStyles(importAll=False) |
503 |
513 |
504 @pyqtSlot() |
514 @pyqtSlot() |
505 def on_exportButton_clicked(self): |
515 def on_exportButton_clicked(self): |
506 """ |
516 """ |
507 Private slot to export styles to be selected. |
517 Private slot to export styles to be selected. |
508 """ |
518 """ |
509 self.__exportStyles(exportAll=False) |
519 self.__exportStyles(exportAll=False) |
510 |
520 |
511 @pyqtSlot() |
521 @pyqtSlot() |
512 def on_importAllButton_clicked(self): |
522 def on_importAllButton_clicked(self): |
513 """ |
523 """ |
514 Private slot to import the styles of all lexers. |
524 Private slot to import the styles of all lexers. |
515 """ |
525 """ |
516 self.__importStyles(importAll=True) |
526 self.__importStyles(importAll=True) |
517 |
527 |
518 @pyqtSlot() |
528 @pyqtSlot() |
519 def on_exportAllButton_clicked(self): |
529 def on_exportAllButton_clicked(self): |
520 """ |
530 """ |
521 Private slot to export the styles of all lexers. |
531 Private slot to export the styles of all lexers. |
522 """ |
532 """ |
523 self.__exportStyles(exportAll=True) |
533 self.__exportStyles(exportAll=True) |
524 |
534 |
525 def __exportStyles(self, exportAll=False): |
535 def __exportStyles(self, exportAll=False): |
526 """ |
536 """ |
527 Private method to export the styles of selectable lexers. |
537 Private method to export the styles of selectable lexers. |
528 |
538 |
529 @param exportAll flag indicating to export all styles without asking |
539 @param exportAll flag indicating to export all styles without asking |
530 (defaults to False) |
540 (defaults to False) |
531 @type bool (optional) |
541 @type bool (optional) |
532 """ |
542 """ |
533 from eric7config import getConfig |
543 from eric7config import getConfig |
|
544 |
534 stylesDir = getConfig("ericStylesDir") |
545 stylesDir = getConfig("ericStylesDir") |
535 |
546 |
536 lexerNames = list(self.lexers.keys()) |
547 lexerNames = list(self.lexers.keys()) |
537 if not exportAll: |
548 if not exportAll: |
538 if self.lexer: |
549 if self.lexer: |
539 preselect = [self.lexer.language()] |
550 preselect = [self.lexer.language()] |
540 else: |
551 else: |
541 preselect = [] |
552 preselect = [] |
542 from .EditorHighlightingStylesSelectionDialog import ( |
553 from .EditorHighlightingStylesSelectionDialog import ( |
543 EditorHighlightingStylesSelectionDialog) |
554 EditorHighlightingStylesSelectionDialog, |
|
555 ) |
|
556 |
544 dlg = EditorHighlightingStylesSelectionDialog( |
557 dlg = EditorHighlightingStylesSelectionDialog( |
545 lexerNames, forImport=False, preselect=preselect) |
558 lexerNames, forImport=False, preselect=preselect |
|
559 ) |
546 if dlg.exec() == QDialog.DialogCode.Accepted: |
560 if dlg.exec() == QDialog.DialogCode.Accepted: |
547 lexerNames = dlg.getLexerNames() |
561 lexerNames = dlg.getLexerNames() |
548 else: |
562 else: |
549 # Cancelled by user |
563 # Cancelled by user |
550 return |
564 return |
551 |
565 |
552 lexers = [self.lexers[name] for name in lexerNames] |
566 lexers = [self.lexers[name] for name in lexerNames] |
553 |
567 |
554 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
568 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( |
555 self, |
569 self, |
556 self.tr("Export Highlighting Styles"), |
570 self.tr("Export Highlighting Styles"), |
557 stylesDir, |
571 stylesDir, |
558 self.tr("Highlighting Styles File (*.ehj)"), |
572 self.tr("Highlighting Styles File (*.ehj)"), |
559 "", |
573 "", |
560 EricFileDialog.DontConfirmOverwrite) |
574 EricFileDialog.DontConfirmOverwrite, |
561 |
575 ) |
|
576 |
562 if not fn: |
577 if not fn: |
563 return |
578 return |
564 |
579 |
565 fpath = pathlib.Path(fn) |
580 fpath = pathlib.Path(fn) |
566 if not fpath.suffix: |
581 if not fpath.suffix: |
567 ex = selectedFilter.split("(*")[1].split(")")[0] |
582 ex = selectedFilter.split("(*")[1].split(")")[0] |
568 if ex: |
583 if ex: |
569 fpath = fpath.with_suffix(ex) |
584 fpath = fpath.with_suffix(ex) |
570 |
585 |
571 ok = ( |
586 ok = ( |
572 EricMessageBox.yesNo( |
587 EricMessageBox.yesNo( |
573 self, |
588 self, |
574 self.tr("Export Highlighting Styles"), |
589 self.tr("Export Highlighting Styles"), |
575 self.tr("""<p>The highlighting styles file <b>{0}</b> exists""" |
590 self.tr( |
576 """ already. Overwrite it?</p>""").format(fpath)) |
591 """<p>The highlighting styles file <b>{0}</b> exists""" |
577 if fpath.exists() else |
592 """ already. Overwrite it?</p>""" |
578 True |
593 ).format(fpath), |
579 ) |
594 ) |
580 |
595 if fpath.exists() |
|
596 else True |
|
597 ) |
|
598 |
581 if ok: |
599 if ok: |
582 from Preferences.HighlightingStylesFile import ( |
600 from Preferences.HighlightingStylesFile import HighlightingStylesFile |
583 HighlightingStylesFile |
601 |
584 ) |
|
585 highlightingStylesFile = HighlightingStylesFile() |
602 highlightingStylesFile = HighlightingStylesFile() |
586 highlightingStylesFile.writeFile(str(fpath), lexers) |
603 highlightingStylesFile.writeFile(str(fpath), lexers) |
587 |
604 |
588 def __importStyles(self, importAll=False): |
605 def __importStyles(self, importAll=False): |
589 """ |
606 """ |
590 Private method to import the styles of lexers to be selected. |
607 Private method to import the styles of lexers to be selected. |
591 |
608 |
592 @param importAll flag indicating to import all styles without asking |
609 @param importAll flag indicating to import all styles without asking |
593 (defaults to False) |
610 (defaults to False) |
594 @type bool (optional) |
611 @type bool (optional) |
595 """ |
612 """ |
596 from eric7config import getConfig |
613 from eric7config import getConfig |
|
614 |
597 stylesDir = getConfig("ericStylesDir") |
615 stylesDir = getConfig("ericStylesDir") |
598 |
616 |
599 fn = EricFileDialog.getOpenFileName( |
617 fn = EricFileDialog.getOpenFileName( |
600 self, |
618 self, |
601 self.tr("Import Highlighting Styles"), |
619 self.tr("Import Highlighting Styles"), |
602 stylesDir, |
620 stylesDir, |
603 self.tr("Highlighting Styles File (*.ehj);;" |
621 self.tr( |
604 "XML Highlighting Styles File (*.e6h *.e4h)")) |
622 "Highlighting Styles File (*.ehj);;" |
605 |
623 "XML Highlighting Styles File (*.e6h *.e4h)" |
|
624 ), |
|
625 ) |
|
626 |
606 if not fn: |
627 if not fn: |
607 return |
628 return |
608 |
629 |
609 if fn.endswith(".ehj"): |
630 if fn.endswith(".ehj"): |
610 # new JSON based file |
631 # new JSON based file |
611 from Preferences.HighlightingStylesFile import ( |
632 from Preferences.HighlightingStylesFile import HighlightingStylesFile |
612 HighlightingStylesFile |
633 |
613 ) |
|
614 highlightingStylesFile = HighlightingStylesFile() |
634 highlightingStylesFile = HighlightingStylesFile() |
615 styles = highlightingStylesFile.readFile(fn) |
635 styles = highlightingStylesFile.readFile(fn) |
616 if not styles: |
636 if not styles: |
617 return |
637 return |
618 else: |
638 else: |
619 # old XML based file |
639 # old XML based file |
620 f = QFile(fn) |
640 f = QFile(fn) |
621 if f.open(QIODevice.OpenModeFlag.ReadOnly): |
641 if f.open(QIODevice.OpenModeFlag.ReadOnly): |
622 from EricXML.HighlightingStylesReader import ( |
642 from EricXML.HighlightingStylesReader import HighlightingStylesReader |
623 HighlightingStylesReader |
643 |
624 ) |
|
625 reader = HighlightingStylesReader(f, self.lexers) |
644 reader = HighlightingStylesReader(f, self.lexers) |
626 styles = reader.readXML() |
645 styles = reader.readXML() |
627 f.close() |
646 f.close() |
628 if not styles: |
647 if not styles: |
629 return |
648 return |
679 font.fromString(styleDict["font"]) |
698 font.fromString(styleDict["font"]) |
680 lexer.setFont(font, style, substyle) |
699 lexer.setFont(font, style, substyle) |
681 lexer.setEolFill(styleDict["eolfill"], style, substyle) |
700 lexer.setEolFill(styleDict["eolfill"], style, substyle) |
682 if substyle >= 0: |
701 if substyle >= 0: |
683 # description and words can only be set for sub-styles |
702 # description and words can only be set for sub-styles |
684 lexer.setDescription(styleDict["description"], |
703 lexer.setDescription(styleDict["description"], style, substyle) |
685 style, substyle) |
|
686 lexer.setWords(styleDict["words"], style, substyle) |
704 lexer.setWords(styleDict["words"], style, substyle) |
687 |
705 |
688 ####################################################################### |
706 ####################################################################### |
689 ## Methods to save and restore the state |
707 ## Methods to save and restore the state |
690 ####################################################################### |
708 ####################################################################### |
691 |
709 |
692 def saveState(self): |
710 def saveState(self): |
693 """ |
711 """ |
694 Public method to save the current state of the widget. |
712 Public method to save the current state of the widget. |
695 |
713 |
696 @return list containing the index of the selected lexer language |
714 @return list containing the index of the selected lexer language |
697 and a tuple containing the index of the parent selected lexer |
715 and a tuple containing the index of the parent selected lexer |
698 entry and the index of the selected entry |
716 entry and the index of the selected entry |
699 @rtype list of int and tuple of (int, int) |
717 @rtype list of int and tuple of (int, int) |
700 """ |
718 """ |
701 itm = self.styleElementList.currentItem() |
719 itm = self.styleElementList.currentItem() |
702 if itm: |
720 if itm: |
703 parent = itm.parent() |
721 parent = itm.parent() |
704 if parent is None: |
722 if parent is None: |
705 currentData = ( |
723 currentData = (None, self.styleElementList.indexOfTopLevelItem(itm)) |
706 None, self.styleElementList.indexOfTopLevelItem(itm)) |
|
707 else: |
724 else: |
708 currentData = ( |
725 currentData = ( |
709 self.styleElementList.indexOfTopLevelItem(parent), |
726 self.styleElementList.indexOfTopLevelItem(parent), |
710 parent.indexOfChild(itm) |
727 parent.indexOfChild(itm), |
711 ) |
728 ) |
712 |
729 |
713 savedState = [ |
730 savedState = [ |
714 self.lexerLanguageComboBox.currentIndex(), |
731 self.lexerLanguageComboBox.currentIndex(), |
715 currentData, |
732 currentData, |
716 ] |
733 ] |
717 else: |
734 else: |
718 savedState = [] |
735 savedState = [] |
719 return savedState |
736 return savedState |
720 |
737 |
721 def setState(self, state): |
738 def setState(self, state): |
722 """ |
739 """ |
723 Public method to set the state of the widget. |
740 Public method to set the state of the widget. |
724 |
741 |
725 @param state state data generated by saveState |
742 @param state state data generated by saveState |
726 """ |
743 """ |
727 if state: |
744 if state: |
728 self.lexerLanguageComboBox.setCurrentIndex(state[0]) |
745 self.lexerLanguageComboBox.setCurrentIndex(state[0]) |
729 self.on_lexerLanguageComboBox_activated( |
746 self.on_lexerLanguageComboBox_activated( |
730 self.lexerLanguageComboBox.currentIndex()) |
747 self.lexerLanguageComboBox.currentIndex() |
731 |
748 ) |
|
749 |
732 parentIndex, index = state[1] |
750 parentIndex, index = state[1] |
733 if parentIndex is None: |
751 if parentIndex is None: |
734 itm = self.styleElementList.topLevelItem(index) |
752 itm = self.styleElementList.topLevelItem(index) |
735 else: |
753 else: |
736 parent = self.styleElementList.topLevelItem(parentIndex) |
754 parent = self.styleElementList.topLevelItem(parentIndex) |
737 itm = parent.child(index) |
755 itm = parent.child(index) |
738 self.styleElementList.setCurrentItem(itm) |
756 self.styleElementList.setCurrentItem(itm) |
739 |
757 |
740 ####################################################################### |
758 ####################################################################### |
741 ## Methods to add, delete and edit sub-styles and their definitions |
759 ## Methods to add, delete and edit sub-styles and their definitions |
742 ####################################################################### |
760 ####################################################################### |
743 |
761 |
744 @pyqtSlot() |
762 @pyqtSlot() |
745 def on_addSubstyleButton_clicked(self): |
763 def on_addSubstyleButton_clicked(self): |
746 """ |
764 """ |
747 Private slot to add a new sub-style. |
765 Private slot to add a new sub-style. |
748 """ |
766 """ |
749 style, substyle = self.__currentStyles() |
767 style, substyle = self.__currentStyles() |
750 dlg = SubstyleDefinitionDialog( |
768 dlg = SubstyleDefinitionDialog(self.lexer, style, substyle, parent=self) |
751 self.lexer, style, substyle, parent=self) |
|
752 if dlg.exec() == QDialog.DialogCode.Accepted: |
769 if dlg.exec() == QDialog.DialogCode.Accepted: |
753 description, words = dlg.getData() |
770 description, words = dlg.getData() |
754 substyle = self.lexer.addSubstyle(style) |
771 substyle = self.lexer.addSubstyle(style) |
755 self.lexer.setDescription(description, style, substyle) |
772 self.lexer.setDescription(description, style, substyle) |
756 self.lexer.setWords(words, style, substyle) |
773 self.lexer.setWords(words, style, substyle) |
757 |
774 |
758 parent = self.styleElementList.findItems( |
775 parent = self.styleElementList.findItems( |
759 self.lexer.description(style), Qt.MatchFlag.MatchExactly)[0] |
776 self.lexer.description(style), Qt.MatchFlag.MatchExactly |
|
777 )[0] |
760 parent.setExpanded(True) |
778 parent.setExpanded(True) |
761 itm = QTreeWidgetItem(parent, [description]) |
779 itm = QTreeWidgetItem(parent, [description]) |
762 itm.setData(0, self.StyleRole, style) |
780 itm.setData(0, self.StyleRole, style) |
763 itm.setData(0, self.SubstyleRole, substyle) |
781 itm.setData(0, self.SubstyleRole, substyle) |
764 self.__styleOneItem(itm, style, substyle) |
782 self.__styleOneItem(itm, style, substyle) |
765 |
783 |
766 @pyqtSlot() |
784 @pyqtSlot() |
767 def on_deleteSubstyleButton_clicked(self): |
785 def on_deleteSubstyleButton_clicked(self): |
768 """ |
786 """ |
769 Private slot to delete the selected sub-style. |
787 Private slot to delete the selected sub-style. |
770 """ |
788 """ |
771 style, substyle = self.__currentStyles() |
789 style, substyle = self.__currentStyles() |
772 ok = EricMessageBox.yesNo( |
790 ok = EricMessageBox.yesNo( |
773 self, |
791 self, |
774 self.tr("Delete Sub-Style"), |
792 self.tr("Delete Sub-Style"), |
775 self.tr("""<p>Shall the sub-style <b>{0}</b> really be""" |
793 self.tr( |
776 """ deleted?</p>""").format( |
794 """<p>Shall the sub-style <b>{0}</b> really be""" """ deleted?</p>""" |
777 self.lexer.description(style, substyle)) |
795 ).format(self.lexer.description(style, substyle)), |
778 ) |
796 ) |
779 if ok: |
797 if ok: |
780 self.lexer.delSubstyle(style, substyle) |
798 self.lexer.delSubstyle(style, substyle) |
781 |
799 |
782 itm = self.styleElementList.currentItem() |
800 itm = self.styleElementList.currentItem() |
783 parent = itm.parent() |
801 parent = itm.parent() |
784 index = parent.indexOfChild(itm) |
802 index = parent.indexOfChild(itm) |
785 parent.takeChild(index) |
803 parent.takeChild(index) |
786 del itm |
804 del itm |
787 |
805 |
788 @pyqtSlot() |
806 @pyqtSlot() |
789 def on_editSubstyleButton_clicked(self): |
807 def on_editSubstyleButton_clicked(self): |
790 """ |
808 """ |
791 Private slot to edit the selected sub-style entry. |
809 Private slot to edit the selected sub-style entry. |
792 """ |
810 """ |
793 style, substyle = self.__currentStyles() |
811 style, substyle = self.__currentStyles() |
794 dlg = SubstyleDefinitionDialog( |
812 dlg = SubstyleDefinitionDialog(self.lexer, style, substyle, parent=self) |
795 self.lexer, style, substyle, parent=self) |
|
796 if dlg.exec() == QDialog.DialogCode.Accepted: |
813 if dlg.exec() == QDialog.DialogCode.Accepted: |
797 description, words = dlg.getData() |
814 description, words = dlg.getData() |
798 self.lexer.setDescription(description, style, substyle) |
815 self.lexer.setDescription(description, style, substyle) |
799 self.lexer.setWords(words, style, substyle) |
816 self.lexer.setWords(words, style, substyle) |
800 |
817 |
801 itm = self.styleElementList.currentItem() |
818 itm = self.styleElementList.currentItem() |
802 itm.setText(0, description) |
819 itm.setText(0, description) |
803 |
820 |
804 @pyqtSlot() |
821 @pyqtSlot() |
805 def on_copySubstyleButton_clicked(self): |
822 def on_copySubstyleButton_clicked(self): |
806 """ |
823 """ |
807 Private slot to copy the selected sub-style. |
824 Private slot to copy the selected sub-style. |
808 """ |
825 """ |
809 style, substyle = self.__currentStyles() |
826 style, substyle = self.__currentStyles() |
810 newSubstyle = self.lexer.addSubstyle(style) |
827 newSubstyle = self.lexer.addSubstyle(style) |
811 |
828 |
812 description = self.tr("{0} - Copy").format( |
829 description = self.tr("{0} - Copy").format( |
813 self.lexer.description(style, substyle)) |
830 self.lexer.description(style, substyle) |
|
831 ) |
814 self.lexer.setDescription(description, style, newSubstyle) |
832 self.lexer.setDescription(description, style, newSubstyle) |
815 self.lexer.setWords(self.lexer.words(style, substyle), |
833 self.lexer.setWords(self.lexer.words(style, substyle), style, newSubstyle) |
816 style, newSubstyle) |
834 self.lexer.setColor(self.lexer.color(style, substyle), style, newSubstyle) |
817 self.lexer.setColor(self.lexer.color(style, substyle), |
835 self.lexer.setPaper(self.lexer.paper(style, substyle), style, newSubstyle) |
818 style, newSubstyle) |
836 self.lexer.setFont(self.lexer.font(style, substyle), style, newSubstyle) |
819 self.lexer.setPaper(self.lexer.paper(style, substyle), |
837 self.lexer.setEolFill(self.lexer.eolFill(style, substyle), style, newSubstyle) |
820 style, newSubstyle) |
838 |
821 self.lexer.setFont(self.lexer.font(style, substyle), |
|
822 style, newSubstyle) |
|
823 self.lexer.setEolFill(self.lexer.eolFill(style, substyle), |
|
824 style, newSubstyle) |
|
825 |
|
826 parent = self.styleElementList.findItems( |
839 parent = self.styleElementList.findItems( |
827 self.lexer.description(style), Qt.MatchFlag.MatchExactly)[0] |
840 self.lexer.description(style), Qt.MatchFlag.MatchExactly |
|
841 )[0] |
828 parent.setExpanded(True) |
842 parent.setExpanded(True) |
829 itm = QTreeWidgetItem(parent, [description]) |
843 itm = QTreeWidgetItem(parent, [description]) |
830 itm.setData(0, self.StyleRole, style) |
844 itm.setData(0, self.StyleRole, style) |
831 itm.setData(0, self.SubstyleRole, newSubstyle) |
845 itm.setData(0, self.SubstyleRole, newSubstyle) |
832 self.__styleOneItem(itm, style, newSubstyle) |
846 self.__styleOneItem(itm, style, newSubstyle) |
833 |
847 |
834 @pyqtSlot() |
848 @pyqtSlot() |
835 def on_defaultSubstylesButton_clicked(self): |
849 def on_defaultSubstylesButton_clicked(self): |
836 """ |
850 """ |
837 Private slot to reset all substyles to default values. |
851 Private slot to reset all substyles to default values. |
838 """ |
852 """ |
839 style, substyle = self.__currentStyles() |
853 style, substyle = self.__currentStyles() |
840 ok = EricMessageBox.yesNo( |
854 ok = EricMessageBox.yesNo( |
841 self, |
855 self, |
842 self.tr("Reset Sub-Styles to Default"), |
856 self.tr("Reset Sub-Styles to Default"), |
843 self.tr("<p>Do you really want to reset all defined sub-styles of" |
857 self.tr( |
844 " <b>{0}</b> to the default values?</p>""") |
858 "<p>Do you really want to reset all defined sub-styles of" |
845 .format(self.lexer.description(style, substyle)) |
859 " <b>{0}</b> to the default values?</p>" |
|
860 "" |
|
861 ).format(self.lexer.description(style, substyle)), |
846 ) |
862 ) |
847 if ok: |
863 if ok: |
848 # 1. reset sub-styles |
864 # 1. reset sub-styles |
849 self.lexer.loadDefaultSubStyles(style) |
865 self.lexer.loadDefaultSubStyles(style) |
850 |
866 |
851 # 2. delete all existing sub-style items |
867 # 2. delete all existing sub-style items |
852 parent = self.styleElementList.currentItem() |
868 parent = self.styleElementList.currentItem() |
853 while parent.childCount() > 0: |
869 while parent.childCount() > 0: |
854 itm = parent.takeChild(0) # __IGNORE_WARNING__ |
870 itm = parent.takeChild(0) # __IGNORE_WARNING__ |
855 del itm |
871 del itm |
856 |
872 |
857 # 3. create the new list of sub-style items |
873 # 3. create the new list of sub-style items |
858 for description, _, substyle in self.lexer.getSubStyles(style): |
874 for description, _, substyle in self.lexer.getSubStyles(style): |
859 itm = QTreeWidgetItem(parent, [description]) |
875 itm = QTreeWidgetItem(parent, [description]) |
860 itm.setData(0, self.StyleRole, style) |
876 itm.setData(0, self.StyleRole, style) |
861 itm.setData(0, self.SubstyleRole, substyle) |
877 itm.setData(0, self.SubstyleRole, substyle) |