Continued implementing a format button bar and provider classes for various markup languages.

Mon, 02 Jan 2017 20:13:40 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 02 Jan 2017 20:13:40 +0100
changeset 5398
1f4509cf8f35
parent 5397
fee5485e67f4
child 5399
c11721fa3c17

Continued implementing a format button bar and provider classes for various markup languages.

QScintilla/EditorButtonsWidget.py file | annotate | diff | comparison | revisions
QScintilla/MarkupProviders/HtmlProvider.py file | annotate | diff | comparison | revisions
QScintilla/MarkupProviders/MarkdownProvider.py file | annotate | diff | comparison | revisions
QScintilla/MarkupProviders/MarkupBase.py file | annotate | diff | comparison | revisions
QScintilla/MarkupProviders/RestructuredTextProvider.py file | annotate | diff | comparison | revisions
icons/default/formatTextBold.png file | annotate | diff | comparison | revisions
icons/default/formatTextHeader.png file | annotate | diff | comparison | revisions
icons/default/formatTextHeader1.png file | annotate | diff | comparison | revisions
icons/default/formatTextHeader2.png file | annotate | diff | comparison | revisions
icons/default/formatTextHeader3.png file | annotate | diff | comparison | revisions
icons/default/formatTextItalic.png file | annotate | diff | comparison | revisions
icons/default/formatTextStrikethrough.png file | annotate | diff | comparison | revisions
--- a/QScintilla/EditorButtonsWidget.py	Mon Jan 02 12:49:28 2017 +0100
+++ b/QScintilla/EditorButtonsWidget.py	Mon Jan 02 20:13:40 2017 +0100
@@ -11,7 +11,7 @@
 from __future__ import unicode_literals
 
 from PyQt5.QtCore import pyqtSlot
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolButton
+from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolButton, QFrame
 
 import UI.PixmapCache
 
@@ -34,9 +34,10 @@
         """
         super(EditorButtonsWidget, self).__init__(parent)
         
+        margin = 2
         self.__layout = QVBoxLayout(self)
-        self.__layout.setContentsMargins(1, 1, 1, 1)
-        self.__layout.setSpacing(1)
+        self.__layout.setContentsMargins(margin, margin, margin, margin)
+        self.__layout.setSpacing(2)
         
         self.__provider = None
         
@@ -48,7 +49,8 @@
         self.__createButtons()
         
         self.__layout.addStretch()
-        self.setMaximumWidth(self.__buttons["bold"].sizeHint().width() + 2)
+        self.setMaximumWidth(
+            self.__buttons["bold"].sizeHint().width() + 2 * margin)
         
         self.__updateButtonStates()
     
@@ -57,36 +59,72 @@
         Private slot to create the various tool buttons.
         """
         self.__buttons = {}
+        self.__separators = []
         
-        button = QToolButton(self)
-        button.setIcon(UI.PixmapCache.getIcon("formatTextBold.png"))
-        button.clicked.connect(lambda: self.__formatClicked("bold"))
-        self.__layout.addWidget(button)
-        self.__buttons["bold"] = button
+        self.__addButton("bold", "formatTextBold.png")
+        self.__addButton("italic", "formatTextItalic.png")
+        self.__addButton("strikethrough", "formatTextStrikethrough.png")
+        self.__addSeparator()
+        self.__addButton("header1", "formatTextHeader1.png")
+        self.__addButton("header2", "formatTextHeader2.png")
+        self.__addButton("header3", "formatTextHeader3.png")
+        button = self.__addButton("header", "formatTextHeader.png")
+        button.setPopupMode(QToolButton.InstantPopup)
+    
+    def __addButton(self, format, iconName):
+        """
+        Private method to add a format button.
         
+        @param format unique name of the format
+        @type str
+        @param iconName name of the icon for the button
+        @type str
+        @return generated button
+        @rtype QToolButton
+        """
         button = QToolButton(self)
-        button.setIcon(UI.PixmapCache.getIcon("formatTextItalic.png"))
-        button.clicked.connect(lambda: self.__formatClicked("italic"))
+        button.setIcon(UI.PixmapCache.getIcon(iconName))
+        button.clicked.connect(lambda: self.__formatClicked(format))
         self.__layout.addWidget(button)
-        self.__buttons["italic"] = button
+        self.__buttons[format] = button
         
-        button = QToolButton(self)
-        button.setIcon(UI.PixmapCache.getIcon("formatTextStrikethrough.png"))
-        button.clicked.connect(lambda: self.__formatClicked("strikethrough"))
-        self.__layout.addWidget(button)
-        self.__buttons["strikethrough"] = button
+        return button
+    
+    def __addSeparator(self):
+        """
+        Private method to add a separator line.
+        """
+        line = QFrame(self)
+        line.setLineWidth(2)
+        if isinstance(self.__layout, QVBoxLayout):
+            line.setFrameShape(QFrame.HLine)
+        else:
+            line.setFrameShape(QFrame.VLine)
+        line.setFrameShadow(QFrame.Sunken)
+        
+        self.__layout.addWidget(line)
+        self.__separators.append(line)
     
     @pyqtSlot()
     def __updateButtonStates(self):
         """
-        Private slot to change tzhe button states.
+        Private slot to change the button states.
         """
-        self.__provider = MarkupProviders.getMarkupProvider(self.__editor)
-        
-        self.__buttons["bold"].setEnabled(self.__provider.hasBold())
-        self.__buttons["italic"].setEnabled(self.__provider.hasItalic())
-        self.__buttons["strikethrough"].setEnabled(
-            self.__provider.hasStrikethrough())
+        provider = MarkupProviders.getMarkupProvider(self.__editor)
+        if self.__provider is None or \
+                provider.kind() != self.__provider.kind():
+            self.__provider = provider
+            
+            self.__buttons["bold"].setEnabled(self.__provider.hasBold())
+            self.__buttons["italic"].setEnabled(self.__provider.hasItalic())
+            self.__buttons["strikethrough"].setEnabled(
+                self.__provider.hasStrikethrough())
+            headerLevels = self.__provider.headerLevels()
+            self.__buttons["header1"].setEnabled(headerLevels >= 1)
+            self.__buttons["header2"].setEnabled(headerLevels >= 2)
+            self.__buttons["header3"].setEnabled(headerLevels >= 3)
+            self.__buttons["header"].setEnabled(headerLevels > 3)
+            # TODO: create header button menu
     
     def __formatClicked(self, format):
         """
@@ -101,3 +139,10 @@
             self.__provider.italic(self.__editor)
         elif format == "strikethrough":
             self.__provider.strikethrough(self.__editor)
+        elif format.startswith("header"):
+            try:
+                level = int(format[-1])
+                self.__provider.header(self.__editor, level)
+            except ValueError:
+                # TODO: implement this
+                pass
--- a/QScintilla/MarkupProviders/HtmlProvider.py	Mon Jan 02 12:49:28 2017 +0100
+++ b/QScintilla/MarkupProviders/HtmlProvider.py	Mon Jan 02 20:13:40 2017 +0100
@@ -22,6 +22,15 @@
         """
         super(HtmlProvider, self).__init__()
     
+    def kind(self):
+        """
+        Public method to get the markup kind.
+        
+        @return string with markup kind
+        @rtype str
+        """
+        return "html"
+    
     def hasBold(self):
         """
         Public method to indicate the availability of bold markup.
@@ -49,6 +58,15 @@
         """
         return True
     
+    def headerLevels(self):
+        """
+        Public method to determine the available header levels.
+        
+        @return supported header levels
+        @rtype int
+        """
+        return 6
+    
     def bold(self, editor):
         """
         Public method to generate bold text.
@@ -76,6 +94,18 @@
         """
         self.__insertMarkup("del", editor)
     
+    def header(self, editor, level):
+        """
+        Public method to generate a header.
+        
+        @param editor reference to the editor to work on
+        @type Editor
+        @param level header level
+        @type int
+        """
+        if level <= 6:
+            self.__insertMarkup("h{0}".format(level), editor)
+    
     def __insertMarkup(self, markup, editor):
         """
         Private method to insert the specified markup.
--- a/QScintilla/MarkupProviders/MarkdownProvider.py	Mon Jan 02 12:49:28 2017 +0100
+++ b/QScintilla/MarkupProviders/MarkdownProvider.py	Mon Jan 02 20:13:40 2017 +0100
@@ -22,6 +22,15 @@
         """
         super(MarkdownProvider, self).__init__()
     
+    def kind(self):
+        """
+        Public method to get the markup kind.
+        
+        @return string with markup kind
+        @rtype str
+        """
+        return "markdown"
+    
     def hasBold(self):
         """
         Public method to indicate the availability of bold markup.
@@ -49,6 +58,15 @@
         """
         return True
     
+    def headerLevels(self):
+        """
+        Public method to determine the available header levels.
+        
+        @return supported header levels
+        @rtype int
+        """
+        return 6
+    
     def bold(self, editor):
         """
         Public method to generate bold text.
@@ -76,6 +94,24 @@
         """
         self.__insertMarkup("~~", editor)
     
+    def header(self, editor, level):
+        """
+        Public method to generate a header.
+        
+        @param editor reference to the editor to work on
+        @type Editor
+        @param level header level
+        @type int
+        """
+        if editor is None or level > self.headerLevels():
+            return
+        
+        editor.beginUndoAction()
+        cline, cindex = editor.getCursorPosition()
+        editor.insertAt(level * "#" + " ", cline, 0)
+        editor.setCursorPosition(cline, level + 1)
+        editor.endUndoAction()
+    
     def __insertMarkup(self, markup, editor):
         """
         Private method to insert the specified markup.
--- a/QScintilla/MarkupProviders/MarkupBase.py	Mon Jan 02 12:49:28 2017 +0100
+++ b/QScintilla/MarkupProviders/MarkupBase.py	Mon Jan 02 20:13:40 2017 +0100
@@ -24,6 +24,15 @@
         """
         pass
     
+    def kind(self):
+        """
+        Public method to get the markup kind.
+        
+        @return markup kind all lowercased
+        @rtype str
+        """
+        return "none"
+    
     def hasBold(self):
         """
         Public method to indicate the availability of bold markup.
@@ -51,6 +60,15 @@
         """
         return False
     
+    def headerLevels(self):
+        """
+        Public method to determine the available header levels.
+        
+        @return supported header levels
+        @rtype int
+        """
+        return 0
+    
     def bold(self, editor):
         """
         Public method to generate bold text.
@@ -77,3 +95,14 @@
         @type Editor
         """
         pass
+    
+    def header(self, editor, level):
+        """
+        Public method to generate a header.
+        
+        @param editor reference to the editor to work on
+        @type Editor
+        @param level header level
+        @type int
+        """
+        pass
--- a/QScintilla/MarkupProviders/RestructuredTextProvider.py	Mon Jan 02 12:49:28 2017 +0100
+++ b/QScintilla/MarkupProviders/RestructuredTextProvider.py	Mon Jan 02 20:13:40 2017 +0100
@@ -21,6 +21,17 @@
         Constructor
         """
         super(RestructuredTextProvider, self).__init__()
+        
+        self.__headerChars = ["=", "-", "~", "+", "#", "^"]
+    
+    def kind(self):
+        """
+        Public method to get the markup kind.
+        
+        @return string with markup kind
+        @rtype str
+        """
+        return "rest"
     
     def hasBold(self):
         """
@@ -40,6 +51,15 @@
         """
         return True
     
+    def headerLevels(self):
+        """
+        Public method to determine the available header levels.
+        
+        @return supported header levels
+        @rtype int
+        """
+        return len(self.__headerChars)
+    
     def bold(self, editor):
         """
         Public method to generate bold text.
@@ -58,6 +78,30 @@
         """
         self.__insertMarkup("*", editor)
     
+    def header(self, editor, level):
+        """
+        Public method to generate a header.
+        
+        @param editor reference to the editor to work on
+        @type Editor
+        @param level header level
+        @type int
+        """
+        if editor is None or level > self.headerLevels():
+            return
+        
+        editor.beginUndoAction()
+        cline, cindex = editor.getCursorPosition()
+        lineSeparator = editor.getLineSeparator()
+        if not editor.text(cline).endswith(lineSeparator):
+            editor.insertAt(lineSeparator, cline, len(editor.text(cline)))
+        lineLength = len(editor.text(cline)) - len(lineSeparator)
+        editor.insertAt(
+            lineLength * self.__headerChars[level - 1] + lineSeparator,
+            cline + 1, 0)
+        editor.setCursorPosition(cline + 2, 0)
+        editor.endUndoAction()
+    
     def __insertMarkup(self, markup, editor):
         """
         Private method to insert the specified markup.
Binary file icons/default/formatTextBold.png has changed
Binary file icons/default/formatTextHeader.png has changed
Binary file icons/default/formatTextHeader1.png has changed
Binary file icons/default/formatTextHeader2.png has changed
Binary file icons/default/formatTextHeader3.png has changed
Binary file icons/default/formatTextItalic.png has changed
Binary file icons/default/formatTextStrikethrough.png has changed

eric ide

mercurial