Added the rich text view to the documentation viewer.

Tue, 17 Oct 2017 19:40:32 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 17 Oct 2017 19:40:32 +0200
changeset 5912
b6643d36dddd
parent 5911
0c7bcba51391
child 5913
7ab2293917f8

Added the rich text view to the documentation viewer.

Preferences/ConfigurationDialog.py file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/EditorDocViewerPage.py file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/EditorDocViewerPage.ui file | annotate | diff | comparison | revisions
UI/CodeDocumentationViewer.py file | annotate | diff | comparison | revisions
UI/CodeDocumentationViewer.ui file | annotate | diff | comparison | revisions
UI/Previewers/PreviewerHTML.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
--- a/Preferences/ConfigurationDialog.py	Mon Oct 16 20:18:04 2017 +0200
+++ b/Preferences/ConfigurationDialog.py	Tue Oct 17 19:40:32 2017 +0200
@@ -237,6 +237,9 @@
                 "editorCalltipsQScintillaPage":
                 [self.tr("QScintilla"), "qscintilla.png",
                  "EditorCalltipsQScintillaPage", "editorCalltipsPage", None],
+                "editorDocViewerPage":
+                [self.tr("Documentation Viewer"), "codeDocuViewer.png",
+                 "EditorDocViewerPage", "0editorPage", None],
                 "editorGeneralPage":
                 [self.tr("General"), "preferences-general.png",
                  "EditorGeneralPage", "0editorPage", None],
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Preferences/ConfigurationPages/EditorDocViewerPage.py	Tue Oct 17 19:40:32 2017 +0200
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2017 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Editor Documentation Viewer configuration page.
+"""
+
+from __future__ import unicode_literals
+
+from .ConfigurationPageBase import ConfigurationPageBase
+from .Ui_EditorDocViewerPage import Ui_EditorDocViewerPage
+
+from E5Gui.E5Application import e5App
+
+import Preferences
+
+
+class EditorDocViewerPage(ConfigurationPageBase, Ui_EditorDocViewerPage):
+    """
+    Class documentation goes here.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(EditorDocViewerPage, self).__init__()
+        self.setupUi(self)
+        self.setObjectName("EditorExportersPage")
+        
+        providers = e5App().getObject("DocuViewer").getProviders()
+        for provider, text in providers:
+            self.providerComboBox.addItem(text, provider)
+        
+        # set initial values
+        self.richTextCheckBox.setChecked(
+            Preferences.getDocuViewer("ShowInfoAsMarkdown"))
+        
+        provider = Preferences.getDocuViewer("Provider")
+        self.viewerGroupBox.setChecked(provider != "disabled")
+            
+        index = self.providerComboBox.findData(provider)
+        if index >= 0:
+            self.providerComboBox.setCurrentIndex(index)
+    
+    def save(self):
+        """
+        Public slot to save the Editor Typing configuration.
+        """
+        enabled = self.viewerGroupBox.isChecked()
+        if enabled:
+            Preferences.setDocuViewer(
+                "ShowInfoAsMarkdown", self.richTextCheckBox.isChecked())
+            Preferences.setDocuViewer(
+                "Provider",
+                self.providerComboBox.itemData(
+                    self.providerComboBox.currentIndex())
+            )
+        else:
+            Preferences.setDocuViewer("Provider", "disabled")
+
+
+def create(dlg):
+    """
+    Module function to create the configuration page.
+    
+    @param dlg reference to the configuration dialog
+    @return reference to the instantiated page (ConfigurationPageBase)
+    """
+    page = EditorDocViewerPage()
+    return page
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Preferences/ConfigurationPages/EditorDocViewerPage.ui	Tue Oct 17 19:40:32 2017 +0200
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditorDocViewerPage</class>
+ <widget class="QWidget" name="EditorDocViewerPage">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string>&lt;b&gt;Configure Documentation Viewer Settings&lt;/b&gt;</string>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="Line" name="line2">
+     <property name="frameShape">
+      <enum>QFrame::HLine</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Sunken</enum>
+     </property>
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="viewerGroupBox">
+     <property name="toolTip">
+      <string>Select to enable the display of code documentation</string>
+     </property>
+     <property name="title">
+      <string>Enable Documentation Viewer</string>
+     </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <widget class="QCheckBox" name="richTextCheckBox">
+        <property name="toolTip">
+         <string>Select to show code documentation as rich text</string>
+        </property>
+        <property name="text">
+         <string>Show documentation as rich text</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Documentation Provider:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QComboBox" name="providerComboBox">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="toolTip">
+           <string>Select the documentation provider to be used</string>
+          </property>
+          <property name="sizeAdjustPolicy">
+           <enum>QComboBox::AdjustToContents</enum>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>167</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>viewerGroupBox</tabstop>
+  <tabstop>richTextCheckBox</tabstop>
+  <tabstop>providerComboBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
--- a/UI/CodeDocumentationViewer.py	Mon Oct 16 20:18:04 2017 +0200
+++ b/UI/CodeDocumentationViewer.py	Tue Oct 17 19:40:32 2017 +0200
@@ -10,15 +10,75 @@
 
 from __future__ import unicode_literals
 
-from PyQt5.QtCore import pyqtSlot, pyqtSignal
-from PyQt5.QtWidgets import QWidget
+from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QThread
+from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLabel, \
+    QComboBox, QSizePolicy, QLineEdit, QTextEdit
 
-from .Ui_CodeDocumentationViewer import Ui_CodeDocumentationViewer
+from E5Gui.E5TextEditSearchWidget import E5TextEditSearchWidget
 
 import Preferences
 
 
-class CodeDocumentationViewer(QWidget, Ui_CodeDocumentationViewer):
+class PlainTextDocumentationViewer(QWidget):
+    """
+    Class implementing the plain text documentation viewer.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(PlainTextDocumentationViewer, self).__init__(parent)
+        self.setObjectName("PlainTextDocumentationViewer")
+        
+        self.__verticalLayout = QVBoxLayout(self)
+        self.__verticalLayout.setObjectName("verticalLayout")
+        
+        self.__contents = QTextEdit(self)
+        self.__contents.setTabChangesFocus(True)
+        self.__contents.setReadOnly(True)
+        self.__contents.setObjectName("contents")
+        self.__verticalLayout.addWidget(self.__contents)
+        
+        self.__searchWidget = E5TextEditSearchWidget(self)
+        self.__searchWidget.setFocusPolicy(Qt.WheelFocus)
+        self.__searchWidget.setObjectName("searchWidget")
+        self.__verticalLayout.addWidget(self.__searchWidget)
+        
+        self.__searchWidget.attachTextEdit(self.__contents)
+        
+        self.preferencesChanged()
+    
+    def clear(self):
+        """
+        Public method to clear the contents.
+        """
+        self.__contents.clear()
+    
+    def setText(self, text):
+        """
+        Public method to set the text to be shown.
+        
+        @param text text to be shown
+        @type str
+        """
+        self.__contents.setPlainText(text)
+    
+    def setHtml(self, html):
+        self.__contents.setHtml(html)
+    
+    def preferencesChanged(self):
+        """
+        Public slot to handle a change of preferences.
+        """
+        font = Preferences.getEditorOtherFonts("MonospacedFont")
+        self.__contents.setFontFamily(font.family())
+        self.__contents.setFontPointSize(font.pointSize())
+
+    
+class CodeDocumentationViewer(QWidget):
     """
     Class implementing a widget to show some source code information provided
     by plug-ins.
@@ -33,9 +93,7 @@
         @type QWidget
         """
         super(CodeDocumentationViewer, self).__init__(parent)
-        self.setupUi(self)
-        
-        self.searchWidget.attachTextEdit(self.contents)
+        self.__setupUi()
         
         self.__ui = parent
         
@@ -55,11 +113,54 @@
             "No source code documentation provider has been registered or"
             " this function has been disabled.")
         
-        self.providerComboBox.addItem(self.tr("<disabled>"), "disabled")
+        self.__processingThread = DocumentProcessingThread()
+        self.__processingThread.htmlReady.connect(self.__setHtml)
+    
+    def __setupUi(self):
+        """
+        Private method to generate the UI layout.
+        """
+        self.setObjectName("CodeDocumentationViewer")
+        
+        self.verticalLayout = QVBoxLayout(self)
+        self.verticalLayout.setObjectName("verticalLayout")
+        
+        # top row of widgets
+        self.horizontalLayout = QHBoxLayout()
+        self.horizontalLayout.setObjectName("horizontalLayout")
+        
+        self.label = QLabel(self)
+        self.label.setObjectName("label")
+        self.label.setText(self.tr("Code Info Provider:"))
+        self.horizontalLayout.addWidget(self.label)
         
-        font = Preferences.getEditorOtherFonts("MonospacedFont")
-        self.contents.setFontFamily(font.family())
-        self.contents.setFontPointSize(font.pointSize())
+        self.providerComboBox = QComboBox(self)
+        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(
+            self.providerComboBox.sizePolicy().hasHeightForWidth())
+        self.providerComboBox.setSizePolicy(sizePolicy)
+        self.providerComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
+        self.providerComboBox.setObjectName("providerComboBox")
+        self.providerComboBox.setToolTip(
+            self.tr("Select the code info provider"))
+        self.providerComboBox.addItem(self.tr("<disabled>"), "disabled")
+        self.horizontalLayout.addWidget(self.providerComboBox)
+        
+        self.objectLineEdit = QLineEdit(self)
+        self.objectLineEdit.setReadOnly(True)
+        self.objectLineEdit.setObjectName("objectLineEdit")
+        self.horizontalLayout.addWidget(self.objectLineEdit)
+        
+        self.verticalLayout.addLayout(self.horizontalLayout)
+        
+        self.contents = PlainTextDocumentationViewer(self)
+        self.contents.setObjectName("contents")
+        self.verticalLayout.addWidget(self.contents)
+        
+        self.providerComboBox.currentIndexChanged[int].connect(
+            self.on_providerComboBox_currentIndexChanged)
     
     def finalizeSetup(self):
         """
@@ -133,6 +234,21 @@
         
         return supported
     
+    def getProviders(self):
+        """
+        Public method to get a list of providers and their visible strings.
+        
+        @return list containing the providers and their visible strings
+        @rtype list of tuple of (str,str)
+        """
+        providers = []
+        for index in range(1, self.providerComboBox.count()):
+            provider = self.providerComboBox.itemData(index)
+            text = self.providerComboBox.itemText(index)
+            providers.append((provider, text))
+        
+        return providers
+    
     def showInfo(self, editor):
         """
         Public method to request code documentation data from a provider.
@@ -199,7 +315,7 @@
 
             if documentationInfo["note"]:
                 if self.__showMarkdown:
-                    note = self.tr("**Info**: _{0}_\n\n----\n\n",
+                    note = self.tr("**Info**: {0}\n\n----\n\n",
                                    "string with markdown syntax").format(
                         documentationInfo["note"])
                 else:
@@ -212,7 +328,19 @@
             fullText = "".join([title, definition, note,
                                 documentationInfo['docstring']])
         
-        self.contents.setPlainText(fullText)
+        if self.__showMarkdown:
+            self.__processingThread.process("markdown", fullText)
+        else:
+            self.contents.setText(fullText)
+    
+    def __setHtml(self, html):
+        """
+        Private slot to set the prepared HTML text.
+        
+        @param html prepared HTML text
+        @type str
+        """
+        self.contents.setHtml(html)
     
     @pyqtSlot(int)
     def on_providerComboBox_currentIndexChanged(self, index):
@@ -223,14 +351,14 @@
         @type int
         """
         if not self.__shuttingDown and not self.__startingUp:
+            self.contents.clear()
+            self.objectLineEdit.clear()
+            
             provider = self.providerComboBox.itemData(index)
             if provider == self.__disabledProvider:
                 self.documentationReady(self.__disabledString)
-            elif provider in self.__providers:
-                Preferences.setDocuViewer("Provider", provider)
+            Preferences.setDocuViewer("Provider", provider)
             self.__selectedProvider = provider
-            self.contents.clear()
-            self.objectLineEdit.clear()
     
     def shutdown(self):
         """
@@ -254,7 +382,121 @@
             if index < 0:
                 index = 0
             self.providerComboBox.setCurrentIndex(index)
+
+
+class DocumentProcessingThread(QThread):
+    """
+    Class implementing a thread to process some text into HTML usable by the
+    viewer.
+    
+    @signal htmlReady(str) emitted with the processed HTML to signal the
+        availability of the processed HTML
+    """
+    htmlReady = pyqtSignal(str)
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
         
-        font = Preferences.getEditorOtherFonts("MonospacedFont")
-        self.contents.setFontFamily(font.family())
-        self.contents.setFontPointSize(font.pointSize())
+        @param parent reference to the parent object (QObject)
+        """
+        super(DocumentProcessingThread, self).__init__()
+    
+    def process(self, language, text):
+        """
+        Public method to convert the given text to HTML.
+        
+        @param language language of the text
+        @type str
+        @param text text to be processed
+        @type str
+        """
+        if self.wait():
+            self.__language = language
+            self.__text = text
+            self.start()
+    
+    def run(self):
+        """
+        Public thread method to convert the stored data.
+        """
+        language = self.__language
+        text = self.__text
+        
+        if language == "markdown":
+            html = self.__convertMarkdown(text, True, "html5")
+        else:
+            html = "<html><body><p>"
+            html += self.tr("Format '{0}' is not supported.").format(language)
+            html += "</p></body></html>"
+        
+        self.htmlReady.emit(html)
+    
+    def __convertMarkdown(self, text, convertNewLineToBreak, htmlFormat):
+        """
+        Private method to convert Markdown text into HTML.
+        
+        @param text text to be processed
+        @type str
+        @param convertNewLineToBreak flag indicating to convert new lines
+            to HTML break
+        @type bool
+        @param htmlFormat HTML format to be generated by markdown
+        @type str
+        @return processed HTML
+        @rtype str
+        """
+        try:
+            import markdown     # __IGNORE_EXCEPTION__
+        except ImportError:
+            return self.tr(
+                """<p>Markdown view requires the <b>Markdown</b> """
+                """package.<br/>Install it with your package manager,"""
+                """ 'pip install Markdown' or see """
+                """<a href="http://pythonhosted.org/Markdown/install.html">"""
+                """installation instructions.</a></p>""")
+        
+        try:
+            import mdx_mathjax  # __IGNORE_EXCEPTION__ __IGNORE_WARNING__
+        except ImportError:
+            # mathjax doesn't require import statement if installed
+            # as extension
+            pass
+        
+        if convertNewLineToBreak:
+            extensions = ['fenced_code', 'nl2br', 'extra']
+        else:
+            extensions = ['fenced_code', 'extra']
+        
+        # version 2.0 supports only extension names, not instances
+        if markdown.version_info[0] > 2 or \
+                (markdown.version_info[0] == 2 and
+                 markdown.version_info[1] > 0):
+            class _StrikeThroughExtension(markdown.Extension):
+                """
+                Class is placed here, because it depends on imported markdown,
+                and markdown import is lazy.
+                
+                (see https://pythonhosted.org/Markdown/extensions/api.html
+                this page for details)
+                """
+                DEL_RE = r'(~~)(.*?)~~'
+
+                def extendMarkdown(self, md, md_globals):
+                    # Create the del pattern
+                    del_tag = markdown.inlinepatterns.SimpleTagPattern(
+                        self.DEL_RE, 'del')
+                    # Insert del pattern into markdown parser
+                    md.inlinePatterns.add('del', del_tag, '>not_strong')
+            
+            extensions.append(_StrikeThroughExtension())
+
+        try:
+            return markdown.markdown(text, extensions=extensions + ['mathjax'],
+                                     output_format=htmlFormat.lower())
+        except (ImportError, ValueError):
+            # markdown raises ValueError or ImportError, depends on version
+            # It is not clear, how to distinguish missing mathjax from other
+            # errors. So keep going without mathjax.
+            return markdown.markdown(text, extensions=extensions,
+                                     output_format=htmlFormat.lower())
--- a/UI/CodeDocumentationViewer.ui	Mon Oct 16 20:18:04 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CodeDocumentationViewer</class>
- <widget class="QWidget" name="CodeDocumentationViewer">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>639</width>
-    <height>595</height>
-   </rect>
-  </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
-   <item>
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="label">
-       <property name="text">
-        <string>Code Info Provider:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QComboBox" name="providerComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="toolTip">
-        <string>Select the code info provider</string>
-       </property>
-       <property name="sizeAdjustPolicy">
-        <enum>QComboBox::AdjustToContents</enum>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QLineEdit" name="objectLineEdit">
-       <property name="readOnly">
-        <bool>true</bool>
-       </property>
-      </widget>
-     </item>
-    </layout>
-   </item>
-   <item>
-    <widget class="QTextEdit" name="contents">
-     <property name="tabChangesFocus">
-      <bool>true</bool>
-     </property>
-     <property name="readOnly">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item>
-    <widget class="E5TextEditSearchWidget" name="searchWidget" native="true">
-     <property name="focusPolicy">
-      <enum>Qt::WheelFocus</enum>
-     </property>
-    </widget>
-   </item>
-  </layout>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>E5TextEditSearchWidget</class>
-   <extends>QWidget</extends>
-   <header>E5Gui/E5TextEditSearchWidget.h</header>
-   <container>1</container>
-  </customwidget>
- </customwidgets>
- <tabstops>
-  <tabstop>providerComboBox</tabstop>
-  <tabstop>objectLineEdit</tabstop>
-  <tabstop>contents</tabstop>
-  <tabstop>searchWidget</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
--- a/UI/Previewers/PreviewerHTML.py	Mon Oct 16 20:18:04 2017 +0200
+++ b/UI/Previewers/PreviewerHTML.py	Tue Oct 17 19:40:32 2017 +0200
@@ -673,9 +673,9 @@
             import markdown     # __IGNORE_EXCEPTION__
         except ImportError:
             return self.tr(
-                """<p>Markdown preview requires the <b>python-markdown</b> """
+                """<p>Markdown preview requires the <b>Markdown</b> """
                 """package.<br/>Install it with your package manager,"""
-                """ 'pip install docutils' or see """
+                """ 'pip install Markdown' or see """
                 """<a href="http://pythonhosted.org/Markdown/install.html">"""
                 """installation instructions.</a></p>""")
         
@@ -700,9 +700,8 @@
                 Class is placed here, because it depends on imported markdown,
                 and markdown import is lazy.
                 
-                (see http://achinghead.com/
-                python-markdown-adding-insert-delete.html this page for
-                details)
+                (see https://pythonhosted.org/Markdown/extensions/api.html
+                this page for details)
                 """
                 DEL_RE = r'(~~)(.*?)~~'
 
--- a/eric6.e4p	Mon Oct 16 20:18:04 2017 +0200
+++ b/eric6.e4p	Tue Oct 17 19:40:32 2017 +0200
@@ -745,6 +745,7 @@
     <Source>Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.py</Source>
     <Source>Preferences/ConfigurationPages/EditorCalltipsPage.py</Source>
     <Source>Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.py</Source>
+    <Source>Preferences/ConfigurationPages/EditorDocViewerPage.py</Source>
     <Source>Preferences/ConfigurationPages/EditorExportersPage.py</Source>
     <Source>Preferences/ConfigurationPages/EditorFilePage.py</Source>
     <Source>Preferences/ConfigurationPages/EditorGeneralPage.py</Source>
@@ -1808,6 +1809,7 @@
     <Form>Preferences/ConfigurationPages/EditorAutocompletionQScintillaPage.ui</Form>
     <Form>Preferences/ConfigurationPages/EditorCalltipsPage.ui</Form>
     <Form>Preferences/ConfigurationPages/EditorCalltipsQScintillaPage.ui</Form>
+    <Form>Preferences/ConfigurationPages/EditorDocViewerPage.ui</Form>
     <Form>Preferences/ConfigurationPages/EditorExportersPage.ui</Form>
     <Form>Preferences/ConfigurationPages/EditorFilePage.ui</Form>
     <Form>Preferences/ConfigurationPages/EditorGeneralPage.ui</Form>
@@ -1899,7 +1901,6 @@
     <Form>Tasks/TaskPropertiesDialog.ui</Form>
     <Form>Templates/TemplatePropertiesDialog.ui</Form>
     <Form>Templates/TemplateSingleVariableDialog.ui</Form>
-    <Form>UI/CodeDocumentationViewer.ui</Form>
     <Form>UI/AuthenticationDialog.ui</Form>
     <Form>UI/ClearPrivateDataDialog.ui</Form>
     <Form>UI/CompareDialog.ui</Form>

eric ide

mercurial