EditorHighlightingStylesPage: converted the styles list to QTreeWidget in order to show sub-styles indented. sub_styles

Sat, 16 Mar 2019 14:10:51 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 16 Mar 2019 14:10:51 +0100
branch
sub_styles
changeset 6862
6f4237ccf576
parent 6861
20899dc18e59
child 6863
e900929889dd

EditorHighlightingStylesPage: converted the styles list to QTreeWidget in order to show sub-styles indented.

Preferences/ConfigurationPages/EditorHighlightingStylesPage.py file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/EditorHighlightingStylesPage.ui file | annotate | diff | comparison | revisions
--- 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>

eric ide

mercurial