Sun, 01 Jan 2017 18:09:48 +0100
Started implementing a format button bar and provider classes for various markup languages.
--- a/QScintilla/EditorAssembly.py Sat Dec 31 17:52:23 2016 +0100 +++ b/QScintilla/EditorAssembly.py Sun Jan 01 18:09:48 2017 +0100 @@ -41,14 +41,18 @@ self.__layout.setContentsMargins(0, 0, 0, 0) self.__layout.setSpacing(1) + from .EditorButtonsWidget import EditorButtonsWidget + from .Editor import Editor + + self.__editor = Editor(dbs, fn, vm, filetype, editor, tv) + self.__buttonsWidget = EditorButtonsWidget(self.__editor) self.__globalsCombo = QComboBox() self.__membersCombo = QComboBox() - from .Editor import Editor - self.__editor = Editor(dbs, fn, vm, filetype, editor, tv) - self.__layout.addWidget(self.__globalsCombo, 0, 0) - self.__layout.addWidget(self.__membersCombo, 0, 1) - self.__layout.addWidget(self.__editor, 1, 0, 1, -1) + self.__layout.addWidget(self.__buttonsWidget, 1, 0, -1, 1) + self.__layout.addWidget(self.__globalsCombo, 0, 1) + self.__layout.addWidget(self.__membersCombo, 0, 2) + self.__layout.addWidget(self.__editor, 1, 1, 1, -1) self.__module = None
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/EditorButtonsWidget.py Sun Jan 01 18:09:48 2017 +0100 @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a widget containing various buttons for accessing +editor actions. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import pyqtSlot +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolButton + +import UI.PixmapCache + +from . import MarkupProviders + + +class EditorButtonsWidget(QWidget): + """ + Class implementing a widget containing various buttons for accessing + editor actions. + """ + def __init__(self, editor, parent=None): + """ + Constructor + + @param editor reference to the editor + @type Editor + @param parent reference to the parent widget + @type QWidget + """ + super(EditorButtonsWidget, self).__init__(parent) + + self.__layout = QVBoxLayout(self) + self.__layout.setContentsMargins(1, 1, 1, 1) + self.__layout.setSpacing(1) + + self.__provider = None + + self.__editor = editor + self.__editor.languageChanged.connect(self.__updateButtonStates) + self.__editor.editorSaved.connect(self.__updateButtonStates) + self.__editor.editorRenamed.connect(self.__updateButtonStates) + + self.__createButtons() + + self.__layout.addStretch() + self.setMaximumWidth(self.__buttons["bold"].sizeHint().width() + 2) + + self.__updateButtonStates() + + def __createButtons(self): + """ + Private slot to create the various tool buttons. + """ + self.__buttons = {} + + 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 + + button = QToolButton(self) + button.setIcon(UI.PixmapCache.getIcon("formatTextItalic.png")) + button.clicked.connect(lambda: self.__formatClicked("italic")) + self.__layout.addWidget(button) + self.__buttons["italic"] = 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 + + @pyqtSlot() + def __updateButtonStates(self): + """ + Private slot to change tzhe 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()) + + def __formatClicked(self, format): + """ + Private slot to handle a format button being clicked. + + @param format format type of the button + @type str + """ + if format == "bold": + self.__provider.bold(self.__editor) + elif format == "italic": + self.__provider.italic(self.__editor) + elif format == "strikethrough": + self.__provider.strikethrough(self.__editor)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/MarkupProviders/MarkdownProvider.py Sun Jan 01 18:09:48 2017 +0100 @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the base class for the markup providers. +""" + +from __future__ import unicode_literals + +from .MarkupBase import MarkupBase + + +class MarkdownProvider(MarkupBase): + """ + Class implementing the base class for the markup providers. + + Note: Derived classes need only implement those method they provide + functionality for. This base class implements do nothing variants for + all methods. + """ + def __init__(self): + """ + Constructor + """ + super(MarkdownProvider, self).__init__() + + def hasBold(self): + """ + Public method to indicate the availability of bold markup. + + @return flag indicating the availability of bold markup + @rtype bool + """ + return True + + def hasItalic(self): + """ + Public method to indicate the availability of italic markup. + + @return flag indicating the availability of italic markup + @rtype bool + """ + return True + + def hasStrikethrough(self): + """ + Public method to indicate the availability of strikethrough markup. + + @return flag indicating the availability of strikethrough markup + @rtype bool + """ + return True + + def bold(self, editor): + """ + Public method to generate bold text. + + @param editor reference to the editor to work on + @type Editor + """ + self.__insertMarkup("**", editor) + + def italic(self, editor): + """ + Public method to generate italic text. + + @param editor reference to the editor to work on + @type Editor + """ + self.__insertMarkup("_", editor) + + def strikethrough(self, editor): + """ + Public method to generate strikethrough text. + + @param editor reference to the editor to work on + @type Editor + """ + self.__insertMarkup("~~", editor) + + def __insertMarkup(self, markup, editor): + """ + Private method to insert the specified markup. + + If the editor has selected text, this text is enclosed by the given + markup. If no text is selected, the markup is inserted at the cursor + position and the cursor is positioned in between. + + @param markup markup string to be inserted + @type str + @param editor reference to the editor to work on + @type Editor + """ + if editor is None: + return + + editor.beginUndoAction() + if editor.hasSelectedText(): + newText = "{0}{1}{0}".format(markup, editor.selectedText()) + editor.replaceSelectedText(newText) + else: + editor.insert(2 * markup) + cline, cindex = editor.getCursorPosition() + editor.setCursorPosition(cline, cindex + len(markup)) + editor.endUndoAction()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/MarkupProviders/MarkupBase.py Sun Jan 01 18:09:48 2017 +0100 @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing the base class for the markup providers. +""" + +from __future__ import unicode_literals + + +class MarkupBase(object): + """ + Class implementing the base class for the markup providers. + + Note: Derived classes need only implement those method they provide + functionality for. This base class implements do nothing variants for + all methods. + """ + def __init__(self): + """ + Constructor + """ + pass + + def hasBold(self): + """ + Public method to indicate the availability of bold markup. + + @return flag indicating the availability of bold markup + @rtype bool + """ + return False + + def hasItalic(self): + """ + Public method to indicate the availability of italic markup. + + @return flag indicating the availability of italic markup + @rtype bool + """ + return False + + def hasStrikethrough(self): + """ + Public method to indicate the availability of strikethrough markup. + + @return flag indicating the availability of strikethrough markup + @rtype bool + """ + return False + + def bold(self, editor): + """ + Public method to generate bold text. + + @param editor reference to the editor to work on + @type Editor + """ + pass + + def italic(self, editor): + """ + Public method to generate italic text. + + @param editor reference to the editor to work on + @type Editor + """ + pass + + def strikethrough(self, editor): + """ + Public method to generate strikethrough text. + + @param editor reference to the editor to work on + @type Editor + """ + pass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QScintilla/MarkupProviders/__init__.py Sun Jan 01 18:09:48 2017 +0100 @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Package providing various markup providers. +""" + +from __future__ import unicode_literals + +import os + +import Preferences + + +def getMarkupProvider(editor): + """ + Public method to get a markup provider for the given editor. + + @param editor reference to the editor to get the markup provider for + @type Editor + @return markup provider + @rtype MarkupBase + """ + if editor is not None: + fn = editor.getFileName() + + if fn: + extension = os.path.normcase(os.path.splitext(fn)[1][1:]) + else: + extension = "" + if extension in \ + Preferences.getEditor("PreviewHtmlFileNameExtensions") or \ + editor.getLanguage() == "HTML": + # TODO: implement this + pass + elif extension in \ + Preferences.getEditor("PreviewMarkdownFileNameExtensions") or \ + editor.getLanguage().lower() == "markdown": + from .MarkdownProvider import MarkdownProvider + return MarkdownProvider() + elif extension in \ + Preferences.getEditor("PreviewRestFileNameExtensions") or \ + editor.getLanguage().lower() == "restructuredtext": + # TODO: implement this + pass + + # no supported markup provider identified + from .MarkupBase import MarkupBase + return MarkupBase()
--- a/UI/Previewers/PreviewerHTML.py Sat Dec 31 17:52:23 2016 +0100 +++ b/UI/Previewers/PreviewerHTML.py Sun Jan 01 18:09:48 2017 +0100 @@ -591,7 +591,8 @@ except ImportError: return self.tr( """<p>Markdown preview requires the <b>python-markdown</b> """ - """package.<br/>Install it with your package manager or see """ + """package.<br/>Install it with your package manager,""" + """ 'pip install docutils' or see """ """<a href="http://pythonhosted.org/Markdown/install.html">""" """installation instructions.</a></p>""")
--- a/eric6.e4p Sat Dec 31 17:52:23 2016 +0100 +++ b/eric6.e4p Sun Jan 01 18:09:48 2017 +0100 @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Project SYSTEM "Project-5.1.dtd"> <!-- eric project file for project eric6 --> -<!-- Copyright (C) 2016 Detlev Offenbach, detlev@die-offenbachs.de --> +<!-- Copyright (C) 2017 Detlev Offenbach, detlev@die-offenbachs.de --> <Project version="5.1"> <Language>en_US</Language> <ProjectWordList>Dictionaries/words.dic</ProjectWordList> @@ -833,6 +833,7 @@ <Source>QScintilla/APIsManager.py</Source> <Source>QScintilla/Editor.py</Source> <Source>QScintilla/EditorAssembly.py</Source> + <Source>QScintilla/EditorButtonsWidget.py</Source> <Source>QScintilla/EditorMarkerMap.py</Source> <Source>QScintilla/Exporters/ExporterBase.py</Source> <Source>QScintilla/Exporters/ExporterHTML.py</Source> @@ -881,6 +882,9 @@ <Source>QScintilla/Lexers/LexerXML.py</Source> <Source>QScintilla/Lexers/LexerYAML.py</Source> <Source>QScintilla/Lexers/__init__.py</Source> + <Source>QScintilla/MarkupProviders/MarkdownProvider.py</Source> + <Source>QScintilla/MarkupProviders/MarkupBase.py</Source> + <Source>QScintilla/MarkupProviders/__init__.py</Source> <Source>QScintilla/MiniEditor.py</Source> <Source>QScintilla/Printer.py</Source> <Source>QScintilla/QsciScintillaCompat.py</Source>