Added a source code exporter for the Open Document Text (ODT) format.

Mon, 30 Aug 2010 15:24:28 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 30 Aug 2010 15:24:28 +0200
changeset 532
a3c0f1e2594a
parent 531
26efb720a299
child 533
bc6063d2ab83

Added a source code exporter for the Open Document Text (ODT) format.

APIs/Python3/eric5.api file | annotate | diff | comparison | revisions
Documentation/Help/source.qch file | annotate | diff | comparison | revisions
Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.Exporters.ExporterHTML.html file | annotate | diff | comparison | revisions
Documentation/Source/eric5.QScintilla.Exporters.ExporterODT.html file | annotate | diff | comparison | revisions
Documentation/Source/index-eric5.QScintilla.Exporters.html file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/EditorExportersPage.py file | annotate | diff | comparison | revisions
Preferences/ConfigurationPages/EditorExportersPage.ui file | annotate | diff | comparison | revisions
Preferences/__init__.py file | annotate | diff | comparison | revisions
QScintilla/Exporters/ExporterHTML.py file | annotate | diff | comparison | revisions
QScintilla/Exporters/ExporterODT.py file | annotate | diff | comparison | revisions
QScintilla/Exporters/__init__.py file | annotate | diff | comparison | revisions
changelog file | annotate | diff | comparison | revisions
eric5.e4p file | annotate | diff | comparison | revisions
--- a/APIs/Python3/eric5.api	Mon Aug 30 12:30:29 2010 +0200
+++ b/APIs/Python3/eric5.api	Mon Aug 30 15:24:28 2010 +0200
@@ -4912,6 +4912,10 @@
 eric5.QScintilla.Exporters.ExporterBase.ExporterBase?1(editor, parent = None)
 eric5.QScintilla.Exporters.ExporterHTML.ExporterHTML.exportSource?4()
 eric5.QScintilla.Exporters.ExporterHTML.ExporterHTML?1(editor, parent = None)
+eric5.QScintilla.Exporters.ExporterHTML.HTMLGenerator.generate?4(tabSize = 4, useTabs = False, wysiwyg = True, folding = False, onlyStylesUsed = False, titleFullPath = False)
+eric5.QScintilla.Exporters.ExporterHTML.HTMLGenerator?1(editor)
+eric5.QScintilla.Exporters.ExporterODT.ExporterODT.exportSource?4()
+eric5.QScintilla.Exporters.ExporterODT.ExporterODT?1(editor, parent = None)
 eric5.QScintilla.Exporters.ExporterPDF.ExporterPDF.exportSource?4()
 eric5.QScintilla.Exporters.ExporterPDF.ExporterPDF?1(editor, parent = None)
 eric5.QScintilla.Exporters.ExporterPDF.PDFObjectTracker.add?4(objectData)
Binary file Documentation/Help/source.qch has changed
--- a/Documentation/Help/source.qhp	Mon Aug 30 12:30:29 2010 +0200
+++ b/Documentation/Help/source.qhp	Mon Aug 30 15:24:28 2010 +0200
@@ -587,6 +587,7 @@
             <section title="eric5.QScintilla.Exporters" ref="index-eric5.QScintilla.Exporters.html">
               <section title="eric5.QScintilla.Exporters.ExporterBase" ref="eric5.QScintilla.Exporters.ExporterBase.html" />
               <section title="eric5.QScintilla.Exporters.ExporterHTML" ref="eric5.QScintilla.Exporters.ExporterHTML.html" />
+              <section title="eric5.QScintilla.Exporters.ExporterODT" ref="eric5.QScintilla.Exporters.ExporterODT.html" />
               <section title="eric5.QScintilla.Exporters.ExporterPDF" ref="eric5.QScintilla.Exporters.ExporterPDF.html" />
               <section title="eric5.QScintilla.Exporters.ExporterRTF" ref="eric5.QScintilla.Exporters.ExporterRTF.html" />
               <section title="eric5.QScintilla.Exporters.ExporterTEX" ref="eric5.QScintilla.Exporters.ExporterTEX.html" />
@@ -9722,6 +9723,10 @@
       <keyword name="ExporterTEX.__getTexRGB" id="ExporterTEX.__getTexRGB" ref="eric5.QScintilla.Exporters.ExporterTEX.html#ExporterTEX.__getTexRGB" />
       <keyword name="ExporterTEX.__texStyle" id="ExporterTEX.__texStyle" ref="eric5.QScintilla.Exporters.ExporterTEX.html#ExporterTEX.__texStyle" />
       <keyword name="ExporterTEX.exportSource" id="ExporterTEX.exportSource" ref="eric5.QScintilla.Exporters.ExporterTEX.html#ExporterTEX.exportSource" />
+      <keyword name="ExporterODT (Module)" id="ExporterODT (Module)" ref="eric5.QScintilla.Exporters.ExporterODT.html" />
+      <keyword name="ExporterODT" id="ExporterODT" ref="eric5.QScintilla.Exporters.ExporterODT.html#ExporterODT" />
+      <keyword name="ExporterODT (Constructor)" id="ExporterODT (Constructor)" ref="eric5.QScintilla.Exporters.ExporterODT.html#ExporterODT.__init__" />
+      <keyword name="ExporterODT.exportSource" id="ExporterODT.exportSource" ref="eric5.QScintilla.Exporters.ExporterODT.html#ExporterODT.exportSource" />
       <keyword name="ExporterBase (Module)" id="ExporterBase (Module)" ref="eric5.QScintilla.Exporters.ExporterBase.html" />
       <keyword name="ExporterBase" id="ExporterBase" ref="eric5.QScintilla.Exporters.ExporterBase.html#ExporterBase" />
       <keyword name="ExporterBase (Constructor)" id="ExporterBase (Constructor)" ref="eric5.QScintilla.Exporters.ExporterBase.html#ExporterBase.__init__" />
@@ -9735,8 +9740,11 @@
       <keyword name="ExporterRTF.exportSource" id="ExporterRTF.exportSource" ref="eric5.QScintilla.Exporters.ExporterRTF.html#ExporterRTF.exportSource" />
       <keyword name="ExporterHTML (Module)" id="ExporterHTML (Module)" ref="eric5.QScintilla.Exporters.ExporterHTML.html" />
       <keyword name="ExporterHTML" id="ExporterHTML" ref="eric5.QScintilla.Exporters.ExporterHTML.html#ExporterHTML" />
+      <keyword name="HTMLGenerator" id="HTMLGenerator" ref="eric5.QScintilla.Exporters.ExporterHTML.html#HTMLGenerator" />
       <keyword name="ExporterHTML (Constructor)" id="ExporterHTML (Constructor)" ref="eric5.QScintilla.Exporters.ExporterHTML.html#ExporterHTML.__init__" />
       <keyword name="ExporterHTML.exportSource" id="ExporterHTML.exportSource" ref="eric5.QScintilla.Exporters.ExporterHTML.html#ExporterHTML.exportSource" />
+      <keyword name="HTMLGenerator (Constructor)" id="HTMLGenerator (Constructor)" ref="eric5.QScintilla.Exporters.ExporterHTML.html#HTMLGenerator.__init__" />
+      <keyword name="HTMLGenerator.generate" id="HTMLGenerator.generate" ref="eric5.QScintilla.Exporters.ExporterHTML.html#HTMLGenerator.generate" />
       <keyword name="ExporterPDF (Module)" id="ExporterPDF (Module)" ref="eric5.QScintilla.Exporters.ExporterPDF.html" />
       <keyword name="ExporterPDF" id="ExporterPDF" ref="eric5.QScintilla.Exporters.ExporterPDF.html#ExporterPDF" />
       <keyword name="PDFObjectTracker" id="PDFObjectTracker" ref="eric5.QScintilla.Exporters.ExporterPDF.html#PDFObjectTracker" />
@@ -10218,6 +10226,7 @@
       <file>eric5.QScintilla.Editor.html</file>
       <file>eric5.QScintilla.Exporters.ExporterBase.html</file>
       <file>eric5.QScintilla.Exporters.ExporterHTML.html</file>
+      <file>eric5.QScintilla.Exporters.ExporterODT.html</file>
       <file>eric5.QScintilla.Exporters.ExporterPDF.html</file>
       <file>eric5.QScintilla.Exporters.ExporterRTF.html</file>
       <file>eric5.QScintilla.Exporters.ExporterTEX.html</file>
--- a/Documentation/Source/eric5.QScintilla.Exporters.ExporterHTML.html	Mon Aug 30 12:30:29 2010 +0200
+++ b/Documentation/Source/eric5.QScintilla.Exporters.ExporterHTML.html	Mon Aug 30 15:24:28 2010 +0200
@@ -33,6 +33,9 @@
 <tr>
 <td><a href="#ExporterHTML">ExporterHTML</a></td>
 <td>Class implementing an exporter for HTML.</td>
+</tr><tr>
+<td><a href="#HTMLGenerator">HTMLGenerator</a></td>
+<td>Class implementing an HTML generator for exporting source code.</td>
 </tr>
 </table>
 <h3>Functions</h3>
@@ -81,5 +84,71 @@
         Public method performing the export.
 </p>
 <div align="right"><a href="#top">Up</a></div>
+<hr /><hr />
+<a NAME="HTMLGenerator" ID="HTMLGenerator"></a>
+<h2>HTMLGenerator</h2>
+<p>
+    Class implementing an HTML generator for exporting source code.
+</p>
+<h3>Derived from</h3>
+object
+<h3>Class Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+<table>
+<tr>
+<td><a href="#HTMLGenerator.__init__">HTMLGenerator</a></td>
+<td>Constructor</td>
+</tr><tr>
+<td><a href="#HTMLGenerator.generate">generate</a></td>
+<td>Public method to generate HTML for the source editor.</td>
+</tr>
+</table>
+<a NAME="HTMLGenerator.__init__" ID="HTMLGenerator.__init__"></a>
+<h4>HTMLGenerator (Constructor)</h4>
+<b>HTMLGenerator</b>(<i>editor</i>)
+<p>
+        Constructor
+</p><dl>
+<dt><i>editor</i></dt>
+<dd>
+reference to the editor object (QScintilla.Editor.Editor)
+</dd>
+</dl><a NAME="HTMLGenerator.generate" ID="HTMLGenerator.generate"></a>
+<h4>HTMLGenerator.generate</h4>
+<b>generate</b>(<i>tabSize = 4, useTabs = False, wysiwyg = True, folding = False, onlyStylesUsed = False, titleFullPath = False</i>)
+<p>
+        Public method to generate HTML for the source editor.
+</p><dl>
+<dt><i>tabSize=</i></dt>
+<dd>
+size of tabs (integer)
+</dd><dt><i>useTabs=</i></dt>
+<dd>
+flag indicating the use of tab characters (boolean)
+</dd><dt><i>wysiwyg=</i></dt>
+<dd>
+flag indicating colorization (boolean)
+</dd><dt><i>folding=</i></dt>
+<dd>
+flag indicating usage of fold markers
+</dd><dt><i>onlyStylesUsed=</i></dt>
+<dd>
+flag indicating to include only style definitions
+            for styles used in the source (boolean)
+</dd><dt><i>titleFullPath=</i></dt>
+<dd>
+flag indicating to include the full file path
+            in the title tag (boolean)
+</dd>
+</dl><dl>
+<dt>Returns:</dt>
+<dd>
+generated HTML text (string)
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
 <hr />
 </body></html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Documentation/Source/eric5.QScintilla.Exporters.ExporterODT.html	Mon Aug 30 15:24:28 2010 +0200
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN'
+'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
+<html><head>
+<title>eric5.QScintilla.Exporters.ExporterODT</title>
+<style>
+body {
+    background: #EDECE6;
+    margin: 0em 1em 10em 1em;
+    color: black;
+}
+
+h1 { color: white; background: #85774A; }
+h2 { color: white; background: #85774A; }
+h3 { color: white; background: #9D936E; }
+h4 { color: white; background: #9D936E; }
+    
+a { color: #BA6D36; }
+
+</style>
+</head>
+<body><a NAME="top" ID="top"></a>
+<h1>eric5.QScintilla.Exporters.ExporterODT</h1>
+<p>
+Module implementing an exporter for ODT.
+</p>
+<h3>Global Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Classes</h3>
+<table>
+<tr>
+<td><a href="#ExporterODT">ExporterODT</a></td>
+<td>Class implementing an exporter for ODT.</td>
+</tr>
+</table>
+<h3>Functions</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<hr /><hr />
+<a NAME="ExporterODT" ID="ExporterODT"></a>
+<h2>ExporterODT</h2>
+<p>
+    Class implementing an exporter for ODT.
+</p>
+<h3>Derived from</h3>
+ExporterBase
+<h3>Class Attributes</h3>
+<table>
+<tr><td>None</td></tr>
+</table>
+<h3>Methods</h3>
+<table>
+<tr>
+<td><a href="#ExporterODT.__init__">ExporterODT</a></td>
+<td>Constructor</td>
+</tr><tr>
+<td><a href="#ExporterODT.exportSource">exportSource</a></td>
+<td>Public method performing the export.</td>
+</tr>
+</table>
+<a NAME="ExporterODT.__init__" ID="ExporterODT.__init__"></a>
+<h4>ExporterODT (Constructor)</h4>
+<b>ExporterODT</b>(<i>editor, parent = None</i>)
+<p>
+        Constructor
+</p><dl>
+<dt><i>editor</i></dt>
+<dd>
+reference to the editor object (QScintilla.Editor.Editor)
+</dd><dt><i>parent</i></dt>
+<dd>
+parent object of the exporter (QObject)
+</dd>
+</dl><a NAME="ExporterODT.exportSource" ID="ExporterODT.exportSource"></a>
+<h4>ExporterODT.exportSource</h4>
+<b>exportSource</b>(<i></i>)
+<p>
+        Public method performing the export.
+</p>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+</body></html>
\ No newline at end of file
--- a/Documentation/Source/index-eric5.QScintilla.Exporters.html	Mon Aug 30 12:30:29 2010 +0200
+++ b/Documentation/Source/index-eric5.QScintilla.Exporters.html	Mon Aug 30 15:24:28 2010 +0200
@@ -35,6 +35,9 @@
 <td><a href="eric5.QScintilla.Exporters.ExporterHTML.html">ExporterHTML</a></td>
 <td>Module implementing an exporter for HTML.</td>
 </tr><tr>
+<td><a href="eric5.QScintilla.Exporters.ExporterODT.html">ExporterODT</a></td>
+<td>Module implementing an exporter for ODT.</td>
+</tr><tr>
 <td><a href="eric5.QScintilla.Exporters.ExporterPDF.html">ExporterPDF</a></td>
 <td>Module implementing an exporter for PDF.</td>
 </tr><tr>
--- a/Preferences/ConfigurationPages/EditorExportersPage.py	Mon Aug 30 12:30:29 2010 +0200
+++ b/Preferences/ConfigurationPages/EditorExportersPage.py	Mon Aug 30 15:24:28 2010 +0200
@@ -31,6 +31,7 @@
         self.pageIds = {}
         self.pageIds[' '] = self.stackedWidget.indexOf(self.emptyPage)
         self.pageIds['HTML'] = self.stackedWidget.indexOf(self.htmlPage)
+        self.pageIds['ODT'] = self.stackedWidget.indexOf(self.odtPage)
         self.pageIds['PDF'] = self.stackedWidget.indexOf(self.pdfPage)
         self.pageIds['RTF'] = self.stackedWidget.indexOf(self.rtfPage)
         self.pageIds['TeX'] = self.stackedWidget.indexOf(self.texPage)
@@ -57,6 +58,14 @@
         self.htmlTabsCheckBox.setChecked(\
             Preferences.getEditorExporter("HTML/UseTabs"))
         
+        # ODT
+        self.odtWysiwygCheckBox.setChecked(\
+            Preferences.getEditorExporter("ODT/WYSIWYG"))
+        self.odtStylesCheckBox.setChecked(\
+            Preferences.getEditorExporter("ODT/OnlyStylesUsed"))
+        self.odtTabsCheckBox.setChecked(\
+            Preferences.getEditorExporter("ODT/UseTabs"))
+        
         # PDF
         self.pdfMagnificationSlider.setValue(\
             Preferences.getEditorExporter("PDF/Magnification"))
@@ -107,6 +116,14 @@
         Preferences.setEditorExporter("HTML/UseTabs",
             self.htmlTabsCheckBox.isChecked())
         
+        # ODT
+        Preferences.setEditorExporter("ODT/WYSIWYG",
+            self.odtWysiwygCheckBox.isChecked())
+        Preferences.setEditorExporter("ODT/OnlyStylesUsed",
+            self.odtStylesCheckBox.isChecked())
+        Preferences.setEditorExporter("ODT/UseTabs",
+            self.odtTabsCheckBox.isChecked())
+        
         # PDF
         Preferences.setEditorExporter("PDF/Magnification", 
             self.pdfMagnificationSlider.value())
--- a/Preferences/ConfigurationPages/EditorExportersPage.ui	Mon Aug 30 12:30:29 2010 +0200
+++ b/Preferences/ConfigurationPages/EditorExportersPage.ui	Mon Aug 30 15:24:28 2010 +0200
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>EditorExportersPage</class>
- <widget class="QWidget" name="EditorExportersPage" >
-  <property name="geometry" >
+ <widget class="QWidget" name="EditorExportersPage">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,51 +10,51 @@
     <height>531</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string/>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout" >
+  <layout class="QVBoxLayout" name="verticalLayout">
    <item>
-    <widget class="QLabel" name="headerLabel" >
-     <property name="text" >
-      <string>&lt;b>Configure exporters&lt;/b></string>
+    <widget class="QLabel" name="headerLabel">
+     <property name="text">
+      <string>&lt;b&gt;Configure exporters&lt;/b&gt;</string>
      </property>
     </widget>
    </item>
    <item>
-    <widget class="Line" name="line1" >
-     <property name="frameShape" >
+    <widget class="Line" name="line1">
+     <property name="frameShape">
       <enum>QFrame::HLine</enum>
      </property>
-     <property name="frameShadow" >
+     <property name="frameShadow">
       <enum>QFrame::Sunken</enum>
      </property>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </widget>
    </item>
    <item>
-    <layout class="QHBoxLayout" >
+    <layout class="QHBoxLayout">
      <item>
-      <widget class="QLabel" name="TextLabel1_3" >
-       <property name="text" >
+      <widget class="QLabel" name="TextLabel1_3">
+       <property name="text">
         <string>Exporter Type:</string>
        </property>
-       <property name="buddy" >
+       <property name="buddy">
         <cstring></cstring>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QComboBox" name="exportersCombo" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+      <widget class="QComboBox" name="exportersCombo">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="toolTip" >
+       <property name="toolTip">
         <string>Select the exporter to be configured.</string>
        </property>
       </widget>
@@ -61,72 +62,72 @@
     </layout>
    </item>
    <item>
-    <widget class="QStackedWidget" name="stackedWidget" >
-     <property name="currentIndex" >
+    <widget class="QStackedWidget" name="stackedWidget">
+     <property name="currentIndex">
       <number>0</number>
      </property>
-     <widget class="QWidget" name="emptyPage" />
-     <widget class="QWidget" name="htmlPage" >
-      <layout class="QVBoxLayout" >
-       <property name="margin" >
+     <widget class="QWidget" name="emptyPage"/>
+     <widget class="QWidget" name="htmlPage">
+      <layout class="QVBoxLayout">
+       <property name="margin">
         <number>0</number>
        </property>
        <item>
-        <widget class="QCheckBox" name="htmlWysiwygCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="htmlWysiwygCheckBox">
+         <property name="toolTip">
           <string>Select to export in WYSIWYG mode</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use WYSIWYG mode</string>
          </property>
         </widget>
        </item>
        <item>
-        <widget class="QCheckBox" name="htmlFoldingCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="htmlFoldingCheckBox">
+         <property name="toolTip">
           <string>Select to include folding functionality</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Include folding functionality</string>
          </property>
         </widget>
        </item>
        <item>
-        <widget class="QCheckBox" name="htmlStylesCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="htmlStylesCheckBox">
+         <property name="toolTip">
           <string>Select to include only used styles</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Include only used styles</string>
          </property>
         </widget>
        </item>
        <item>
-        <widget class="QCheckBox" name="htmlTitleCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="htmlTitleCheckBox">
+         <property name="toolTip">
           <string>Select to use the full pathname as the document title</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use full pathname as document title</string>
          </property>
         </widget>
        </item>
        <item>
-        <widget class="QCheckBox" name="htmlTabsCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="htmlTabsCheckBox">
+         <property name="toolTip">
           <string>Select to use tabs in the generated file</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use tabs</string>
          </property>
         </widget>
        </item>
        <item>
         <spacer>
-         <property name="orientation" >
+         <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeHint" stdset="0" >
+         <property name="sizeHint" stdset="0">
           <size>
            <width>507</width>
            <height>21</height>
@@ -136,116 +137,163 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="pdfPage" >
-      <layout class="QGridLayout" name="gridLayout" >
-       <property name="margin" >
+     <widget class="QWidget" name="odtPage">
+      <layout class="QVBoxLayout" name="verticalLayout_2">
+       <item>
+        <widget class="QCheckBox" name="odtWysiwygCheckBox">
+         <property name="toolTip">
+          <string>Select to export in WYSIWYG mode</string>
+         </property>
+         <property name="text">
+          <string>Use WYSIWYG mode</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="odtStylesCheckBox">
+         <property name="toolTip">
+          <string>Select to include only used styles</string>
+         </property>
+         <property name="text">
+          <string>Include only used styles</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QCheckBox" name="odtTabsCheckBox">
+         <property name="toolTip">
+          <string>Select to use tabs in the generated file</string>
+         </property>
+         <property name="text">
+          <string>Use tabs</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="spacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>498</width>
+           <height>136</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="pdfPage">
+      <layout class="QGridLayout" name="gridLayout">
+       <property name="margin">
         <number>0</number>
        </property>
-       <item row="0" column="0" >
-        <widget class="QLabel" name="label" >
-         <property name="text" >
+       <item row="0" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
           <string>Magnification:</string>
          </property>
         </widget>
        </item>
-       <item row="0" column="1" >
-        <widget class="QSlider" name="pdfMagnificationSlider" >
-         <property name="toolTip" >
+       <item row="0" column="1">
+        <widget class="QSlider" name="pdfMagnificationSlider">
+         <property name="toolTip">
           <string>Select the magnification value to be added to the font sizes of the styles</string>
          </property>
-         <property name="maximum" >
+         <property name="maximum">
           <number>20</number>
          </property>
-         <property name="orientation" >
+         <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
         </widget>
        </item>
-       <item row="0" column="2" >
-        <widget class="QLCDNumber" name="pdfMagnificationLCD" >
-         <property name="toolTip" >
+       <item row="0" column="2">
+        <widget class="QLCDNumber" name="pdfMagnificationLCD">
+         <property name="toolTip">
           <string>Displays the selected magnification value</string>
          </property>
-         <property name="numDigits" >
+         <property name="numDigits">
           <number>2</number>
          </property>
-         <property name="segmentStyle" >
+         <property name="segmentStyle">
           <enum>QLCDNumber::Flat</enum>
          </property>
         </widget>
        </item>
-       <item row="1" column="0" >
-        <widget class="QLabel" name="label_2" >
-         <property name="text" >
+       <item row="1" column="0">
+        <widget class="QLabel" name="label_2">
+         <property name="text">
           <string>Font:</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="1" colspan="2" >
-        <widget class="QComboBox" name="pdfFontCombo" >
-         <property name="toolTip" >
+       <item row="1" column="1" colspan="2">
+        <widget class="QComboBox" name="pdfFontCombo">
+         <property name="toolTip">
           <string>Select the font from the list</string>
          </property>
         </widget>
        </item>
-       <item row="2" column="0" >
-        <widget class="QLabel" name="label_3" >
-         <property name="text" >
+       <item row="2" column="0">
+        <widget class="QLabel" name="label_3">
+         <property name="text">
           <string>Pagesize:</string>
          </property>
         </widget>
        </item>
-       <item row="2" column="1" colspan="2" >
-        <widget class="QComboBox" name="pdfPageSizeCombo" >
-         <property name="toolTip" >
+       <item row="2" column="1" colspan="2">
+        <widget class="QComboBox" name="pdfPageSizeCombo">
+         <property name="toolTip">
           <string>Select the page size from the list</string>
          </property>
         </widget>
        </item>
-       <item row="3" column="0" colspan="3" >
-        <layout class="QHBoxLayout" name="horizontalLayout" >
+       <item row="3" column="0" colspan="3">
+        <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
-          <widget class="QGroupBox" name="groupBox" >
-           <property name="title" >
+          <widget class="QGroupBox" name="groupBox">
+           <property name="title">
             <string>Margins</string>
            </property>
-           <layout class="QGridLayout" >
-            <item row="0" column="1" >
-             <widget class="QSpinBox" name="pdfMarginTopSpin" >
-              <property name="toolTip" >
-               <string>Select the top margin in points (72 pt == 1")</string>
+           <layout class="QGridLayout">
+            <item row="0" column="1">
+             <widget class="QSpinBox" name="pdfMarginTopSpin">
+              <property name="toolTip">
+               <string>Select the top margin in points (72 pt == 1&quot;)</string>
               </property>
-              <property name="maximum" >
+              <property name="maximum">
                <number>288</number>
               </property>
              </widget>
             </item>
-            <item row="1" column="0" >
-             <widget class="QSpinBox" name="pdfMarginLeftSpin" >
-              <property name="toolTip" >
-               <string>Select the left margin in points (72 pt == 1")</string>
+            <item row="1" column="0">
+             <widget class="QSpinBox" name="pdfMarginLeftSpin">
+              <property name="toolTip">
+               <string>Select the left margin in points (72 pt == 1&quot;)</string>
               </property>
-              <property name="maximum" >
+              <property name="maximum">
                <number>288</number>
               </property>
              </widget>
             </item>
-            <item row="1" column="2" >
-             <widget class="QSpinBox" name="pdfMarginRightSpin" >
-              <property name="toolTip" >
-               <string>Select the right margin in points (72 pt == 1")</string>
+            <item row="1" column="2">
+             <widget class="QSpinBox" name="pdfMarginRightSpin">
+              <property name="toolTip">
+               <string>Select the right margin in points (72 pt == 1&quot;)</string>
               </property>
-              <property name="maximum" >
+              <property name="maximum">
                <number>288</number>
               </property>
              </widget>
             </item>
-            <item row="2" column="1" >
-             <widget class="QSpinBox" name="pdfMarginBottomSpin" >
-              <property name="toolTip" >
-               <string>Select the bottom margin in points (72 pt == 1")</string>
+            <item row="2" column="1">
+             <widget class="QSpinBox" name="pdfMarginBottomSpin">
+              <property name="toolTip">
+               <string>Select the bottom margin in points (72 pt == 1&quot;)</string>
               </property>
-              <property name="maximum" >
+              <property name="maximum">
                <number>288</number>
               </property>
              </widget>
@@ -254,11 +302,11 @@
           </widget>
          </item>
          <item>
-          <spacer name="horizontalSpacer" >
-           <property name="orientation" >
+          <spacer name="horizontalSpacer">
+           <property name="orientation">
             <enum>Qt::Horizontal</enum>
            </property>
-           <property name="sizeHint" stdset="0" >
+           <property name="sizeHint" stdset="0">
             <size>
              <width>40</width>
              <height>20</height>
@@ -268,12 +316,12 @@
          </item>
         </layout>
        </item>
-       <item row="4" column="1" >
+       <item row="4" column="1">
         <spacer>
-         <property name="orientation" >
+         <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeHint" stdset="0" >
+         <property name="sizeHint" stdset="0">
           <size>
            <width>20</width>
            <height>21</height>
@@ -283,45 +331,45 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="rtfPage" >
-      <layout class="QVBoxLayout" >
-       <property name="margin" >
+     <widget class="QWidget" name="rtfPage">
+      <layout class="QVBoxLayout">
+       <property name="margin">
         <number>0</number>
        </property>
        <item>
-        <widget class="QCheckBox" name="rtfWysiwygCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="rtfWysiwygCheckBox">
+         <property name="toolTip">
           <string>Select to export in WYSIWYG mode</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use WYSIWYG mode</string>
          </property>
         </widget>
        </item>
        <item>
-        <layout class="QHBoxLayout" >
+        <layout class="QHBoxLayout">
          <item>
-          <widget class="QPushButton" name="rtfFontButton" >
-           <property name="toolTip" >
+          <widget class="QPushButton" name="rtfFontButton">
+           <property name="toolTip">
             <string>Press to select the font for the RTF export</string>
            </property>
-           <property name="text" >
+           <property name="text">
             <string>Select Font</string>
            </property>
           </widget>
          </item>
          <item>
-          <widget class="QLineEdit" name="rtfFontSample" >
-           <property name="focusPolicy" >
+          <widget class="QLineEdit" name="rtfFontSample">
+           <property name="focusPolicy">
             <enum>Qt::NoFocus</enum>
            </property>
-           <property name="text" >
+           <property name="text">
             <string>Font for RTF export</string>
            </property>
-           <property name="alignment" >
+           <property name="alignment">
             <set>Qt::AlignHCenter</set>
            </property>
-           <property name="readOnly" >
+           <property name="readOnly">
             <bool>true</bool>
            </property>
           </widget>
@@ -329,21 +377,21 @@
         </layout>
        </item>
        <item>
-        <widget class="QCheckBox" name="rtfTabsCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="rtfTabsCheckBox">
+         <property name="toolTip">
           <string>Select to use tabs in the generated file</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use tabs</string>
          </property>
         </widget>
        </item>
        <item>
         <spacer>
-         <property name="orientation" >
+         <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeHint" stdset="0" >
+         <property name="sizeHint" stdset="0">
           <size>
            <width>451</width>
            <height>21</height>
@@ -353,37 +401,37 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="texPage" >
-      <layout class="QVBoxLayout" >
-       <property name="margin" >
+     <widget class="QWidget" name="texPage">
+      <layout class="QVBoxLayout">
+       <property name="margin">
         <number>0</number>
        </property>
        <item>
-        <widget class="QCheckBox" name="texStylesCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="texStylesCheckBox">
+         <property name="toolTip">
           <string>Select to include only used styles</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Include only used styles</string>
          </property>
         </widget>
        </item>
        <item>
-        <widget class="QCheckBox" name="texTitleCheckBox" >
-         <property name="toolTip" >
+        <widget class="QCheckBox" name="texTitleCheckBox">
+         <property name="toolTip">
           <string>Select to use the full pathname as the document title</string>
          </property>
-         <property name="text" >
+         <property name="text">
           <string>Use full pathname as document title</string>
          </property>
         </widget>
        </item>
        <item>
         <spacer>
-         <property name="orientation" >
+         <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
-         <property name="sizeHint" stdset="0" >
+         <property name="sizeHint" stdset="0">
           <size>
            <width>507</width>
            <height>21</height>
@@ -397,10 +445,10 @@
    </item>
    <item>
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" stdset="0" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>519</width>
        <height>21</height>
@@ -417,6 +465,9 @@
   <tabstop>htmlStylesCheckBox</tabstop>
   <tabstop>htmlTitleCheckBox</tabstop>
   <tabstop>htmlTabsCheckBox</tabstop>
+  <tabstop>odtWysiwygCheckBox</tabstop>
+  <tabstop>odtStylesCheckBox</tabstop>
+  <tabstop>odtTabsCheckBox</tabstop>
   <tabstop>pdfMagnificationSlider</tabstop>
   <tabstop>pdfFontCombo</tabstop>
   <tabstop>pdfPageSizeCombo</tabstop>
@@ -438,11 +489,11 @@
    <receiver>rtfFontButton</receiver>
    <slot>setDisabled(bool)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>57</x>
      <y>83</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>59</x>
      <y>117</y>
     </hint>
@@ -454,11 +505,11 @@
    <receiver>rtfFontSample</receiver>
    <slot>setDisabled(bool)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>216</x>
      <y>86</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>217</x>
      <y>115</y>
     </hint>
@@ -470,11 +521,11 @@
    <receiver>pdfMagnificationLCD</receiver>
    <slot>display(int)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>174</x>
      <y>86</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>331</x>
      <y>91</y>
     </hint>
@@ -486,11 +537,11 @@
    <receiver>pdfMagnificationLCD</receiver>
    <slot>display(int)</slot>
    <hints>
-    <hint type="sourcelabel" >
+    <hint type="sourcelabel">
      <x>140</x>
      <y>87</y>
     </hint>
-    <hint type="destinationlabel" >
+    <hint type="destinationlabel">
      <x>332</x>
      <y>96</y>
     </hint>
--- a/Preferences/__init__.py	Mon Aug 30 12:30:29 2010 +0200
+++ b/Preferences/__init__.py	Mon Aug 30 15:24:28 2010 +0200
@@ -449,6 +449,10 @@
         
         "TeX/OnlyStylesUsed"    : False, 
         "TeX/FullPathAsTitle"   : False, 
+        
+        "ODT/WYSIWYG"           : True, 
+        "ODT/OnlyStylesUsed"    : False, 
+        "ODT/UseTabs"           : False, 
     }
     
     # defaults for the printer settings
@@ -1478,7 +1482,8 @@
         return f
     elif key in ["HTML/WYSIWYG", "HTML/Folding", "HTML/OnlyStylesUsed", 
                  "HTML/FullPathAsTitle", "HTML/UseTabs", "RTF/WYSIWYG", 
-                 "RTF/UseTabs", "TeX/OnlyStylesUsed", "TeX/FullPathAsTitle"]:
+                 "RTF/UseTabs", "TeX/OnlyStylesUsed", "TeX/FullPathAsTitle", 
+                 "ODT/WYSIWYG", "ODT/OnlyStylesUsed", "ODT/UseTabs"]:
         return toBool(prefClass.settings.value("Editor/Exporters/" + key,
             prefClass.editorExporterDefaults[key]))
     elif key in ["PDF/Magnification", "PDF/MarginLeft", "PDF/MarginRight", 
--- a/QScintilla/Exporters/ExporterHTML.py	Mon Aug 30 12:30:29 2010 +0200
+++ b/QScintilla/Exporters/ExporterHTML.py	Mon Aug 30 15:24:28 2010 +0200
@@ -21,6 +21,326 @@
 import Preferences
 import Utilities
 
+class HTMLGenerator(object):
+    """
+    Class implementing an HTML generator for exporting source code.
+    """
+    def __init__(self, editor):
+        """
+        Constructor
+        
+        @param editor reference to the editor object (QScintilla.Editor.Editor)
+        """
+        self.editor = editor
+    
+    def generate(self, tabSize = 4, useTabs = False, wysiwyg = True, folding = False, 
+                 onlyStylesUsed = False, titleFullPath = False):
+        """
+        Public method to generate HTML for the source editor.
+        
+        @keyparam tabSize size of tabs (integer)
+        @keyparam useTabs flag indicating the use of tab characters (boolean)
+        @keyparam wysiwyg flag indicating colorization (boolean)
+        @keyparam folding flag indicating usage of fold markers
+        @keyparam onlyStylesUsed flag indicating to include only style definitions
+            for styles used in the source (boolean)
+        @keyparam titleFullPath flag indicating to include the full file path
+            in the title tag (boolean)
+        @return generated HTML text (string)
+        """
+        self.editor.recolor(0, -1)
+        
+        lengthDoc = self.editor.length()
+        styleIsUsed = {}
+        if onlyStylesUsed:
+            for index in range(QsciScintilla.STYLE_MAX + 1):
+                styleIsUsed[index] = False
+            # check the used styles
+            pos = 0
+            while pos < lengthDoc:
+                styleIsUsed[self.editor.styleAt(pos) & 0x7F] = True
+                pos += 1
+        else:
+            for index in range(QsciScintilla.STYLE_MAX + 1):
+                styleIsUsed[index] = True
+        styleIsUsed[QsciScintilla.STYLE_DEFAULT] = True
+        
+        html = '''<!DOCTYPE html PUBLIC "-//W3C//DTD''' \
+            ''' XHTML 1.0 Transitional//EN"\n''' \
+            ''' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n''' \
+            '''<html xmlns="http://www.w3.org/1999/xhtml">\n''' \
+            '''<head>\n'''
+        if titleFullPath:
+            html += '''<title>{0}</title>\n'''.format(self.editor.getFileName())
+        else:
+            html += '''<title>{0}</title>\n'''.format(
+                os.path.basename(self.editor.getFileName()))
+        html += '''<meta name="Generator" content="eric5" />\n''' \
+            '''<meta http-equiv="Content-Type" ''' \
+            '''content="text/html; charset=utf-8" />\n'''
+        if folding:
+            html += '''<script language="JavaScript" type="text/javascript">\n''' \
+                    '''<!--\n''' \
+                    '''function symbol(id, sym) {\n''' \
+                    '''  if (id.textContent == undefined) {\n''' \
+                    '''    id.innerText = sym;\n''' \
+                    '''  } else {\n''' \
+                    '''    id.textContent = sym;\n''' \
+                    '''  }\n''' \
+                    '''}\n''' \
+                    '''function toggle(id) {\n''' \
+                    '''  var thislayer = document.getElementById('ln' + id);\n''' \
+                    '''  id -= 1;\n''' \
+                    '''  var togline = document.getElementById('hd' + id);\n''' \
+                    '''  var togsym = document.getElementById('bt' + id);\n''' \
+                    '''  if (thislayer.style.display == 'none') {\n''' \
+                    '''    thislayer.style.display = 'block';\n''' \
+                    '''    togline.style.textDecoration = 'none';\n''' \
+                    '''    symbol(togsym, '- ');\n''' \
+                    '''  } else {\n''' \
+                    '''    thislayer.style.display = 'none';\n''' \
+                    '''    togline.style.textDecoration = 'underline';\n''' \
+                    '''    symbol(togsym, '+ ');\n''' \
+                    '''  }\n''' \
+                    '''}\n''' \
+                    '''//-->\n''' \
+                    '''</script>\n'''
+        
+        lex = self.editor.getLexer()
+        if lex:
+            bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT).name()
+        else:
+            bgColour = self.editor.paper().name()
+        
+        html += '''<style type="text/css">\n'''
+        if lex:
+            istyle = 0
+            while istyle <= QsciScintilla.STYLE_MAX:
+                if (istyle <= QsciScintilla.STYLE_DEFAULT or \
+                    istyle > QsciScintilla.STYLE_LASTPREDEFINED) and \
+                   styleIsUsed[istyle]:
+                    if lex.description(istyle) or \
+                       istyle == QsciScintilla.STYLE_DEFAULT:
+                        font = lex.font(istyle)
+                        colour = lex.color(istyle)
+                        paper = lex.paper(istyle)
+                        if istyle == QsciScintilla.STYLE_DEFAULT:
+                            html += '''span {\n'''
+                        else:
+                            html += '''.S{0:d} {{\n'''.format(istyle)
+                        if font.italic():
+                            html += '''    font-style: italic;\n'''
+                        if font.bold():
+                            html += '''    font-weight: bold;\n'''
+                        if wysiwyg:
+                            html += '''    font-family: '{0}';\n'''.format(
+                                    font.family())
+                        html += '''    color: {0};\n'''.format(colour.name())
+                        if istyle != QsciScintilla.STYLE_DEFAULT and \
+                           bgColour != paper.name():
+                            html += '''    background: {0};\n'''.format(
+                                    paper.name())
+                            html += '''    text-decoration: inherit;\n'''
+                        if wysiwyg:
+                            html += '''    font-size: {0:d}pt;\n'''.format(
+                                    QFontInfo(font).pointSize())
+                        html += '''}\n'''
+                    else:
+                        styleIsUsed[istyle] = False
+                istyle += 1
+        else:
+            colour = self.editor.color()
+            paper = self.editor.paper()
+            font = Preferences.getEditorOtherFonts("DefaultFont")
+            html += '''.S0 {\n'''
+            if font.italic():
+                html += '''    font-style: italic;\n'''
+            if font.bold():
+                html += '''    font-weight: bold;\n'''
+            if wysiwyg:
+                html += '''    font-family: '{0}';\n'''.format(font.family())
+            html += '''    color: {0};\n'''.format(colour.name())
+            if bgColour != paper.name():
+                html += '''    background: {0};\n'''.format(paper.name())
+                html += '''    text-decoration: inherit;\n'''
+            if wysiwyg:
+                html += '''    font-size: {0:d}pt;\n'''.format(
+                        QFontInfo(font).pointSize())
+            html += '''}\n'''
+        html += '''</style>\n'''
+        html += '''</head>\n'''
+        
+        html += '''<body bgcolor="{0}">\n'''.format(bgColour)
+        line = self.editor.lineAt(0)
+        level = self.editor.foldLevelAt(line) - QsciScintilla.SC_FOLDLEVELBASE
+        levelStack = [level]
+        styleCurrent = self.editor.styleAt(0)
+        inStyleSpan = False
+        inFoldSpan = False
+        # Global span for default attributes
+        if wysiwyg:
+            html += '''<span>'''
+        else:
+            html += '''<pre>'''
+        
+        if folding:
+            if self.editor.foldFlagsAt(line) & \
+               QsciScintilla.SC_FOLDLEVELHEADERFLAG:
+                html += '''<span id="hd{0:d}" onclick="toggle('{1:d}')">'''\
+                        .format(line, line + 1)
+                html += '''<span id="bt{0:d}">- </span>'''.format(line)
+                inFoldSpan = True
+            else:
+                html += '''&nbsp; '''
+        
+        if styleIsUsed[styleCurrent]:
+            html += '''<span class="S{0:0d}">'''.format(styleCurrent)
+            inStyleSpan = True
+        
+        column = 0
+        pos = 0
+        utf8 = self.editor.isUtf8()
+        utf8Ch = b""
+        utf8Len = 0
+        
+        while pos < lengthDoc:
+            ch = self.editor.byteAt(pos)
+            style = self.editor.styleAt(pos)
+            if style != styleCurrent:
+                if inStyleSpan:
+                    html += '''</span>'''
+                    inStyleSpan = False
+                if ch not in [b'\r', b'\n']: # no need of a span for the EOL
+                    if styleIsUsed[style]:
+                        html += '''<span class="S{0:d}">'''.format(style)
+                        inStyleSpan = True
+                    styleCurrent = style
+            
+            if ch == b' ':
+                if wysiwyg:
+                    prevCh = b''
+                    if column == 0: 
+                        # at start of line, must put a &nbsp; 
+                        # because regular space will be collapsed
+                        prevCh = b' '
+                    while pos < lengthDoc and self.editor.byteAt(pos) == b' ':
+                        if prevCh != b' ':
+                            html += ' '
+                        else:
+                            html += '''&nbsp;'''
+                        prevCh = self.editor.byteAt(pos)
+                        pos += 1
+                        column += 1
+                    pos -= 1 
+                    # the last incrementation will be done by the outer loop
+                else:
+                    html += ' '
+                    column += 1
+            elif ch == b'\t':
+                ts = tabSize - (column % tabSize)
+                if wysiwyg:
+                    html += '''&nbsp;''' * ts
+                    column += ts
+                else:
+                    if tabs:
+                        html += '\t'
+                        column += 1
+                    else:
+                        html += ' ' * ts
+                        column += ts
+            elif ch in [b'\r', b'\n']:
+                if inStyleSpan:
+                    html += '''</span>'''
+                    inStyleSpan = False
+                if inFoldSpan:
+                    html += '''</span>'''
+                    inFoldSpan = False
+                if ch == b'\r' and self.editor.byteAt(pos + 1) == b'\n':
+                    pos += 1 # CR+LF line ending, skip the "extra" EOL char
+                column = 0
+                if wysiwyg:
+                    html += '''<br />'''
+                
+                styleCurrent = self.editor.styleAt(pos + 1)
+                if folding:
+                    line = self.editor.lineAt(pos + 1)
+                    newLevel = self.editor.foldLevelAt(line)
+                    
+                    if newLevel < level:
+                        while levelStack[-1] > newLevel:
+                            html += '''</span>'''
+                            levelStack.pop()
+                    html += '\n' # here to get clean code
+                    if newLevel > level:
+                        html += '''<span id="ln{0:d}">'''.format(line)
+                        levelStack.append(newLevel)
+                    if self.editor.foldFlagsAt(line) & \
+                       QsciScintilla.SC_FOLDLEVELHEADERFLAG:
+                        html += \
+                            '''<span id="hd{0:d}" onclick="toggle('{1:d}')">'''\
+                            .format(line, line + 1)
+                        html += '''<span id="bt{0:d}">- </span>'''.format(line)
+                        inFoldSpan = True
+                    else:
+                        html += '''&nbsp; '''
+                    level = newLevel
+                else:
+                    html += '\n'
+                
+                if styleIsUsed[styleCurrent] and \
+                   self.editor.byteAt(pos + 1) not in [b'\r', b'\n']:
+                    # We know it's the correct next style,
+                    # but no (empty) span for an empty line
+                    html += '''<span class="S{0:0d}">'''.format(styleCurrent)
+                    inStyleSpan = True
+            else:
+                if ch == b'<':
+                    html += '''&lt;'''
+                elif ch == b'>':
+                    html += '''&gt'''
+                elif ch == b'&':
+                    html += '''&amp;'''
+                else:
+                    if ord(ch) > 127 and utf8:
+                        utf8Ch += ch
+                        if utf8Len == 0:
+                            if (utf8Ch[0] & 0xF0) == 0xF0:
+                                utf8Len = 4
+                            elif (utf8Ch[0] & 0xE0) == 0xE0:
+                                utf8Len = 3
+                            elif (utf8Ch[0] & 0xC0) == 0xC0:
+                                utf8Len = 2
+                            column -= 1 # will be incremented again later
+                        elif len(utf8Ch) == utf8Len:
+                            ch = utf8Ch.decode('utf8')
+                            html += Utilities.html_encode(ch)
+                            utf8Ch = b""
+                            utf8Len = 0
+                        else:
+                            column -= 1 # will be incremented again later
+                    else:
+                        html += ch.decode()
+                column += 1
+            
+            pos += 1
+        
+        if inStyleSpan:
+            html += '''</span>'''
+        
+        if folding:
+            while levelStack:
+                html += '''</span>'''
+                levelStack.pop()
+        
+        if wysiwyg:
+            html += '''</span>'''
+        else:
+            html += '''</pre>'''
+        
+        html += '''</body>\n</html>\n'''
+        
+        return html
+
 class ExporterHTML(ExporterBase):
     """
     Class implementing an exporter for HTML.
@@ -46,8 +366,6 @@
             QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
             QApplication.processEvents()
             
-            self.editor.recolor(0, -1)
-            
             tabSize = Preferences.getEditor("TabWidth")
             if tabSize == 0:
                 tabSize = 4
@@ -57,300 +375,19 @@
             titleFullPath = Preferences.getEditorExporter("HTML/FullPathAsTitle")
             tabs = Preferences.getEditorExporter("HTML/UseTabs")
             
-            lengthDoc = self.editor.length()
-            styleIsUsed = {}
-            if onlyStylesUsed:
-                for index in range(QsciScintilla.STYLE_MAX + 1):
-                    styleIsUsed[index] = False
-                # check the used styles
-                pos = 0
-                while pos < lengthDoc:
-                    styleIsUsed[self.editor.styleAt(pos) & 0x7F] = True
-                    pos += 1
-            else:
-                for index in range(QsciScintilla.STYLE_MAX + 1):
-                    styleIsUsed[index] = True
-            styleIsUsed[QsciScintilla.STYLE_DEFAULT] = True
+            generator = HTMLGenerator(self.editor)
+            html = generator.generate(
+                tabSize = tabSize, 
+                useTabs = tabs, 
+                wysiwyg = wysiwyg, 
+                folding = folding, 
+                onlyStylesUsed = onlyStylesUsed, 
+                titleFullPath = titleFullPath
+            )
             
             try:
                 f = open(filename, "w", encoding = "utf-8")
-                
-                f.write(
-                    '''<!DOCTYPE html PUBLIC "-//W3C//DTD'''
-                    ''' XHTML 1.0 Transitional//EN"\n''')
-                f.write(
-                    ''' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n''')
-                f.write('''<html xmlns="http://www.w3.org/1999/xhtml">\n''')
-                f.write('''<head>\n''')
-                if titleFullPath:
-                    f.write('''<title>{0}</title>\n'''.format(self.editor.getFileName()))
-                else:
-                    f.write('''<title>{0}</title>\n'''.format(
-                        os.path.basename(self.editor.getFileName())))
-                f.write('''<meta name="Generator" content="eric5" />\n''')
-                f.write('''<meta http-equiv="Content-Type" '''
-                        '''content="text/html; charset=utf-8" />\n''')
-                if folding:
-                    f.write('''<script language="JavaScript" type="text/javascript">\n'''
-                            '''<!--\n'''
-                            '''function symbol(id, sym) {\n'''
-                            '''  if (id.textContent == undefined) {\n'''
-                            '''    id.innerText = sym;\n'''
-                            '''  } else {\n'''
-                            '''    id.textContent = sym;\n'''
-                            '''  }\n'''
-                            '''}\n'''
-                            '''function toggle(id) {\n'''
-                            '''  var thislayer = document.getElementById('ln' + id);\n'''
-                            '''  id -= 1;\n'''
-                            '''  var togline = document.getElementById('hd' + id);\n'''
-                            '''  var togsym = document.getElementById('bt' + id);\n'''
-                            '''  if (thislayer.style.display == 'none') {\n'''
-                            '''    thislayer.style.display = 'block';\n'''
-                            '''    togline.style.textDecoration = 'none';\n'''
-                            '''    symbol(togsym, '- ');\n'''
-                            '''  } else {\n'''
-                            '''    thislayer.style.display = 'none';\n'''
-                            '''    togline.style.textDecoration = 'underline';\n'''
-                            '''    symbol(togsym, '+ ');\n'''
-                            '''  }\n'''
-                            '''}\n'''
-                            '''//-->\n'''
-                            '''</script>\n'''
-                    )
-                
-                lex = self.editor.getLexer()
-                if lex:
-                    bgColour = lex.paper(QsciScintilla.STYLE_DEFAULT).name()
-                else:
-                    bgColour = self.editor.paper().name()
-                
-                f.write('''<style type="text/css">\n''')
-                if lex:
-                    istyle = 0
-                    while istyle <= QsciScintilla.STYLE_MAX:
-                        if (istyle <= QsciScintilla.STYLE_DEFAULT or \
-                            istyle > QsciScintilla.STYLE_LASTPREDEFINED) and \
-                           styleIsUsed[istyle]:
-                            if lex.description(istyle) or \
-                               istyle == QsciScintilla.STYLE_DEFAULT:
-                                font = lex.font(istyle)
-                                colour = lex.color(istyle)
-                                paper = lex.paper(istyle)
-                                if istyle == QsciScintilla.STYLE_DEFAULT:
-                                    f.write('''span {\n''')
-                                else:
-                                    f.write('''.S{0:d} {\n'''.format(istyle))
-                                if font.italic():
-                                    f.write('''    font-style: italic;\n''')
-                                if font.bold():
-                                    f.write('''    font-weight: bold;\n''')
-                                if wysiwyg:
-                                    f.write('''    font-family: '{0}';\n'''.format(
-                                            font.family()))
-                                f.write('''    color: {0};\n'''.format(colour.name()))
-                                if istyle != QsciScintilla.STYLE_DEFAULT and \
-                                   bgColour != paper.name():
-                                    f.write('''    background: {0};\n'''.format(
-                                            paper.name()))
-                                    f.write('''    text-decoration: inherit;\n''')
-                                if wysiwyg:
-                                    f.write('''    font-size: {0:d}pt;\n'''.format(
-                                            QFontInfo(font).pointSize()))
-                                f.write('''}\n''')
-                            else:
-                                styleIsUsed[istyle] = False
-                        istyle += 1
-                else:
-                    colour = self.editor.color()
-                    paper = self.editor.paper()
-                    font = Preferences.getEditorOtherFonts("DefaultFont")
-                    f.write('''.S0 {\n''')
-                    if font.italic():
-                        f.write('''    font-style: italic;\n''')
-                    if font.bold():
-                        f.write('''    font-weight: bold;\n''')
-                    if wysiwyg:
-                        f.write('''    font-family: '{0}';\n'''.format(font.family()))
-                    f.write('''    color: {0};\n'''.format(colour.name()))
-                    if bgColour != paper.name():
-                        f.write('''    background: {0};\n'''.format(paper.name()))
-                        f.write('''    text-decoration: inherit;\n''')
-                    if wysiwyg:
-                        f.write('''    font-size: {0:d}pt;\n'''.format(
-                                QFontInfo(font).pointSize()))
-                    f.write('''}\n''')
-                f.write('''</style>\n''')
-                f.write('''</head>\n''')
-                
-                f.write('''<body bgcolor="{0}">\n'''.format(bgColour))
-                line = self.editor.lineAt(0)
-                level = self.editor.foldLevelAt(line) - QsciScintilla.SC_FOLDLEVELBASE
-                levelStack = [level]
-                styleCurrent = self.editor.styleAt(0)
-                inStyleSpan = False
-                inFoldSpan = False
-                # Global span for default attributes
-                if wysiwyg:
-                    f.write('''<span>''')
-                else:
-                    f.write('''<pre>''')
-                
-                if folding:
-                    if self.editor.foldFlagsAt(line) & \
-                       QsciScintilla.SC_FOLDLEVELHEADERFLAG:
-                        f.write('''<span id="hd{0:d}" onclick="toggle('{1:d}')">'''\
-                                .format(line, line + 1))
-                        f.write('''<span id="bt{0:d}">- </span>'''.format(line))
-                        inFoldSpan = True
-                    else:
-                        f.write('''&nbsp; ''')
-                
-                if styleIsUsed[styleCurrent]:
-                    f.write('''<span class="S{0:0d}">'''.format(styleCurrent))
-                    inStyleSpan = True
-                
-                column = 0
-                pos = 0
-                utf8 = self.editor.isUtf8()
-                utf8Ch = b""
-                utf8Len = 0
-                
-                while pos < lengthDoc:
-                    ch = self.editor.byteAt(pos)
-                    style = self.editor.styleAt(pos)
-                    if style != styleCurrent:
-                        if inStyleSpan:
-                            f.write('''</span>''')
-                            inStyleSpan = False
-                        if ch not in [b'\r', b'\n']: # no need of a span for the EOL
-                            if styleIsUsed[style]:
-                                f.write('''<span class="S{0:d}">'''.format(style))
-                                inStyleSpan = True
-                            styleCurrent = style
-                    
-                    if ch == b' ':
-                        if wysiwyg:
-                            prevCh = b''
-                            if column == 0: 
-                                # at start of line, must put a &nbsp; 
-                                # because regular space will be collapsed
-                                prevCh = b' '
-                            while pos < lengthDoc and self.editor.byteAt(pos) == b' ':
-                                if prevCh != b' ':
-                                    f.write(' ')
-                                else:
-                                    f.write('''&nbsp;''')
-                                prevCh = self.editor.byteAt(pos)
-                                pos += 1
-                                column += 1
-                            pos -= 1 
-                            # the last incrementation will be done by the outer loop
-                        else:
-                            f.write(' ')
-                            column += 1
-                    elif ch == b'\t':
-                        ts = tabSize - (column % tabSize)
-                        if wysiwyg:
-                            f.write('''&nbsp;''' * ts)
-                            column += ts
-                        else:
-                            if tabs:
-                                f.write('\t')
-                                column += 1
-                            else:
-                                f.write(' ' * ts)
-                                column += ts
-                    elif ch in [b'\r', b'\n']:
-                        if inStyleSpan:
-                            f.write('''</span>''')
-                            inStyleSpan = False
-                        if inFoldSpan:
-                            f.write('''</span>''')
-                            inFoldSpan = False
-                        if ch == b'\r' and self.editor.byteAt(pos + 1) == b'\n':
-                            pos += 1 # CR+LF line ending, skip the "extra" EOL char
-                        column = 0
-                        if wysiwyg:
-                            f.write('''<br />''')
-                        
-                        styleCurrent = self.editor.styleAt(pos + 1)
-                        if folding:
-                            line = self.editor.lineAt(pos + 1)
-                            newLevel = self.editor.foldLevelAt(line)
-                            
-                            if newLevel < level:
-                                while levelStack[-1] > newLevel:
-                                    f.write('''</span>''')
-                                    levelStack.pop()
-                            f.write('\n') # here to get clean code
-                            if newLevel > level:
-                                f.write('''<span id="ln{0:d}">'''.format(line))
-                                levelStack.append(newLevel)
-                            if self.editor.foldFlagsAt(line) & \
-                               QsciScintilla.SC_FOLDLEVELHEADERFLAG:
-                                f.write(
-                                    '''<span id="hd{0:d}" onclick="toggle('{1:d}')">'''\
-                                    .format(line, line + 1))
-                                f.write('''<span id="bt{0:d}">- </span>'''.format(line))
-                                inFoldSpan = True
-                            else:
-                                f.write('''&nbsp; ''')
-                            level = newLevel
-                        else:
-                            f.write('\n')
-                        
-                        if styleIsUsed[styleCurrent] and \
-                           self.editor.byteAt(pos + 1) not in [b'\r', b'\n']:
-                            # We know it's the correct next style,
-                            # but no (empty) span for an empty line
-                            f.write('''<span class="S{0:0d}">'''.format(styleCurrent))
-                            inStyleSpan = True
-                    else:
-                        if ch == b'<':
-                            f.write('''&lt;''')
-                        elif ch == b'>':
-                            f.write('''&gt''')
-                        elif ch == b'&':
-                            f.write('''&amp;''')
-                        else:
-                            if ord(ch) > 127 and utf8:
-                                utf8Ch += ch
-                                if utf8Len == 0:
-                                    if (utf8Ch[0] & 0xF0) == 0xF0:
-                                        utf8Len = 4
-                                    elif (utf8Ch[0] & 0xE0) == 0xE0:
-                                        utf8Len = 3
-                                    elif (utf8Ch[0] & 0xC0) == 0xC0:
-                                        utf8Len = 2
-                                    column -= 1 # will be incremented again later
-                                elif len(utf8Ch) == utf8Len:
-                                    ch = utf8Ch.decode('utf8')
-                                    f.write(Utilities.html_encode(ch))
-                                    utf8Ch = b""
-                                    utf8Len = 0
-                                else:
-                                    column -= 1 # will be incremented again later
-                            else:
-                                f.write(ch.decode())
-                        column += 1
-                    
-                    pos += 1
-                
-                if inStyleSpan:
-                    f.write('''</span>''')
-                
-                if folding:
-                    while levelStack:
-                        f.write('''</span>''')
-                        levelStack.pop()
-                
-                if wysiwyg:
-                    f.write('''</span>''')
-                else:
-                    f.write('''</pre>''')
-                
-                f.write('''</body>\n</html>\n''')
+                f.write(html)
                 f.close()
             except IOError as err:
                 QApplication.restoreOverrideCursor()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QScintilla/Exporters/ExporterODT.py	Mon Aug 30 15:24:28 2010 +0200
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing an exporter for ODT.
+"""
+
+from PyQt4.QtCore import Qt
+from PyQt4.QtGui import QApplication, QCursor, QTextDocument, QTextDocumentWriter, \
+    QMessageBox
+
+from .ExporterBase import ExporterBase
+from .ExporterHTML import HTMLGenerator
+
+import Preferences
+
+class ExporterODT(ExporterBase):
+    """
+    Class implementing an exporter for ODT.
+    """
+    def __init__(self, editor, parent = None):
+        """
+        Constructor
+        
+        @param editor reference to the editor object (QScintilla.Editor.Editor)
+        @param parent parent object of the exporter (QObject)
+        """
+        ExporterBase.__init__(self, editor, parent)
+    
+    def exportSource(self):
+        """
+        Public method performing the export.
+        """
+        filename = self._getFileName(self.trUtf8("ODT Files (*.odt)"))
+        if not filename:
+            return
+        
+        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
+        QApplication.processEvents()
+        
+        tabSize = Preferences.getEditor("TabWidth")
+        if tabSize == 0:
+            tabSize = 4
+        wysiwyg = Preferences.getEditorExporter("ODT/WYSIWYG")
+        onlyStylesUsed = Preferences.getEditorExporter("ODT/OnlyStylesUsed")
+        tabs = Preferences.getEditorExporter("ODT/UseTabs")
+        
+        # generate HTML of the source
+        generator = HTMLGenerator(self.editor)
+        html = generator.generate(
+            tabSize = tabSize, 
+            useTabs = tabs, 
+            wysiwyg = wysiwyg, 
+            folding = False, 
+            onlyStylesUsed = onlyStylesUsed, 
+            titleFullPath = False
+        )
+        
+        # convert HTML to ODT
+        doc = QTextDocument()
+        doc.setHtml(html)
+        writer = QTextDocumentWriter(filename)
+        ok = writer.write(doc)
+        QApplication.restoreOverrideCursor()
+        if not ok:
+            QMessageBox.critical(self.editor,
+                self.trUtf8("Export source"),
+                self.trUtf8(\
+                    """<p>The source could not be exported to <b>{0}</b>.</p>""")\
+                    .format(filename),
+                QMessageBox.StandardButtons(\
+                    QMessageBox.Ok))
--- a/QScintilla/Exporters/__init__.py	Mon Aug 30 12:30:29 2010 +0200
+++ b/QScintilla/Exporters/__init__.py	Mon Aug 30 15:24:28 2010 +0200
@@ -22,6 +22,7 @@
         "RTF"  : QApplication.translate('Exporters', "RTF"), 
         "PDF"  : QApplication.translate('Exporters', "PDF"), 
         "TeX"  : QApplication.translate('Exporters', "TeX"), 
+        "ODT"  : QApplication.translate('Exporters', "ODT"), 
     }
     
     return supportedFormats
@@ -47,5 +48,8 @@
         elif format == "TeX":
             from .ExporterTEX import ExporterTEX
             return ExporterTEX(editor)
+        elif format == "ODT":
+            from .ExporterODT import ExporterODT
+            return ExporterODT(editor)
     except ImportError:
         return None
--- a/changelog	Mon Aug 30 12:30:29 2010 +0200
+++ b/changelog	Mon Aug 30 15:24:28 2010 +0200
@@ -8,7 +8,8 @@
 - added code to show hidden files in the various browsers
 - added an editor action to join the current line with the next one
 - added code to cope with Linux distributor's usage of KDE wrapper dialogs
-  for the Qt file dialogs
+  for the Qt file dialogs
+- added a source code exporter for the Open Document Text (ODT) format
 
 Version 5.1-snapshot-20100718:
 - bug fixes
--- a/eric5.e4p	Mon Aug 30 12:30:29 2010 +0200
+++ b/eric5.e4p	Mon Aug 30 15:24:28 2010 +0200
@@ -814,6 +814,7 @@
     <Source>Helpviewer/UserAgent/UserAgentMenu.py</Source>
     <Source>Helpviewer/UserAgent/UserAgentDefaults.py</Source>
     <Source>E5Gui/E5FileDialog.py</Source>
+    <Source>QScintilla/Exporters/ExporterODT.py</Source>
   </Sources>
   <Forms>
     <Form>PyUnit/UnittestDialog.ui</Form>

eric ide

mercurial