Sat, 16 Mar 2019 14:10:51 +0100
EditorHighlightingStylesPage: converted the styles list to QTreeWidget in order to show sub-styles indented.
--- a/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py Sat Mar 16 14:08:02 2019 +0100 +++ b/Preferences/ConfigurationPages/EditorHighlightingStylesPage.py Sat Mar 16 14:10:51 2019 +0100 @@ -12,7 +12,7 @@ from PyQt5.QtCore import pyqtSlot, Qt, QFileInfo, QFile, QIODevice from PyQt5.QtGui import QPalette, QFont from PyQt5.QtWidgets import QColorDialog, QFontDialog, QInputDialog, QMenu, \ - QListWidgetItem + QTreeWidgetItem from .ConfigurationPageBase import ConfigurationPageBase from .Ui_EditorHighlightingStylesPage import Ui_EditorHighlightingStylesPage @@ -95,14 +95,14 @@ QScintilla.Lexers.getLanguageIcon(language, False), language) self.on_lexerLanguageComboBox_activated("") - + def save(self): """ Public slot to save the Editor Highlighting Styles configuration. """ for lexer in list(self.lexers.values()): lexer.writeSettings() - + @pyqtSlot(str) def on_lexerLanguageComboBox_activated(self, language): """ @@ -127,36 +127,30 @@ self.styleGroup.setEnabled(True) for description, styleNo, subStyleNo in self.lexer.getStyles(): - itm = QListWidgetItem(description, self.styleElementList) - itm.setData(self.StyleRole, styleNo) - itm.setData(self.SubstyleRole, subStyleNo) + if subStyleNo >= 0: + parent = self.styleElementList.findItems( + self.lexer.description(styleNo), Qt.MatchExactly)[0] + parent.setExpanded(True) + else: + parent = self.styleElementList + itm = QTreeWidgetItem(parent, [description]) + itm.setData(0, self.StyleRole, styleNo) + itm.setData(0, self.SubstyleRole, subStyleNo) self.__styleAllItems() - self.styleElementList.setCurrentRow(0) + self.styleElementList.setCurrentItem( + self.styleElementList.topLevelItem(0)) - def __stylesForRow(self, row): - """ - Private method to get the style and sub-style number of the item of - a given row. - - @param row row number - @type int - @return tuple containing the style and sub-style numbers - @rtype tuple of (int, int) - """ - itm = self.styleElementList.item(row) - return self.__stylesForItem(itm) - def __stylesForItem(self, itm): """ Private method to get the style and sub-style number of the given item. @param itm reference to the item to extract the styles from - @type QListWidgetItem + @type QTreeWidgetItem @return tuple containing the style and sub-style numbers @rtype tuple of (int, int) """ - style = itm.data(self.StyleRole) - substyle = itm.data(self.SubstyleRole) + style = itm.data(0, self.StyleRole) + substyle = itm.data(0, self.SubstyleRole) return (style, substyle) @@ -180,7 +174,7 @@ Private method to style one item of the style element list. @param item reference to the item to be styled - @type QListWidgetItem + @type QTreeWidgetItem @param style base style number @type int @param substyle sub-style number @@ -191,31 +185,33 @@ font = self.lexer.font(style, substyle) eolfill = self.lexer.eolFill(style, substyle) - item.setFont(font) - item.setBackground(paper) - item.setForeground(colour) + item.setFont(0, font) + item.setBackground(0, paper) + item.setForeground(0, colour) if eolfill: - item.setCheckState(Qt.Checked) + item.setCheckState(0, Qt.Checked) else: - item.setCheckState(Qt.Unchecked) + item.setCheckState(0, Qt.Unchecked) def __styleAllItems(self): """ Private method to style all items of the style element list. """ - for row in range(self.styleElementList.count()): - style, substyle = self.__stylesForRow(row) - itm = self.styleElementList.item(row) + itm = self.styleElementList.topLevelItem(0) + while itm is not None: + style, substyle = self.__stylesForItem(itm) self.__styleOneItem(itm, style, substyle) + itm = self.styleElementList.itemBelow(itm) + @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) def on_styleElementList_currentItemChanged(self, current, previous): """ Private method to handle a change of the current row. @param current reference to the current item - @type QListWidgetItem + @type QTreeWidgetItem @param previous reference to the previous item - @type QListWidgetItem + @type QTreeWidgetItem """ if current is None: return @@ -233,7 +229,7 @@ self.sampleText.setPalette(pl) self.sampleText.repaint() self.eolfillCheckBox.setChecked(eolfill) - + @pyqtSlot() def on_foregroundButton_clicked(self): """ @@ -250,8 +246,8 @@ for selItem in self.styleElementList.selectedItems(): style, substyle = self.__stylesForItem(selItem) self.lexer.setColor(colour, style, substyle) - selItem.setForeground(colour) - + selItem.setForeground(0, colour) + @pyqtSlot() def on_backgroundButton_clicked(self): """ @@ -268,8 +264,8 @@ for selItem in self.styleElementList.selectedItems(): style, substyle = self.__stylesForItem(selItem) self.lexer.setPaper(colour, style, substyle) - selItem.setBackground(colour) - + selItem.setBackground(0, colour) + @pyqtSlot() def on_allBackgroundColoursButton_clicked(self): """ @@ -283,11 +279,14 @@ pl.setColor(QPalette.Base, colour) self.sampleText.setPalette(pl) self.sampleText.repaint() - for row in range(self.styleElementList.count()): - style, substyle = self.__stylesForRow(row) + + itm = self.styleElementList.topLevelItem(0) + while itm is not None: + style, substyle = self.__stylesForItem(itm) self.lexer.setPaper(colour, style, substyle) + itm = self.styleElementList.itemBelow(itm) self.__styleAllItems() - + def __changeFont(self, doAll, familyOnly, sizeOnly): """ Private slot to change the highlighter font. @@ -352,17 +351,19 @@ if ok: setSampleFont(font, familyOnly, sizeOnly) if doAll: - for row in range(self.styleElementList.count()): - style, substyle = self.__stylesForRow(row) + itm = self.styleElementList.topLevelItem(0) + while itm is not None: + style, substyle = self.__stylesForItem(itm) setFont(font, style, substyle, familyOnly, sizeOnly) + itm = self.styleElementList.itemBelow(itm) self.__styleAllItems() else: for selItem in self.styleElementList.selectedItems(): style, substyle = self.__stylesForItem(selItem) setFont(font, style, substyle, familyOnly, sizeOnly) itmFont = self.lexer.font(style, substyle) - selItem.setFont(itmFont) - + selItem.setFont(0, itmFont) + def __fontButtonMenuTriggered(self, act): """ Private slot used to select the font of the selected style and lexer. @@ -375,7 +376,7 @@ familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] self.__changeFont(False, familyOnly, sizeOnly) - + def __allFontsButtonMenuTriggered(self, act): """ Private slot used to change the font of all styles of a selected lexer. @@ -388,8 +389,9 @@ familyOnly = act.data() in [self.FAMILYANDSIZE, self.FAMILYONLY] sizeOnly = act.data() in [self.FAMILYANDSIZE, self.SIZEONLY] self.__changeFont(True, familyOnly, sizeOnly) - - def on_eolfillCheckBox_toggled(self, on): + + @pyqtSlot(bool) + def on_eolfillCheckBox_clicked(self, on): """ Private method used to set the eolfill for the selected style and lexer. @@ -401,8 +403,8 @@ for selItem in self.styleElementList.selectedItems(): style, substyle = self.__stylesForItem(selItem) self.lexer.setEolFill(on, style, substyle) - selItem.setCheckState(checkState) - + selItem.setCheckState(0, checkState) + @pyqtSlot() def on_allEolFillButton_clicked(self): """ @@ -420,11 +422,14 @@ if ok: enabled = selection == on self.eolfillCheckBox.setChecked(enabled) - for row in range(self.styleElementList.count()): - style, substyle = self.__stylesForRow(row) + + itm = self.styleElementList.topLevelItem(0) + while itm is not None: + style, substyle = self.__stylesForItem(itm) self.lexer.setEolFill(enabled, style, substyle) + itm = self.styleElementList.itemBelow(itm) self.__styleAllItems() - + @pyqtSlot() def on_defaultButton_clicked(self): """ @@ -436,19 +441,21 @@ self.on_styleElementList_currentItemChanged( self.styleElementList.currentItem(), None) self.__styleAllItems() - + @pyqtSlot() def on_allDefaultButton_clicked(self): """ Private method to set all styles to their default values. """ - for row in range(self.styleElementList.count()): - style, substyle = self.__stylesForRow(row) + itm = self.styleElementList.topLevelItem(0) + while itm is not None: + style, substyle = self.__stylesForItem(itm) self.__setToDefault(style, substyle) + itm = self.styleElementList.itemBelow(itm) self.on_styleElementList_currentItemChanged( self.styleElementList.currentItem(), None) self.__styleAllItems() - + def __setToDefault(self, style, substyle): """ Private method to set a specific style to its default values. @@ -466,46 +473,53 @@ style, substyle) self.lexer.setEolFill(self.lexer.defaultEolFill(style, substyle), style, substyle) - + + ####################################################################### + ## Importing and exporting of styles + ####################################################################### + @pyqtSlot() def on_importCurrentButton_clicked(self): """ Private slot to import the styles of the current lexer. """ self.__importStyles({self.lexer.language(): self.lexer}) - + @pyqtSlot() def on_exportCurrentButton_clicked(self): """ Private slot to export the styles of the current lexer. """ self.__exportStyles([self.lexer]) - + @pyqtSlot() def on_importAllButton_clicked(self): """ Private slot to import the styles of all lexers. """ self.__importStyles(self.lexers) - + @pyqtSlot() def on_exportAllButton_clicked(self): """ Private slot to export the styles of all lexers. """ self.__exportStyles(list(self.lexers.values())) - + def __exportStyles(self, lexers): """ Private method to export the styles of the given lexers. @param lexers list of lexer objects for which to export the styles """ + from eric6config import getConfig + stylesDir = getConfig("ericStylesDir") + fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, self.tr("Export Highlighting Styles"), - "", - self.tr("Highlighting styles file (*.e4h)"), + stylesDir, + self.tr("Highlighting styles file (*.e6h)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) @@ -521,7 +535,6 @@ f = QFile(fn) if f.open(QIODevice.WriteOnly): from E5XML.HighlightingStylesWriter import HighlightingStylesWriter - # TODO: sub-styles HighlightingStylesWriter(f, lexers).writeXML() f.close() else: @@ -533,7 +546,7 @@ """ to file <b>{0}</b>.</p><p>Reason: {1}</p>""") .format(fn, f.errorString()) ) - + def __importStyles(self, lexers): """ Private method to import the styles of the given lexers. @@ -548,7 +561,7 @@ self, self.tr("Import Highlighting Styles"), stylesDir, - self.tr("Highlighting styles file (*.e4h)")) + self.tr("Highlighting styles file (*.e6h *.e4h)")) if not fn: return @@ -556,7 +569,6 @@ f = QFile(fn) if f.open(QIODevice.ReadOnly): from E5XML.HighlightingStylesReader import HighlightingStylesReader - # TODO: sub-styles reader = HighlightingStylesReader(f, lexers) reader.readXML() f.close() @@ -571,36 +583,39 @@ ) return - if self.lexer: - style, substyle = self.__currentStyles() - colour = self.lexer.color(style, substyle) - paper = self.lexer.paper(style, substyle) - eolfill = self.lexer.eolFill(style, substyle) - font = self.lexer.font(style, substyle) - - self.sampleText.setFont(font) - pl = self.sampleText.palette() - pl.setColor(QPalette.Text, colour) - pl.setColor(QPalette.Base, paper) - self.sampleText.setPalette(pl) - self.sampleText.repaint() - self.eolfillCheckBox.setChecked(eolfill) - - self.__styleAllItems() - + self.on_lexerLanguageComboBox_activated( + self.lexerLanguageComboBox.currentText()) + + ####################################################################### + ## Methods to save and restore the state + ####################################################################### + def saveState(self): """ Public method to save the current state of the widget. - @return array containing the index of the selected lexer language - (integer) and the index of the selected lexer entry (integer) + @return list containing the index of the selected lexer language + and a tuple containing the index of the parent selected lexer + entry and the index of the selected entry + @rtype list of int and tuple of (int, int) """ + itm = self.styleElementList.currentItem() + parent = itm.parent() + if parent is None: + currentData = ( + None, self.styleElementList.indexOfTopLevelItem(itm)) + else: + currentData = ( + self.styleElementList.indexOfTopLevelItem(parent), + parent.indexOfChild(itm) + ) + savedState = [ self.lexerLanguageComboBox.currentIndex(), - self.styleElementList.currentRow(), + currentData, ] return savedState - + def setState(self, state): """ Public method to set the state of the widget. @@ -610,7 +625,14 @@ self.lexerLanguageComboBox.setCurrentIndex(state[0]) self.on_lexerLanguageComboBox_activated( self.lexerLanguageComboBox.currentText()) - self.styleElementList.setCurrentRow(state[1]) + + parentIndex, index = state[1] + if parentIndex is None: + itm = self.styleElementList.topLevelItem(index) + else: + parent = self.styleElementList.topLevelItem(parentIndex) + itm = parent.child(index) + self.styleElementList.setCurrentItem(itm) def create(dlg):
--- a/Preferences/ConfigurationPages/EditorHighlightingStylesPage.ui Sat Mar 16 14:08:02 2019 +0100 +++ b/Preferences/ConfigurationPages/EditorHighlightingStylesPage.ui Sat Mar 16 14:10:51 2019 +0100 @@ -67,13 +67,6 @@ <string>Style Element</string> </property> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" rowspan="14"> - <widget class="QListWidget" name="styleElementList"> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - </widget> - </item> <item row="0" column="1"> <widget class="QPushButton" name="foregroundButton"> <property name="toolTip"> @@ -246,6 +239,27 @@ </property> </widget> </item> + <item row="0" column="0" rowspan="14"> + <widget class="QTreeWidget" name="styleElementList"> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string notr="true">1</string> + </property> + </column> + </widget> + </item> </layout> </widget> </item>