[MERGE] sfd-adoons: base_synchro, openoffice-plugin
authorPanos Christeas <xrg@linux.gr>
Sat, 18 Sep 2010 07:24:46 +0000 (12:54 +0530)
committerHarry (OpenERP) <hmo@tinyerp.com>
Sat, 18 Sep 2010 07:24:46 +0000 (12:54 +0530)
bzr revid: hmo@tinyerp.com-20100918072446-gc1slo8lz82b2qli

63 files changed:
addons/base_report_designer/__init__.py
addons/base_report_designer/__openerp__.py
addons/base_report_designer/base_report_data.xml [deleted file]
addons/base_report_designer/base_report_designer.py
addons/base_report_designer/base_report_designer_installer.xml [new file with mode: 0644]
addons/base_report_designer/base_report_designer_wizard.xml [deleted file]
addons/base_report_designer/installer.py [new file with mode: 0644]
addons/base_report_designer/openerp_sxw2rml/__init__.py [new file with mode: 0644]
addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl [new file with mode: 0644]
addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl [new file with mode: 0644]
addons/base_report_designer/openerp_sxw2rml/office.dtd [new file with mode: 0644]
addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer.zip [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/README [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/Makefile [new file with mode: 0755]
addons/base_report_designer/plugin/openerp_report_designer/bin/OOo_run.sh [new file with mode: 0755]
addons/base_report_designer/plugin/openerp_report_designer/bin/package/Addons.xcu [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/LoginTest.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/__init__.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/compile_all.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/import [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/__init__.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/actions.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/gui.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tiny_socket.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/test/test.txt [new file with mode: 0644]
addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py [new file with mode: 0644]
addons/base_report_designer/security/base_report_security.xml [new file with mode: 0644]
addons/base_report_designer/wizard/__init__.py
addons/base_report_designer/wizard/base_report_design_view.xml [new file with mode: 0644]
addons/base_report_designer/wizard/base_report_designer_modify.py
addons/base_report_designer/wizard/tiny_sxw2rml/__init__.py [deleted file]
addons/base_report_designer/wizard/tiny_sxw2rml/normalized_odt2rml.xsl [deleted file]
addons/base_report_designer/wizard/tiny_sxw2rml/normalized_oo2rml.xsl [deleted file]
addons/base_report_designer/wizard/tiny_sxw2rml/office.dtd [deleted file]
addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py [deleted file]
addons/base_synchro/__init__.py [new file with mode: 0644]
addons/base_synchro/__openerp__.py [new file with mode: 0644]
addons/base_synchro/base_synchro_obj.py [new file with mode: 0755]
addons/base_synchro/base_synchro_view.xml [new file with mode: 0755]
addons/base_synchro/base_synchro_wizard.xml [new file with mode: 0644]
addons/base_synchro/wizard/__init__.py [new file with mode: 0644]
addons/base_synchro/wizard/base_synchro.py [new file with mode: 0644]

index 46a0a1e..2a14d28 100644 (file)
@@ -18,8 +18,9 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
 #
 ##############################################################################
-
-import base_report_designer
 import wizard
+import base_report_designer
+import installer
+import openerp_sxw2rml
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
index 50fe73f..9d39bba 100644 (file)
@@ -36,8 +36,9 @@ upload the report using the same wizard.
     'author': 'OpenERP SA',
     'website': 'http://www.openerp.com',
     'depends': ['base'],
-    'init_xml': ['base_report_data.xml'],
-    'update_xml': ['base_report_designer_wizard.xml'],
+    'init_xml': ['security/base_report_security.xml',
+                 'wizard/base_report_design_view.xml'],
+    'update_xml': ['base_report_designer_installer.xml'],
     'demo_xml': [],
     'installable': True,
     'active': False,
diff --git a/addons/base_report_designer/base_report_data.xml b/addons/base_report_designer/base_report_data.xml
deleted file mode 100644 (file)
index bd3854e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" ?>
-<openerp>
-       <data noupdate="1">
-               <record id="res_groups_openofficereportdesigner0" model="res.groups">
-                       <field eval="[(6,0,[])]" name="menu_access"/>
-                       <field eval="[(6,0,[])]" name="rule_groups"/>
-                       <field eval="[(6,0,[ref('base.user_root')])]" name="users"/>
-                       <field eval="&quot;&quot;&quot;OpenOfficeReportDesigner&quot;&quot;&quot;" name="name"/>
-               </record>
-
-       <record id="ir_model_access_openofficereportdesigner0" model="ir.model.access">
-           <field name="model_id" ref="base.model_ir_actions_report_xml"/>
-           <field eval="1" name="perm_read"/>
-           <field eval="&quot;&quot;&quot;OpenOfficeReportDesigner&quot;&quot;&quot;" name="name"/>
-           <field eval="1" name="perm_unlink"/>
-           <field eval="1" name="perm_write"/>
-           <field eval="1" name="perm_create"/>
-           <field name="group_id" ref="res_groups_openofficereportdesigner0"/>
-       </record>
-       </data>
-
-</openerp>
index a4a135c..283c8ec 100644 (file)
 ##############################################################################
 
 from osv import osv
-from wizard.tiny_sxw2rml import sxw2rml
+from openerp_sxw2rml import sxw2rml
 from StringIO import StringIO
 from report import interface
 import base64
 import pooler
 import tools
-
+import addons
 
 class report_xml(osv.osv):
     _inherit = 'ir.actions.report.xml'
@@ -37,12 +37,9 @@ class report_xml(osv.osv):
         '''
         sxwval = StringIO(base64.decodestring(file_sxw))
         if file_type=='sxw':
-            fp = tools.file_open('normalized_oo2rml.xsl', 
-                    subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
+            fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
         if file_type=='odt':
-            fp = tools.file_open('normalized_odt2rml.xsl', 
-                    subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
-
+            fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
         return  {'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read()))}
 
     def upload_report(self, cr, uid, report_id, file_sxw, file_type, context):
@@ -52,11 +49,9 @@ class report_xml(osv.osv):
         pool = pooler.get_pool(cr.dbname)
         sxwval = StringIO(base64.decodestring(file_sxw))
         if file_type=='sxw':
-            fp = tools.file_open('normalized_oo2rml.xsl', 
-                    subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
+            fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_oo2rml.xsl'),'rb')
         if file_type=='odt':
-            fp = tools.file_open('normalized_odt2rml.xsl', 
-                    subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
+            fp = open(addons.get_module_resource('base_report_designer','openerp_sxw2rml', 'normalized_odt2rml.xsl'),'rb')
         report = pool.get('ir.actions.report.xml').write(cr, uid, [report_id], {
             'report_sxw_content': base64.decodestring(file_sxw), 
             'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read())), 
diff --git a/addons/base_report_designer/base_report_designer_installer.xml b/addons/base_report_designer/base_report_designer_installer.xml
new file mode 100644 (file)
index 0000000..21537d3
--- /dev/null
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<openerp>
+  <data>
+
+
+    <record id="view_report_designer_installer" model="ir.ui.view">
+      <field name="name">Form View: OpenERP Report Designer Installation</field>
+      <field name="model">base_report_designer.installer</field>
+      <field name="type">form</field>
+      <field name="inherit_id" ref="base.res_config_installer"/>
+      <field name="arch" type="xml">
+          <data>
+              <form position="attributes">
+                  <attribute name="string">OpenERP Report Designer Configuration</attribute>
+              </form>
+              <separator string="title" position="attributes">
+                   <attribute name="string">OpenERP Report Designer</attribute>
+              </separator>
+              <xpath expr="//label[@string='description']" position="attributes">
+                  <attribute name="string">This plug-in allows you to create/modify OpenERP Reports into OpenOffice Writer.</attribute>
+              </xpath>
+                 <xpath expr="//button[@string='Install Modules']" position="replace">
+                <button colspan="1" icon="gtk-close" special="cancel" string="_Close" invisible="not context.get('menu',False)"/>
+                <button name="action_next" icon="gtk-go-forward"
+                        type="object" string="Configure" colspan="1" invisible="context.get('menu',False)"/>
+              </xpath>
+              <xpath expr="//button[@string='Skip']" position="replace">
+                <button name="action_skip" icon="gtk-jump-to" special="cancel"
+                        type="object" string="Skip" colspan="1" invisible="context.get('menu',False)"/>
+              </xpath>
+              <xpath expr='//separator[@string="vsep"]' position='attributes'>
+                               <attribute name='string'></attribute>
+                               <attribute name='rowspan'>15</attribute>
+                         </xpath>
+                         <group colspan="8" position="replace">
+              <group colspan="8" height="450" width="750">
+                  <field name="name" invisible="1"/>
+                  <field name="plugin_file" filename="name"/>
+                  <separator string="Installation and Configuration Steps" colspan="4"/>
+                  <field name="description" nolabel="1" colspan="8"/>
+              </group>
+              </group>
+          </data>
+      </field>
+    </record>
+
+    <record id="action_report_designer_installer" model="ir.actions.act_window">
+      <field name="name">OpenERP Report Designer Installation</field>
+      <field name="type">ir.actions.act_window</field>
+      <field name="res_model">base_report_designer.installer</field>
+      <field name="view_id" ref="view_report_designer_installer"/>
+      <field name="view_type">form</field>
+      <field name="view_mode">form</field>
+      <field name="target">new</field>
+    </record>
+
+    <record id="report_designer_installer_todo" model="ir.actions.todo">
+      <field name="action_id" ref="action_report_designer_installer"/>
+      <field name="sequence">3</field>
+    </record>
+
+
+
+    <record id="action_report_designer_wizard" model="ir.actions.act_window">
+      <field name="name">OpenERP Report Designer</field>
+      <field name="type">ir.actions.act_window</field>
+      <field name="res_model">base_report_designer.installer</field>
+      <field name="view_id" ref="view_report_designer_installer"/>
+      <field name="view_type">form</field>
+      <field name="view_mode">form</field>
+      <field name="target">new</field>
+      <field name="context">{'menu':True}</field> 
+    </record>
+
+    
+    <menuitem icon="terp-graph" id="base.reporting_menu"
+            name="Reporting" sequence="30" />
+
+    <menuitem id="base.next_id_50" name="Configuration"
+        parent="base.reporting_menu"  sequence="3" />
+
+    <menuitem parent="base.next_id_50" name="Report Designer"
+        action="action_report_designer_wizard"
+        id="menu_action_report_designer_wizard" sequence="70" />
+
+   <menuitem parent="base.next_id_50" name="Modify an existing report"
+            action="action_view_base_report_sxw"
+            id="menu_wizard_report_designer_modify" sequence="70" groups="base.group_extended"/>
+
+  </data>
+</openerp>
+
+
diff --git a/addons/base_report_designer/base_report_designer_wizard.xml b/addons/base_report_designer/base_report_designer_wizard.xml
deleted file mode 100644 (file)
index c1bb7c3..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0"?>
-<openerp>
-    <data>
-
-        <wizard string="Modify an existing report"
-            model="ir.actions.report.xml" name="base_report_designer.modify"
-            id="wizard_report_designer_modify" />
-
-        <menuitem icon="terp-graph" id="base.reporting_menu"
-            name="Reporting" sequence="30" />
-
-        <menuitem id="base.next_id_50" name="Configuration"
-            parent="base.reporting_menu" groups="base.group_system" sequence="3" />
-
-        <menuitem parent="base.next_id_50" name="Report Designer"
-            action="wizard_report_designer_modify" type="wizard"
-            id="menu_wizard_report_designer_modify" sequence="70" />
-
-    </data>
-</openerp>
-
-
diff --git a/addons/base_report_designer/installer.py b/addons/base_report_designer/installer.py
new file mode 100644 (file)
index 0000000..082383b
--- /dev/null
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from osv import fields
+from osv import osv
+import base64
+from tools.translate import _
+import addons
+
+class base_report_designer_installer(osv.osv_memory):
+    _name = 'base_report_designer.installer'
+    _inherit = 'res.config.installer'
+
+    def default_get(self, cr, uid, fields, context={}):
+        data = super(base_report_designer_installer, self).default_get(cr, uid, fields, context)
+        plugin_file = open(addons.get_module_resource('base_report_designer','plugin', 'openerp_report_designer.zip'),'rb')
+        data['plugin_file'] = base64.encodestring(plugin_file.read())
+        return data
+
+    _columns = {
+        'name':fields.char('File name', size=34),
+        'plugin_file':fields.binary('OpenObject Report Designer Plug-in', readonly=True, help="OpenObject Report Designer plug-in file. Save as this file and install this plug-in in OpenOffice."),
+        'description':fields.text('Description', readonly=True)
+    }
+
+    _defaults = {
+        'name' : 'openerp_report_designer.zip',
+        'description' : """
+        * Save the OpenERP Report Designer plug-­in.
+        * Follow these steps to install plug-­in.
+            1. Open Extension Manager window from Menu Bar of Openoffice writer, Open Tools > Extension Menu.
+            2. Click on "Add" button.
+            3. Select path where the openerp_report_designer.zip is located.
+            4. On the completion of adding package you will get your package under 'Extension Manager' and the status of your package become 'Enabled'.
+            5. Restart openoffice writer.
+        * Follow the steps to configure OpenERP Report Designer plug-­in in Openoffice writer.
+            1. Connect OpenERP Server from Menu bar , OpenERP Report Designer > Server parameter.
+            2. Select Server url, database and provide user name and password
+            3. Click "Connect".
+            4. if your connection success, A message appears like 'You can start creating your report in current document.'.
+        """
+    }
+base_report_designer_installer()
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/base_report_designer/openerp_sxw2rml/__init__.py b/addons/base_report_designer/openerp_sxw2rml/__init__.py
new file mode 100644 (file)
index 0000000..797fa7f
--- /dev/null
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#    
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
+#
+##############################################################################
+
+from openerp_sxw2rml import sxw2rml
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl b/addons/base_report_designer/openerp_sxw2rml/normalized_odt2rml.xsl
new file mode 100644 (file)
index 0000000..50ffb3d
--- /dev/null
@@ -0,0 +1,696 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
+  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
+  xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
+  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
+  xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
+  xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
+  xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
+  xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
+  xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
+  xmlns:math="http://www.w3.org/1998/Math/MathML"
+  xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
+  xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
+  office:class="text" office:version="1.1"
+  exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
+
+  <!--TODO's: indent, picture cache (trml2pdf) -->
+
+<xsl:output method="xml" indent="yes" />
+<xsl:strip-space elements="*"/>
+
+<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
+<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
+<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
+<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
+<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
+<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
+
+<xsl:template match="office:document-content">
+  <document filename="test.pdf">
+    <xsl:apply-templates select="office:automatic-styles" />
+    <xsl:apply-templates select="office:body" />
+  </document>
+</xsl:template>
+
+<xsl:template name="page_size">
+  <xsl:attribute name="pageSize">
+    <xsl:text>(</xsl:text>
+    <xsl:value-of select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
+    <xsl:text>,</xsl:text>
+    <xsl:value-of select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height" />
+    <xsl:text>)</xsl:text>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="fixed_frame">
+       <xsl:for-each select="//draw:text-box">
+               <frame>
+                       <xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
+                       <xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
+                       <xsl:attribute name="y1">
+                               <xsl:value-of
+                                       select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
+                       </xsl:attribute>
+                       <xsl:attribute name="width">
+                               <xsl:value-of select="./@svg:width" />
+                       </xsl:attribute>
+                       <xsl:attribute name="height">
+                               <xsl:value-of select="./@fo:min-height" />
+                       </xsl:attribute>
+               </frame>
+       </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="margin_sizes">
+  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-left" />
+  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-right" />
+  <xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-top" />
+  <xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-bottom" />
+  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
+  <xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height" />
+  <xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
+  <xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
+  <xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
+  <xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
+</xsl:template>
+
+<xsl:template name="text_width">
+  <!-- You need this for the workaround to make primitive outlines-->
+  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-left" />
+  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-right" />
+  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
+  <xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
+</xsl:template>
+
+
+
+<xsl:template match="office:automatic-styles">
+  <!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
+  <template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
+    <xsl:call-template name="page_size" />
+    <pageTemplate id="first">
+         <xsl:call-template name="fixed_frame" />
+      <frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
+        <xsl:call-template name="margin_sizes" />
+      </frame>
+    </pageTemplate>
+  </template>
+  <stylesheet>
+    <!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
+    <blockTableStyle id="Standard_Outline">
+      <blockAlignment value="LEFT"/>
+      <blockValign value="TOP"/>
+    </blockTableStyle>
+    <!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
+    <!--TODO insert table cell colors here, not within the <td> tag - otherwise
+         it will not work with flowables as cell content-->
+    <xsl:call-template name="make_blocktablestyle" />
+    <initialize>
+      <paraStyle name="all" alignment="justify" />
+    </initialize>
+    <xsl:apply-templates select="style:style" />
+  </stylesheet>
+</xsl:template>
+
+<xsl:template name="make_blocktablestyle">
+  <xsl:for-each select="//table:table">
+    <xsl:variable name="test">
+      <xsl:value-of select="./@table:name" />
+    </xsl:variable>
+    <xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
+      <!--Test if this is the first table with this style, nested tables not counted-->
+      <blockTableStyle id="{@table:name}">
+           <xsl:if test=".//draw:image">
+             <blockTopPadding value="0"/>
+             <blockBottomPadding value="0"/>
+           </xsl:if>
+        <blockAlignment value="LEFT" />
+        <blockValign value="TOP" />
+        <xsl:call-template name="make_linestyle" />
+        <xsl:call-template name="make_tablebackground" />
+      </blockTableStyle>
+    </xsl:if>
+  </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="make_linestyle">
+       <xsl:for-each select=".//table:table-row">
+               <xsl:variable name="row" select="position() - 1"/>
+               <xsl:for-each select=".//table:table-cell">
+                       <xsl:variable name="col" select="position() - 1"/>
+                       <xsl:variable name="linebefore">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-left"/>
+                       </xsl:variable>
+                       <xsl:if test="not($linebefore='') and not($linebefore='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($linebefore,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                       </xsl:if>
+                       <xsl:variable name="lineafter">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-right"/>
+                       </xsl:variable>
+                       <xsl:if test="not($lineafter='') and not($lineafter='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($lineafter,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                       </xsl:if>
+                       <xsl:variable name="lineabove">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-top"/>
+                       </xsl:variable>
+                       <xsl:if test="not($lineabove='') and not($lineabove='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($lineabove,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
+                       </xsl:if>
+                       <xsl:variable name="linebelow">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-bottom"/>
+                       </xsl:variable>
+                       <xsl:if test="not($linebelow='') and not($linebelow='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($linebelow,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
+                       </xsl:if>
+                       <xsl:variable name="grid">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border"/>
+                       </xsl:variable>
+                       <xsl:if test="not($grid='') and not($grid='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($grid,'#')"/>
+                               </xsl:variable>
+                               <!-- Don't use grid because we don't need a line between each rows -->
+                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
+                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
+                       </xsl:if>
+               </xsl:for-each>
+       </xsl:for-each>
+</xsl:template>
+
+<!-- Was needed to simulate bulleted lists:
+<xsl:template match="text:ordered-list|text:unordered-list">
+  <xsl:variable name = "text_width">
+    <xsl:call-template name="text_width" />
+  </xsl:variable>
+  <blockTable style="Standard_Outline" colWidths="18,{$text_width}">
+  <xsl:apply-templates match="text:list-item" />
+</blockTable>
+</xsl:template>
+
+<xsl:template match="text:list-item">
+  <tr>
+    <td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
+    <td>
+      <xsl:apply-templates />
+    </td>
+  </tr>
+</xsl:template>
+
+-->
+
+
+<xsl:template match="office:body">
+  <story>
+    <xsl:apply-templates />
+       <xsl:for-each select="//draw:text-box">
+               <currentFrame>
+                       <xsl:attribute name="name">
+                               <xsl:value-of select="./@draw:name" />
+                       </xsl:attribute>
+               </currentFrame>
+               <xsl:apply-templates>
+                       <xsl:with-param name="skip_draw" select="0" />
+               </xsl:apply-templates>
+               <frameEnd />
+       </xsl:for-each>
+       <xsl:for-each select="//text:ordered-list">
+               <para><seqReset id="{./@text:style-name}"/></para>
+       </xsl:for-each>
+  </story>
+</xsl:template>
+
+<xsl:template match="table:table">
+  <blockTable>
+    <xsl:attribute name="colWidths">
+      <xsl:call-template name="make_columns" />
+    </xsl:attribute>
+    <xsl:call-template name="make_tableheaders" />
+    <xsl:attribute name="style">
+      <xsl:value-of select="@table:name" />
+    </xsl:attribute>
+    <xsl:apply-templates />
+  </blockTable>
+</xsl:template>
+
+<xsl:template name="make_tableheaders">
+  <xsl:if test="boolean(count(table:table-header-rows))">
+    <xsl:attribute name="repeatRows">1</xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_tablebackground">
+  <xsl:for-each select=".//table:table-row">
+    <!--Be careful when there are table:table-header-rows as
+         parent node of table:table-row -->
+    <xsl:variable name="row" select="position() - 1" />
+    <xsl:for-each select="./table:table-cell">
+      <xsl:variable name="col" select="position() - 1" />
+      <xsl:variable name="background">
+        <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
+      </xsl:variable>
+      <xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
+        <!--only RGB hexcolors are accepted -->
+               <blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},-1" />
+      </xsl:if>
+     </xsl:for-each>
+   </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="make_columns">
+  <xsl:variable name="columns" >
+    <xsl:for-each select="table:table-column">
+      <xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
+      <xsl:text>,</xsl:text>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
+  <!--strip the last comma-->
+</xsl:template>
+
+<xsl:template match="table:table-row">
+  <tr>
+    <xsl:apply-templates />
+  </tr>
+</xsl:template>
+
+<xsl:template match="table:table-cell">
+  <td>
+    <xsl:apply-templates />
+  </td>
+</xsl:template>
+
+<xsl:template match="text:section">
+  <section>
+    <xsl:apply-templates />
+  </section>
+</xsl:template>
+
+
+<xsl:template match="text:span">
+  <font>
+    <xsl:call-template name="make_fontnames_span" />
+    <xsl:call-template name="make_fontsize_span" />
+    <xsl:apply-templates />
+  </font>
+</xsl:template>
+
+<xsl:template name="make_fontsize_span">
+  <xsl:variable name ="fontsize">
+    <xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
+  </xsl:variable>
+  <xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
+    <xsl:attribute name="size">
+      <xsl:value-of select="$fontsize" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontnames_span">
+  <xsl:attribute name="face">
+    <xsl:call-template name="make_fontnames">
+      <xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name"  />
+      <xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight"  />
+      <xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
+    </xsl:call-template>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="make_image">
+  <illustration height="{.//draw:frame/@svg:height}" width="{.//draw:frame/@svg:width}">
+    <image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'Pictures/')}" height="{.//draw:frame/@svg:height}" width="{.//draw:frame/@svg:width}" />
+  </illustration>
+</xsl:template>
+
+<xsl:template name="empty_paragraph">
+  <xsl:if test="not(boolean(count(descendant::node())))">
+    <xsl:call-template name="distance_point">
+      <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="distance_point">
+  <xsl:param name="background" />
+  <xsl:param name="tab_stop"></xsl:param>
+  <xsl:variable name="local_back">
+    <xsl:choose>
+      <xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
+        <!-- Do not accept OO colors like "transparent", only hex-colors -->
+        <xsl:text>white</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$background" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <font color="{$local_back}">
+    <xsl:text> </xsl:text>
+    <xsl:if test="boolean($tab_stop)">
+      <!-- simulate a tabstop with white/background-color points -->
+      <xsl:text>.........</xsl:text>
+    </xsl:if>
+  </font>
+</xsl:template>
+
+<xsl:template match="text:ordered-list">
+  <xsl:apply-templates />
+
+  <!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
+       so it needs a dummy paragraph to enclose it -->
+</xsl:template>
+
+<xsl:template name="make_listitem">
+  <xsl:if test="(name(..)='text:list-item')">
+    <xsl:attribute name="leftIndent">15</xsl:attribute>
+    <xsl:attribute name="bulletIndent">0</xsl:attribute>
+    <xsl:choose>
+      <xsl:when test="(name(../..)='text:unordered-list')">
+        <xsl:variable name="fontsize">
+          <xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
+        </xsl:variable>
+        <xsl:choose>
+          <xsl:when test="$fontsize='NaN'">
+            <!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
+            <!--use a default bullet font size-->
+            <xsl:attribute name="bulletFontSize">6</xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
+        <xsl:attribute name="bulletText">l</xsl:attribute>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- Generate the numbers for an ordered list -->
+        <xsl:variable name="size">
+          <xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
+        </xsl:variable>
+        <!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
+        <bullet>
+          <xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
+            <xsl:attribute name="size">
+              <!-- adapt the fontsize to the fontsize of the current paragraph -->
+              <xsl:value-of select="$size" />
+            </xsl:attribute>
+          </xsl:if>
+          <seq id="{../../@text:style-name}"/>.</bullet>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="text:drop-down">
+    <xsl:value-of select="text:label[2]/@text:value" />
+</xsl:template>
+
+
+<xsl:template match="text:p|text:h">
+       <xsl:param name="skip_draw" select="1" />
+  <xsl:if test="boolean(key('page_break_before',@text:style-name))" >
+    <pageBreak />
+  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="boolean(.//draw:image)">
+      <xsl:call-template name="make_image" />
+    </xsl:when>
+       <xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
+       </xsl:when>
+    <xsl:otherwise>
+      <para>
+        <xsl:attribute name="style">
+          <xsl:value-of select="@text:style-name" />
+        </xsl:attribute>
+        <xsl:call-template name="make_listitem" />
+        <xsl:apply-templates />
+        <xsl:call-template name="empty_paragraph" />
+      </para>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:if test="boolean(key('page_break_after',@text:style-name))" >
+    <pageBreak />
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="text:p/text:tab-stop">
+  <!-- simulate a tabstop -->
+  <xsl:call-template name="distance_point">
+    <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
+    <xsl:with-param name="tab_stop">yes</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- experimental - switched off
+<xsl:template match="text:h">
+  <para>
+    <xsl:attribute name="style">
+      <xsl:value-of select="@text:style-name" />
+    </xsl:attribute>
+    <xsl:call-template name="make_number" />
+    <xsl:apply-templates />
+    <xsl:call-template name="empty_paragraph" />
+  </para>
+</xsl:template>
+
+<xsl:template name="make_number">
+  <xsl:choose>
+    <xsl:when test="@text:level='1'">
+      <xsl:number format="1. " />
+    </xsl:when>
+    <xsl:when test="@text:level='2'">
+      <xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+-->
+
+<xsl:template match="style:style[@style:family='paragraph']">
+  <paraStyle>
+    <xsl:attribute name="name">
+      <xsl:value-of select="@style:name" />
+    </xsl:attribute>
+    <xsl:call-template name="make_indent_paragraph" />
+    <xsl:call-template name="make_fontnames_paragraph" />
+    <xsl:call-template name="make_fontsize" />
+    <!--<xsl:call-template name="make_parent" /> not necessary -
+         parent styles processed by PyOpenOffice -->
+    <xsl:call-template name="make_alignment" />
+    <xsl:call-template name="make_background" />
+    <xsl:call-template name="make_space_beforeafter" />
+    <xsl:call-template name="make_fontcolor" />
+  </paraStyle>
+</xsl:template>
+
+<xsl:template name="make_indent_paragraph">
+  <xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
+  <xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
+  <xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
+    <xsl:attribute name="rightIndent">
+      <xsl:value-of select="$right_indent" />
+    </xsl:attribute>
+  </xsl:if>
+  <xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
+    <xsl:attribute name="leftIndent">
+      <xsl:value-of select="$left_indent" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_background">
+  <xsl:variable name="background">
+    <xsl:value-of select="style:properties/@fo:background-color" />
+  </xsl:variable>
+  <xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
+    <xsl:attribute name="backColor">
+      <xsl:value-of select="$background" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_space_beforeafter">
+  <xsl:variable name="before">
+    <xsl:value-of select="style:properties/@fo:margin-top" />
+  </xsl:variable>
+  <xsl:variable name="after">
+    <xsl:value-of select="style:properties/@fo:margin-bottom" />
+  </xsl:variable>
+  <xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
+    <xsl:attribute name="spaceBefore">
+      <xsl:value-of select="$before" />
+    </xsl:attribute>
+  </xsl:if>
+  <xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
+    <xsl:attribute name="spaceAfter">
+      <xsl:value-of select="$after" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontsize">
+  <xsl:variable name="fontSize">
+    <xsl:value-of select="style:properties/@fo:font-size" />
+  </xsl:variable>
+  <xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
+    <xsl:attribute name="fontSize">
+      <xsl:value-of select="$fontSize" />
+    </xsl:attribute>
+    <xsl:attribute name="leading">
+      <xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
+      <!--use a standard leading related to the font size -->
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!--this template is not needed anymore for "normalized" sxw files -->
+<xsl:template name="make_parent">
+  <xsl:variable name="parent">
+    <xsl:value-of select="@style:parent-style-name" />
+  </xsl:variable>
+  <xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
+    <xsl:attribute name="parent">
+      <xsl:value-of select="$parent" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_alignment">
+  <xsl:variable name="alignment">
+    <xsl:value-of select="style:properties/@fo:text-align" />
+  </xsl:variable>
+  <xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
+    <xsl:choose>
+      <xsl:when test="$alignment='start'">
+        <xsl:attribute name="alignment">LEFT</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='center'">
+        <xsl:attribute name="alignment">CENTER</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='end'">
+        <xsl:attribute name="alignment">RIGHT</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='justify'">
+        <xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontnames_paragraph">
+  <xsl:attribute name="fontName">
+    <xsl:call-template name="make_fontnames">
+      <xsl:with-param name="fontName" select="style:properties/@style:font-name" />
+      <xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
+      <xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
+    </xsl:call-template>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="make_fontnames">
+  <!--much too verbose, needs improvement-->
+<xsl:param name="fontName" />
+<xsl:param name="fontWeight" />
+<xsl:param name="fontStyle" />
+<xsl:choose>
+<xsl:when test="not($fontName='') and boolean($fontName)">
+  <xsl:choose>
+    <xsl:when test="contains($fontName,'Courier')">
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Courier-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Courier-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Courier-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Courier</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Helvetica-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Helvetica</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Helvetica-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Helvetica</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:when>
+<xsl:otherwise>
+  <!--Use this as default -->
+  <xsl:text>Helvetica</xsl:text>
+</xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+
+<xsl:template name="make_fontcolor">
+  <xsl:variable name="textColor">
+    <xsl:value-of select="style:properties/@fo:color"/>
+  </xsl:variable>
+  <xsl:if test="not($textColor='') and boolean(style:properties/@fo:color)">
+  <xsl:attribute name="textColor">
+      <xsl:value-of select="$textColor" />
+   </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!--
+This stylesheet is part of:
+PyOpenOffice Version 0.4
+Copyright (C) 2005: Martin Simon
+Homepage: www.bezirksreiter.de
+
+GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
+-->
+
+</xsl:stylesheet>
+
+
diff --git a/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl b/addons/base_report_designer/openerp_sxw2rml/normalized_oo2rml.xsl
new file mode 100644 (file)
index 0000000..66ef0b5
--- /dev/null
@@ -0,0 +1,696 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="http://www.w3.org/1999/XSL/Format"
+  xmlns:office="http://openoffice.org/2000/office"
+  xmlns:style="http://openoffice.org/2000/style"
+  xmlns:text="http://openoffice.org/2000/text"
+  xmlns:table="http://openoffice.org/2000/table"
+  xmlns:draw="http://openoffice.org/2000/drawing"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:number="http://openoffice.org/2000/datastyle"
+  xmlns:svg="http://www.w3.org/2000/svg"
+  xmlns:chart="http://openoffice.org/2000/chart"
+  xmlns:dr3d="http://openoffice.org/2000/dr3d"
+  xmlns:math="http://www.w3.org/1998/Math/MathML"
+  xmlns:form="http://openoffice.org/2000/form"
+  xmlns:script="http://openoffice.org/2000/script"
+  office:class="text" office:version="1.0"
+  exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
+
+  <!--TODO's: indent, picture cache (trml2pdf) -->
+
+<xsl:output method="xml" indent="yes" />
+<xsl:strip-space elements="*"/>
+
+<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
+<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
+<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
+<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
+<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
+<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
+
+<xsl:template match="office:document-content">
+  <document filename="test.pdf">
+    <xsl:apply-templates select="office:automatic-styles" />
+    <xsl:apply-templates select="office:body" />
+  </document>
+</xsl:template>
+
+<xsl:template name="page_size">
+  <xsl:attribute name="pageSize">
+    <xsl:text>(</xsl:text>
+    <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
+    <xsl:text>,</xsl:text>
+    <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
+    <xsl:text>)</xsl:text>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="fixed_frame">
+       <xsl:for-each select="//draw:text-box">
+               <frame>
+                       <xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
+                       <xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
+                       <xsl:attribute name="y1">
+                               <xsl:value-of
+                                       select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
+                       </xsl:attribute>
+                       <xsl:attribute name="width">
+                               <xsl:value-of select="./@svg:width" />
+                       </xsl:attribute>
+                       <xsl:attribute name="height">
+                               <xsl:value-of select="./@fo:min-height" />
+                       </xsl:attribute>
+               </frame>
+       </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="margin_sizes">
+  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
+  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
+  <xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-top" />
+  <xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-bottom" />
+  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
+  <xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
+  <xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
+  <xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
+  <xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
+  <xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
+</xsl:template>
+
+<xsl:template name="text_width">
+  <!-- You need this for the workaround to make primitive outlines-->
+  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
+  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
+  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
+  <xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
+</xsl:template>
+
+
+
+<xsl:template match="office:automatic-styles">
+  <!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
+  <template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
+    <xsl:call-template name="page_size" />
+    <pageTemplate id="first">
+         <xsl:call-template name="fixed_frame" />
+      <frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
+        <xsl:call-template name="margin_sizes" />
+      </frame>
+    </pageTemplate>
+  </template>
+  <stylesheet>
+    <!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
+    <blockTableStyle id="Standard_Outline">
+      <blockAlignment value="LEFT"/>
+      <blockValign value="TOP"/>
+    </blockTableStyle>
+    <!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
+    <!--TODO insert table cell colors here, not within the <td> tag - otherwise
+         it will not work with flowables as cell content-->
+    <xsl:call-template name="make_blocktablestyle" />
+    <initialize>
+      <paraStyle name="all" alignment="justify" />
+    </initialize>
+    <xsl:apply-templates select="style:style" />
+  </stylesheet>
+</xsl:template>
+
+<xsl:template name="make_blocktablestyle">
+  <xsl:for-each select="//table:table">
+    <xsl:variable name="test">
+      <xsl:value-of select="./@table:name" />
+    </xsl:variable>
+    <xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
+      <!--Test if this is the first table with this style, nested tables not counted-->
+      <blockTableStyle id="{@table:name}">
+           <xsl:if test=".//draw:image">
+             <blockTopPadding value="0"/>
+             <blockBottomPadding value="0"/>
+           </xsl:if>
+        <blockAlignment value="LEFT" />
+        <blockValign value="TOP" />
+        <xsl:call-template name="make_linestyle" />
+        <xsl:call-template name="make_tablebackground" />
+      </blockTableStyle>
+    </xsl:if>
+  </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="make_linestyle">
+       <xsl:for-each select=".//table:table-row">
+               <xsl:variable name="row" select="position() - 1"/>
+               <xsl:for-each select=".//table:table-cell">
+                       <xsl:variable name="col" select="position() - 1"/>
+                       <xsl:variable name="linebefore">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-left"/>
+                       </xsl:variable>
+                       <xsl:if test="not($linebefore='') and not($linebefore='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($linebefore,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                       </xsl:if>
+                       <xsl:variable name="lineafter">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-right"/>
+                       </xsl:variable>
+                       <xsl:if test="not($lineafter='') and not($lineafter='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($lineafter,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                       </xsl:if>
+                       <xsl:variable name="lineabove">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-top"/>
+                       </xsl:variable>
+                       <xsl:if test="not($lineabove='') and not($lineabove='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($lineabove,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
+                       </xsl:if>
+                       <xsl:variable name="linebelow">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-bottom"/>
+                       </xsl:variable>
+                       <xsl:if test="not($linebelow='') and not($linebelow='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($linebelow,'#')"/>
+                               </xsl:variable>
+                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
+                       </xsl:if>
+                       <xsl:variable name="grid">
+                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border"/>
+                       </xsl:variable>
+                       <xsl:if test="not($grid='') and not($grid='none')">
+                               <xsl:variable name="colorname">
+                                       <xsl:value-of select="substring-after($grid,'#')"/>
+                               </xsl:variable>
+                               <!-- Don't use grid because we don't need a line between each rows -->
+                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
+                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
+                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
+                       </xsl:if>
+               </xsl:for-each>
+       </xsl:for-each>
+</xsl:template>
+
+<!-- Was needed to simulate bulleted lists:
+<xsl:template match="text:ordered-list|text:unordered-list">
+  <xsl:variable name = "text_width">
+    <xsl:call-template name="text_width" />
+  </xsl:variable>
+  <blockTable style="Standard_Outline" colWidths="18,{$text_width}">
+  <xsl:apply-templates match="text:list-item" />
+</blockTable>
+</xsl:template>
+
+<xsl:template match="text:list-item">
+  <tr>
+    <td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
+    <td>
+      <xsl:apply-templates />
+    </td>
+  </tr>
+</xsl:template>
+
+-->
+
+
+<xsl:template match="office:body">
+  <story>
+    <xsl:apply-templates />
+       <xsl:for-each select="//draw:text-box">
+               <currentFrame>
+                       <xsl:attribute name="name">
+                               <xsl:value-of select="./@draw:name" />
+                       </xsl:attribute>
+               </currentFrame>
+               <xsl:apply-templates>
+                       <xsl:with-param name="skip_draw" select="0" />
+               </xsl:apply-templates>
+               <frameEnd />
+       </xsl:for-each>
+       <xsl:for-each select="//text:ordered-list">
+               <para><seqReset id="{./@text:style-name}"/></para>
+       </xsl:for-each>
+  </story>
+</xsl:template>
+
+<xsl:template match="table:table">
+  <blockTable>
+    <xsl:attribute name="colWidths">
+      <xsl:call-template name="make_columns" />
+    </xsl:attribute>
+    <xsl:call-template name="make_tableheaders" />
+    <xsl:attribute name="style">
+      <xsl:value-of select="@table:name" />
+    </xsl:attribute>
+    <xsl:apply-templates />
+  </blockTable>
+</xsl:template>
+
+<xsl:template name="make_tableheaders">
+  <xsl:if test="boolean(count(table:table-header-rows))">
+    <xsl:attribute name="repeatRows">1</xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_tablebackground">
+  <xsl:for-each select=".//table:table-row">
+    <!--Be careful when there are table:table-header-rows as
+         parent node of table:table-row -->
+    <xsl:variable name="row" select="position() - 1" />
+    <xsl:for-each select="./table:table-cell">
+      <xsl:variable name="col" select="position() - 1" />
+      <xsl:variable name="background">
+        <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
+      </xsl:variable>
+      <xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
+        <!--only RGB hexcolors are accepted -->
+               <blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},-1" />
+      </xsl:if>
+     </xsl:for-each>
+   </xsl:for-each>
+</xsl:template>
+
+<xsl:template name="make_columns">
+  <xsl:variable name="columns" >
+    <xsl:for-each select="table:table-column">
+      <xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
+      <xsl:text>,</xsl:text>
+    </xsl:for-each>
+  </xsl:variable>
+  <xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
+  <!--strip the last comma-->
+</xsl:template>
+
+<xsl:template match="table:table-row">
+  <tr>
+    <xsl:apply-templates />
+  </tr>
+</xsl:template>
+
+<xsl:template match="table:table-cell">
+  <td>
+    <xsl:apply-templates />
+  </td>
+</xsl:template>
+
+<xsl:template match="text:section">
+  <section>
+    <xsl:apply-templates />
+  </section>
+</xsl:template>
+
+
+<xsl:template match="text:span">
+  <font>
+    <xsl:call-template name="make_fontnames_span" />
+    <xsl:call-template name="make_fontsize_span" />
+    <xsl:apply-templates />
+  </font>
+</xsl:template>
+
+<xsl:template name="make_fontsize_span">
+  <xsl:variable name ="fontsize">
+    <xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
+  </xsl:variable>
+  <xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
+    <xsl:attribute name="size">
+      <xsl:value-of select="$fontsize" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontnames_span">
+  <xsl:attribute name="face">
+    <xsl:call-template name="make_fontnames">
+      <xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name"  />
+      <xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight"  />
+      <xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
+    </xsl:call-template>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="make_image">
+  <illustration height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}">
+    <image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'#Pictures/')}" height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}" />
+  </illustration>
+</xsl:template>
+
+<xsl:template name="empty_paragraph">
+  <xsl:if test="not(boolean(count(descendant::node())))">
+    <xsl:call-template name="distance_point">
+      <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
+    </xsl:call-template>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="distance_point">
+  <xsl:param name="background" />
+  <xsl:param name="tab_stop"></xsl:param>
+  <xsl:variable name="local_back">
+    <xsl:choose>
+      <xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
+        <!-- Do not accept OO colors like "transparent", only hex-colors -->
+        <xsl:text>white</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="$background" />
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <font color="{$local_back}">
+    <xsl:text> </xsl:text>
+    <xsl:if test="boolean($tab_stop)">
+      <!-- simulate a tabstop with white/background-color points -->
+      <xsl:text>.........</xsl:text>
+    </xsl:if>
+  </font>
+</xsl:template>
+
+<xsl:template match="text:ordered-list">
+  <xsl:apply-templates />
+
+  <!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
+       so it needs a dummy paragraph to enclose it -->
+</xsl:template>
+
+<xsl:template name="make_listitem">
+  <xsl:if test="(name(..)='text:list-item')">
+    <xsl:attribute name="leftIndent">15</xsl:attribute>
+    <xsl:attribute name="bulletIndent">0</xsl:attribute>
+    <xsl:choose>
+      <xsl:when test="(name(../..)='text:unordered-list')">
+        <xsl:variable name="fontsize">
+          <xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
+        </xsl:variable>
+        <xsl:choose>
+          <xsl:when test="$fontsize='NaN'">
+            <!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
+            <!--use a default bullet font size-->
+            <xsl:attribute name="bulletFontSize">6</xsl:attribute>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
+          </xsl:otherwise>
+        </xsl:choose>
+        <xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
+        <xsl:attribute name="bulletText">l</xsl:attribute>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- Generate the numbers for an ordered list -->
+        <xsl:variable name="size">
+          <xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
+        </xsl:variable>
+        <!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
+        <bullet>
+          <xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
+            <xsl:attribute name="size">
+              <!-- adapt the fontsize to the fontsize of the current paragraph -->
+              <xsl:value-of select="$size" />
+            </xsl:attribute>
+          </xsl:if>
+          <seq id="{../../@text:style-name}"/>.</bullet>
+
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="text:drop-down">
+    <xsl:value-of select="text:label[2]/@text:value" />
+</xsl:template>
+
+
+<xsl:template match="text:p|text:h">
+       <xsl:param name="skip_draw" select="1" />
+  <xsl:if test="boolean(key('page_break_before',@text:style-name))" >
+    <pageBreak />
+  </xsl:if>
+  <xsl:choose>
+    <xsl:when test="boolean(.//draw:image)">
+      <xsl:call-template name="make_image" />
+    </xsl:when>
+       <xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
+       </xsl:when>
+    <xsl:otherwise>
+      <para>
+        <xsl:attribute name="style">
+          <xsl:value-of select="@text:style-name" />
+        </xsl:attribute>
+        <xsl:call-template name="make_listitem" />
+        <xsl:apply-templates />
+        <xsl:call-template name="empty_paragraph" />
+      </para>
+    </xsl:otherwise>
+  </xsl:choose>
+  <xsl:if test="boolean(key('page_break_after',@text:style-name))" >
+    <pageBreak />
+  </xsl:if>
+</xsl:template>
+
+<xsl:template match="text:p/text:tab-stop">
+  <!-- simulate a tabstop -->
+  <xsl:call-template name="distance_point">
+    <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
+    <xsl:with-param name="tab_stop">yes</xsl:with-param>
+  </xsl:call-template>
+</xsl:template>
+
+<!-- experimental - switched off
+<xsl:template match="text:h">
+  <para>
+    <xsl:attribute name="style">
+      <xsl:value-of select="@text:style-name" />
+    </xsl:attribute>
+    <xsl:call-template name="make_number" />
+    <xsl:apply-templates />
+    <xsl:call-template name="empty_paragraph" />
+  </para>
+</xsl:template>
+
+<xsl:template name="make_number">
+  <xsl:choose>
+    <xsl:when test="@text:level='1'">
+      <xsl:number format="1. " />
+    </xsl:when>
+    <xsl:when test="@text:level='2'">
+      <xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
+    </xsl:when>
+  </xsl:choose>
+</xsl:template>
+
+-->
+
+<xsl:template match="style:style[@style:family='paragraph']">
+  <paraStyle>
+    <xsl:attribute name="name">
+      <xsl:value-of select="@style:name" />
+    </xsl:attribute>
+    <xsl:call-template name="make_indent_paragraph" />
+    <xsl:call-template name="make_fontnames_paragraph" />
+    <xsl:call-template name="make_fontsize" />
+    <!--<xsl:call-template name="make_parent" /> not necessary -
+         parent styles processed by PyOpenOffice -->
+    <xsl:call-template name="make_alignment" />
+    <xsl:call-template name="make_background" />
+    <xsl:call-template name="make_space_beforeafter" />
+    <xsl:call-template name="make_fontcolor" />
+  </paraStyle>
+</xsl:template>
+
+<xsl:template name="make_indent_paragraph">
+  <xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
+  <xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
+  <xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
+    <xsl:attribute name="rightIndent">
+      <xsl:value-of select="$right_indent" />
+    </xsl:attribute>
+  </xsl:if>
+  <xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
+    <xsl:attribute name="leftIndent">
+      <xsl:value-of select="$left_indent" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_background">
+  <xsl:variable name="background">
+    <xsl:value-of select="style:properties/@fo:background-color" />
+  </xsl:variable>
+  <xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
+    <xsl:attribute name="backColor">
+      <xsl:value-of select="$background" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_space_beforeafter">
+  <xsl:variable name="before">
+    <xsl:value-of select="style:properties/@fo:margin-top" />
+  </xsl:variable>
+  <xsl:variable name="after">
+    <xsl:value-of select="style:properties/@fo:margin-bottom" />
+  </xsl:variable>
+  <xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
+    <xsl:attribute name="spaceBefore">
+      <xsl:value-of select="$before" />
+    </xsl:attribute>
+  </xsl:if>
+  <xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
+    <xsl:attribute name="spaceAfter">
+      <xsl:value-of select="$after" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontsize">
+  <xsl:variable name="fontSize">
+    <xsl:value-of select="style:properties/@fo:font-size" />
+  </xsl:variable>
+  <xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
+    <xsl:attribute name="fontSize">
+      <xsl:value-of select="$fontSize" />
+    </xsl:attribute>
+    <xsl:attribute name="leading">
+      <xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
+      <!--use a standard leading related to the font size -->
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!--this template is not needed anymore for "normalized" sxw files -->
+<xsl:template name="make_parent">
+  <xsl:variable name="parent">
+    <xsl:value-of select="@style:parent-style-name" />
+  </xsl:variable>
+  <xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
+    <xsl:attribute name="parent">
+      <xsl:value-of select="$parent" />
+    </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_alignment">
+  <xsl:variable name="alignment">
+    <xsl:value-of select="style:properties/@fo:text-align" />
+  </xsl:variable>
+  <xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
+    <xsl:choose>
+      <xsl:when test="$alignment='start'">
+        <xsl:attribute name="alignment">LEFT</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='center'">
+        <xsl:attribute name="alignment">CENTER</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='end'">
+        <xsl:attribute name="alignment">RIGHT</xsl:attribute>
+      </xsl:when>
+      <xsl:when test="$alignment='justify'">
+        <xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
+      </xsl:when>
+    </xsl:choose>
+  </xsl:if>
+</xsl:template>
+
+<xsl:template name="make_fontnames_paragraph">
+  <xsl:attribute name="fontName">
+    <xsl:call-template name="make_fontnames">
+      <xsl:with-param name="fontName" select="style:properties/@style:font-name" />
+      <xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
+      <xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
+    </xsl:call-template>
+  </xsl:attribute>
+</xsl:template>
+
+<xsl:template name="make_fontnames">
+  <!--much too verbose, needs improvement-->
+<xsl:param name="fontName" />
+<xsl:param name="fontWeight" />
+<xsl:param name="fontStyle" />
+<xsl:choose>
+<xsl:when test="not($fontName='') and boolean($fontName)">
+  <xsl:choose>
+    <xsl:when test="contains($fontName,'Courier')">
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Courier-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Courier-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Courier-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Courier</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Helvetica-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Helvetica</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:when>
+    <xsl:otherwise>
+      <xsl:choose>
+        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-BoldOblique</xsl:text>
+        </xsl:when>
+        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
+          <xsl:text>Helvetica-Bold</xsl:text>
+        </xsl:when>
+        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
+          <xsl:text>Helvetica-Oblique</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>Helvetica</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:otherwise>
+  </xsl:choose>
+</xsl:when>
+<xsl:otherwise>
+  <!--Use this as default -->
+  <xsl:text>Helvetica</xsl:text>
+</xsl:otherwise>
+</xsl:choose>
+</xsl:template>
+<xsl:template name="make_fontcolor">
+  <xsl:variable name="textColor">
+    <xsl:value-of select="style:properties/@fo:color"/>
+  </xsl:variable>
+  <xsl:if test="not($textColor='') and boolean(style:properties/@fo:color)">
+  <xsl:attribute name="textColor">
+      <xsl:value-of select="$textColor" />
+   </xsl:attribute>
+  </xsl:if>
+</xsl:template>
+
+<!--
+This stylesheet is part of:
+PyOpenOffice Version 0.4
+Copyright (C) 2005: Martin Simon
+Homepage: www.bezirksreiter.de
+
+GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
+-->
+
+</xsl:stylesheet>
+
+
diff --git a/addons/base_report_designer/openerp_sxw2rml/office.dtd b/addons/base_report_designer/openerp_sxw2rml/office.dtd
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py b/addons/base_report_designer/openerp_sxw2rml/openerp_sxw2rml.py
new file mode 100644 (file)
index 0000000..c51602c
--- /dev/null
@@ -0,0 +1,361 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c):
+#
+#     2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
+#     2005 Fabien Pinckaers, TINY SPRL. (http://tiny.be)
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+#!/usr/bin/python
+"""
+OpenERP SXW2RML - The OpenERP's report engine
+
+OpenERP SXW2RML is part of the OpenERP Report Project.
+OpenERP Report is a module that allows you to render high quality PDF document
+from an OpenOffice template (.sxw) and any relationnal database.
+"""
+__version__ = '0.9'
+
+
+import re
+import string
+import os
+import zipfile
+import xml.dom.minidom
+from reportlab.lib.units import toLength
+import base64
+import copy
+
+class DomApiGeneral:
+    """General DOM API utilities."""
+    def __init__(self,content_string="",file=""):
+        self.content_string = content_string
+        self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)")
+
+    def _unitTuple(self,string):
+        """Split values and units to a tuple."""
+        temp = self.re_digits.findall(string)
+        if not temp:
+            return (string,"")
+        else:
+            return (temp[0])
+
+    def stringPercentToFloat(self,string):
+        temp = string.replace("""%""","")
+        return float(temp)/100
+
+    def findChildrenByName(self,parent,name,attr_dict={}):
+        """Helper functions. Does not work recursively.
+        Optional: also test for certain attribute/value pairs."""
+        children = []
+        for c in parent.childNodes:
+            if c.nodeType == c.ELEMENT_NODE and c.nodeName == name:
+                children.append(c)
+        if attr_dict == {}:
+            return children
+        else:
+            return self._selectForAttributes(nodelist=children,attr_dict=attr_dict)
+
+    def _selectForAttributes(self,nodelist,attr_dict):
+        "Helper function."""
+        selected_nodes = []
+        for n in nodelist:
+            check = 1
+            for a in attr_dict.keys():
+                if n.getAttribute(a) != attr_dict[a]:
+                    # at least one incorrect attribute value?
+                    check = 0
+            if check:
+                selected_nodes.append(n)
+        return selected_nodes
+
+    def _stringToTuple(self,s):
+        """Helper function."""
+        try:
+            temp = string.split(s,",")
+            return int(temp[0]),int(temp[1])
+        except:
+            return None
+
+    def _tupleToString(self,t):
+        try:
+            return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1]))
+        except:
+            return None
+
+    def _lengthToFloat(self,value):
+        v = value
+        if not self.re_digits.search(v):
+            return v
+        try:
+            if v[-4:] == "inch":
+                # OO files use "inch" instead of "in" in Reportlab units
+                v = v[:-2]
+        except:
+            pass
+        try:
+            c = round(toLength(v))
+            return c
+        except:
+            return v
+
+    def openOfficeStringUtf8(self,string):
+        if type(string) == unicode:
+            return string.encode("utf-8")
+        tempstring = unicode(string,"cp1252").encode("utf-8")
+        return tempstring
+
+class DomApi(DomApiGeneral):
+    """This class provides a DOM-API for XML-Files from an SXW-Archive."""
+    def __init__(self,xml_content,xml_styles):
+        DomApiGeneral.__init__(self)
+        self.content_dom = xml.dom.minidom.parseString(xml_content)
+        self.styles_dom = xml.dom.minidom.parseString(xml_styles)
+        body = self.content_dom.getElementsByTagName("office:body")
+        self.body = body and body[0]
+
+        # TODO:
+        self.style_dict = {}
+        self.style_properties_dict = {}
+
+        # ******** always use the following order:
+        self.buildStyleDict()
+        self.buildStylePropertiesDict()
+        if self.styles_dom.getElementsByTagName("style:page-master").__len__()<>0:
+            self.page_master = self.styles_dom.getElementsByTagName("style:page-master")[0]
+        if  self.styles_dom.getElementsByTagName("style:page-layout").__len__()<>0 :
+                       self.page_master = self.styles_dom.getElementsByTagName("style:page-layout")[0]        
+        self.document = self.content_dom.getElementsByTagName("office:document-content")[0]
+
+    def buildStylePropertiesDict(self):
+        for s in self.style_dict.keys():
+            self.style_properties_dict[s] = self.getStylePropertiesDict(s)
+
+    def updateWithPercents(self,dict,updatedict):
+        """Sometimes you find values like "115%" in the style hierarchy."""
+        if not updatedict:
+            # no style hierarchies for this style? =>
+            return
+        new_updatedict = copy.copy(updatedict)
+        for u in new_updatedict.keys():
+            try:
+                if new_updatedict[u].find("""%""") != -1 and dict.has_key(u):
+                    number = float(self.re_digits.search(dict[u]).group(1))
+                    unit = self.re_digits.search(dict[u]).group(2)
+                    new_number = self.stringPercentToFloat(new_updatedict[u]) * number
+                    if unit == "pt":
+                        new_number = int(new_number)
+                        # no floats allowed for "pt"
+                        # OOo just takes the int, does not round (try it out!)
+                    new_updatedict[u] = "%s%s" % (new_number,unit)
+                else:
+                    dict[u] = new_updatedict[u]
+            except:
+                dict[u] = new_updatedict[u]
+        dict.update(new_updatedict)
+
+    def normalizeStyleProperties(self):
+        """Transfer all style:style-properties attributes from the
+        self.style_properties_hierarchical dict to the automatic-styles
+        from content.xml. Use this function to preprocess content.xml for
+        XSLT transformations etc.Do not try to implement this function
+        with XSlT - believe me, it's a terrible task..."""
+        styles_styles = self.styles_dom.getElementsByTagName("style:style")
+        automatic_styles = self.content_dom.getElementsByTagName("office:automatic-styles")[0]
+        for s in styles_styles:
+            automatic_styles.appendChild(s.cloneNode(deep=1))
+        content_styles = self.content_dom.getElementsByTagName("style:style")
+        # these are the content_styles with styles_styles added!!!
+        for s in content_styles:
+            c = self.findChildrenByName(s,"style:properties")
+            if c == []:
+                # some derived automatic styles do not have "style:properties":
+                temp = self.content_dom.createElement("style:properties")
+                s.appendChild(temp)
+                c = self.findChildrenByName(s,"style:properties")
+            c = c[0]
+            dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("utf-8")] or {}
+            for attribute in dict.keys():
+                c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
+
+    def transferStylesXml(self):
+        """Transfer certain sub-trees from styles.xml to the normalized content.xml
+        (see above). It is not necessary to do this - for example - with paragraph styles.
+        the "normalized" style properties contain all information needed for
+        further processing."""
+        # TODO: What about table styles etc.?
+        outline_styles = self.styles_dom.getElementsByTagName("text:outline-style")
+        t = self.content_dom.createElement("transferredfromstylesxml")
+        self.document.insertBefore(t,self.body)
+        t_new = self.body.previousSibling
+        try:
+            page_master = self.page_master
+            t_new.appendChild(page_master.cloneNode(deep=1))
+            t_new.appendChild(outline_styles[0].cloneNode(deep=1))
+        except:
+            pass
+
+    def normalizeLength(self):
+        """Normalize all lengthes to floats (i.e: 1 inch = 72).
+        Always use this after "normalizeContent" and "transferStyles"!"""
+        # TODO: The complex attributes of table cell styles are not transferred yet.
+        #all_styles = self.content_dom.getElementsByTagName("style:properties")
+        #all_styles += self.content_dom.getElementsByTagName("draw:image")
+        all_styles = self.content_dom.getElementsByTagName("*")
+        for s in all_styles:
+            for x in s._attrs.keys():
+                v = s.getAttribute(x)
+                s.setAttribute(x,"%s" % self._lengthToFloat(v))
+                # convert float to string first!
+
+    def normalizeTableColumns(self):
+        """Handle this strange table:number-columns-repeated attribute."""
+        columns = self.content_dom.getElementsByTagName("table:table-column")
+        for c in columns:
+            if c.hasAttribute("table:number-columns-repeated"):
+                number = int(c.getAttribute("table:number-columns-repeated"))
+                c.removeAttribute("table:number-columns-repeated")
+                for i in range(number-1):
+                    (c.parentNode).insertBefore(c.cloneNode(deep=1),c)
+
+    def buildStyleDict(self):
+        """Store all style:style-nodes from content.xml and styles.xml in self.style_dict.
+        Caution: in this dict the nodes from two dom apis are merged!"""
+        for st in (self.styles_dom,self.content_dom):
+            for s in st.getElementsByTagName("style:style"):
+                name = s.getAttribute("style:name").encode("utf-8")
+                self.style_dict[name] = s
+        return True
+
+    def toxml(self):
+        return self.content_dom.toxml(encoding="utf-8")
+
+    def getStylePropertiesDict(self,style_name):
+        res = {}
+
+        if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
+            parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("utf-8")
+            res = self.getStylePropertiesDict(parent)
+
+        childs = self.style_dict[style_name].childNodes
+        for c in childs:
+            if c.nodeType == c.ELEMENT_NODE and c.nodeName.find("properties")>0 :
+                for attr in c._attrs.keys():
+                    res[attr] = c.getAttribute(attr).encode("utf-8")
+        return res
+
+class PyOpenOffice(object):
+    """This is the main class which provides all functionality."""
+    def __init__(self, path='.', save_pict=False):
+        self.path = path
+        self.save_pict = save_pict
+        self.images = {}
+
+    def oo_read(self,fname):
+        z = zipfile.ZipFile(fname,"r")
+        content = z.read('content.xml')
+        style = z.read('styles.xml')
+        all = z.namelist()
+        for a in all:
+            if a[:9]=='Pictures/' and len(a)>10:
+                pic_content = z.read(a)
+                self.images[a[9:]] = pic_content
+                if self.save_pict:
+                    f=open(os.path.join(self.path, os.path.basename(a)),"wb")
+                    f.write(pic_content)
+                    f.close()
+        z.close()
+        return content,style
+
+    def oo_replace(self,content):
+        regex = [
+            (r"<para[^>]*/>", ""),
+            (r"<para(.*)>(.*?)<text:line-break[^>]*/>", "<para$1>$2</para><para$1>"),
+        ]
+        for key,val in regex:
+            content = re.sub(key, val, content)
+        return content
+
+    def unpackNormalize(self,sourcefile):
+        c,s = self.oo_read(sourcefile)
+        c = self.oo_replace(c)
+        dom = DomApi(c,s)
+        dom.normalizeStyleProperties()
+        dom.transferStylesXml()
+        dom.normalizeLength()
+        dom.normalizeTableColumns()
+        new_c = dom.toxml()
+        return new_c
+
+def sxw2rml(sxw_file, xsl, output='.', save_pict=False):
+    from lxml import etree
+    from StringIO import StringIO
+
+    tool = PyOpenOffice(output, save_pict = save_pict)
+    res = tool.unpackNormalize(sxw_file)
+    
+    f = StringIO(xsl)
+    styledoc = etree.parse(f)
+    style = etree.XSLT(styledoc)
+    
+    f = StringIO(res)
+    doc = etree.parse(f)
+    result = style(doc)
+    root = etree.XPathEvaluator(result)("/document/stylesheet")
+    
+    if root:
+        root=root[0]
+        images = etree.Element("images")
+        for img in tool.images:
+            node = etree.Element('image', name=img)
+            node.text = base64.encodestring(tool.images[img])
+            images.append(node)
+        root.append(images)
+
+    try:
+        xml = str(result)
+        return xml
+    except:
+        return result
+
+if __name__ == "__main__":
+    import optparse
+    parser = optparse.OptionParser(
+        version="OpenERP Report v%s" % __version__,
+        usage = 'openerp_sxw2rml.py [options] file.sxw')
+    parser.add_option("-v", "--verbose", default=False, dest="verbose", help="enable basic debugging")
+    parser.add_option("-o", "--output", dest="output", default='.', help="directory of image output")
+    (opt, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.error("incorrect number of arguments")
+
+    import sys
+    import StringIO
+
+    fname = sys.argv[1]
+    f = fname
+    xsl_file = 'normalized_oo2rml.xsl'
+    z = zipfile.ZipFile(fname,"r")
+    mimetype = z.read('mimetype')
+    if mimetype.split('/')[-1] == 'vnd.oasis.opendocument.text' :
+               xsl_file = 'normalized_odt2rml.xsl'
+    xsl = file(os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), xsl_file)).read()
+    result = sxw2rml(f, xsl, output=opt.output, save_pict=False)
+
+    print result
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer.zip b/addons/base_report_designer/plugin/openerp_report_designer.zip
new file mode 100644 (file)
index 0000000..22c0b77
Binary files /dev/null and b/addons/base_report_designer/plugin/openerp_report_designer.zip differ
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/README b/addons/base_report_designer/plugin/openerp_report_designer/README
new file mode 100644 (file)
index 0000000..41e0273
--- /dev/null
@@ -0,0 +1,40 @@
+About OpenERP Report Designer Plugin
+===================================================================
+OpenERP Report Desinger Plugin is a Package of OpenOffice Writer.
+Using this Plugin , we can modify existing OpenERP Reports and also we can make new nice OpenERP Reports.
+
+
+How to Install OpenERP Report Designer Plugin into Openoffice 3.2 in Linux?
+=====================================================================
+- In Openoffice writer, Open Extension Manager window from Tools > Extension Menu
+
+- Click on "Add" button and select path where the openerp_report_designer.zip is located.
+
+- On the completion of adding package you will get your package
+  under 'Extension Manager' and the status of your package become 'Enabled'
+
+- Close openoffice writer.
+
+- Restart openoffice writer, Now you will find one new menu "OpenERP Report Designer" in Menubar.
+
+
+How to install the plugin with OpenOffice 2.4 on Windows
+========================================================
+
+If you get an error for the installation of the plugin, edit the pythonloader.py file
+in $(OPEN_OFFICE_DIR)\program\ and change the value of DEBUG to None.
+
+If you get an error for the uno.exe in window then just close the Quick starter
+       Openoffice.2.4.1 Too\Option\Openoffic.org in that select the Memory
+       in that Openoffice.org.QuickStarter
+       if checked mark is there then just remove it..
+
+If you are using OpenOffice 3.0 and install the Report Desinger with make all
+       command then change  path in makefile
+
+       sh /opt/openoffice.org3/program/unopkg add or remove both
+
+       And for previous version of Openoffice used
+
+       sh /usr/lib/openoffice/program/unopkg add -v $(ZIP_FILE)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/Makefile b/addons/base_report_designer/plugin/openerp_report_designer/bin/Makefile
new file mode 100755 (executable)
index 0000000..d3a5580
--- /dev/null
@@ -0,0 +1,42 @@
+ZIP_FILE=../../openerp_report_designer.zip
+
+all: pack uninstall install
+
+create:
+       cat script/import \
+           script/lib/actions.py \
+           script/lib/error.py \
+           script/lib/functions.py \
+           script/lib/gui.py \
+           script/lib/tools.py \
+           script/lib/logreport.py\
+           script/lib/rpc.py\
+           script/lib/tiny_socket.py\
+           script/Repeatln.py \
+           script/Fields.py \
+           script/Expression.py \
+           script/modify.py \
+           script/ServerParameter.py \
+           script/Change.py \
+           script/NewReport.py \
+           script/LoginTest.py \
+           script/ModifyExistingReport.py \
+           script/SendToServer.py \
+           script/About.py \
+           script/ConvertBracesToField.py \
+           script/ConvertFieldsToBraces.py \
+           script/ExportToRML.py \
+           script/Translation.py \
+           script/AddAttachment.py > package/OpenERPReport.py
+
+pack: clean create
+       zip $(ZIP_FILE) `find package/ | grep -v svn` 
+       
+install:
+       sh /opt/openoffice.org3/program/unopkg add -v $(ZIP_FILE)
+       
+uninstall:
+       sh /opt/openoffice.org3/program/unopkg remove -v  $(ZIP_FILE)
+
+clean:
+       rm -f $(ZIP_FILE)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/OOo_run.sh b/addons/base_report_designer/plugin/openerp_report_designer/bin/OOo_run.sh
new file mode 100755 (executable)
index 0000000..a22ff96
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+ooffice "-accept=socket,host=localhost,port=2002;urp;"
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/package/Addons.xcu b/addons/base_report_designer/plugin/openerp_report_designer/bin/package/Addons.xcu
new file mode 100644 (file)
index 0000000..121c49a
--- /dev/null
@@ -0,0 +1,636 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<oor:component-data xmlns:oor="http://openoffice.org/2001/registry"
+    xmlns:xs="http://www.w3.org/2001/XMLSchema"
+    oor:name="Addons" oor:package="org.openoffice.Office">
+    <node oor:name="AddonUI">
+        <node oor:name="OfficeMenuBar">
+            <node oor:name="org.openoffice.openerp.report" oor:op="replace">
+                <prop oor:name="Title" oor:type="xs:string">
+                    <value/>
+                    <value xml:lang="en-US">OpenERP Report Designer</value>
+                    <value xml:lang="fr_FR">OpenERP Rapport Designer</value>
+                </prop>
+                <prop oor:name="Target" oor:type="xs:string">
+                    <value>_self</value>
+                </prop>
+                <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                    <value/>
+                </prop>
+                <node oor:name="Submenu">
+                    <node oor:name="m11" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.serverparam?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Server parameters</value>
+                            <value xml:lang="fr_FR">Paramètres serveur</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m12" oor:op="replace">
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>private:separator</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m21" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.repeatln?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Add a loop</value>
+                           <value xml:lang="fr_FR"> Ajouter une boucle</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m22" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.fields?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Add a field</value>
+                            <value xml:lang="fr_FR">Ajouter un champ</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+
+                    <node oor:name="m23" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.expression?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Add an expression</value>
+                            <value xml:lang="fr_FR">Ajouter une expression</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+
+                    <node oor:name="m24" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.langtag?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Add a lang tag</value>
+                            <value xml:lang="fr_FR">Ajouter un tag lang</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m25" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.modify?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Modify</value>
+                            <value xml:lang="fr_FR">Modifier</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m26" oor:op="replace">
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>private:separator</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m31" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.convertFB?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Conversion Fields -> Brackets</value>
+                            <value xml:lang="fr_FR">Conversion champs -> crochets</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m32" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.convertBF?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Conversion Brackets -> Fields</value>
+                            <value xml:lang="fr_FR">Conversion crochets -> champs</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m33" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.exporttorml?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Export to RML</value>
+                            <value xml:lang="fr_FR">Exporter en RML</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m34" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.addattachment?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Add Attachment</value>
+                            <value xml:lang="fr_FR">Envoyer comme attachement</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m35" oor:op="replace">
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>private:separator</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m41" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.sendtoserver?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Send to the server</value>
+                            <value xml:lang="fr_FR">Envoyer au serveur</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m42" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.opennewreport?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Open a new report</value>
+                            <value xml:lang="fr_FR">Nouveau rapport</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m43" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.modifyreport?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">Modify Existing Report</value>
+                            <value xml:lang="fr_FR">Modifier un rapport</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m45" oor:op="replace">
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>private:separator</value>
+                        </prop>
+                    </node>
+                    <node oor:name="m51" oor:op="replace">
+                        <prop oor:name="URL" oor:type="xs:string">
+                            <value>service:org.openoffice.openerp.report.about?execute</value>
+                        </prop>
+                        <prop oor:name="Title" oor:type="xs:string">
+                            <value/>
+                            <value xml:lang="en-US">About</value>
+                            <value xml:lang="fr_FR">À propos de</value>
+                        </prop>
+                        <prop oor:name="Target" oor:type="xs:string">
+                            <value>_self</value>
+                        </prop>
+                        <prop oor:name="Context" oor:type="xs:string">
+                            <value>com.sun.star.text.TextDocument</value>
+                        </prop>
+                    </node>
+                </node>
+            </node>
+        </node>
+
+        <node oor:name="OfficeToolBar">
+            <node oor:name="org.openoffice.openerp.report" oor:op="replace">
+                <node oor:name="m11" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.serverparam?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Server parameters</value>
+                        <value xml:lang="fr_FR">Paramètres serveur</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+
+
+                <node oor:name="m12" oor:op="replace">
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>private:separator</value>
+                    </prop>
+                </node>
+                <node oor:name="m21" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.repeatln?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Add a loop</value>
+                        <value xml:lang="fr_FR">Ajouter une boucle</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m22" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.fields?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Add a field</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+
+                <node oor:name="m23" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.expression?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Add an expression</value>
+                        <value xml:lang="fr_FR">Ajouter une expression</value>>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m24" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.langtag?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Add a lang tag</value>
+                        <value xml:lang="fr_FR">Ajouter un tag lang</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m25" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.modify?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Modify</value>
+                        <value xml:lang="fr_FR">Modifier</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m26" oor:op="replace">
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>private:separator</value>
+                    </prop>
+                </node>
+                <node oor:name="m31" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.convertFB?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Conversion Fields -> Brackets</value>
+                        <value xml:lang="fr_FR">Domaines de conversion -> Supports</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m32" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.convertBF?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Conversion Brackets -> Fields</value>
+                        <value xml:lang="fr_FR">Supports de conversion -> Domaines</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m33" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.exporttorml?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">Export to RML</value>
+                        <value xml:lang="fr_FR">RML Ã  l'exportation</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+                <node oor:name="m45" oor:op="replace">
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>private:separator</value>
+                    </prop>
+                </node>
+                <node oor:name="m51" oor:op="replace">
+                    <prop oor:name="URL" oor:type="xs:string">
+                        <value>service:org.openoffice.openerp.report.about?execute</value>
+                    </prop>
+                    <prop oor:name="ImageIdentifier" oor:type="xs:string">
+                        <value/>
+                    </prop>
+                    <prop oor:name="Title" oor:type="xs:string">
+                        <value/>
+                        <value xml:lang="en-US">About</value>
+                        <value xml:lang="fr_FR">À propos de</value>
+                    </prop>
+                    <prop oor:name="Target" oor:type="xs:string">
+                        <value>_self</value>
+                    </prop>
+                    <prop oor:name="Context" oor:type="xs:string">
+                        <value>com.sun.star.text.TextDocument</value>
+                    </prop>
+                </node>
+            </node>
+        </node>
+        <node oor:name="Images">
+            <node oor:name="org.openoffice.openerp.report.image1" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.expression?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/expression_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/expression_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image2" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.repeatln?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/loop_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/loop_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image3" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.fields?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/field_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/field_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image4" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.exporttorml?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/export_rml_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/export_rml_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image5" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.convertFB?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/convetFtoB_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/convetFtoB_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image6" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.convertBF?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/convetBtoF_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/convetBtoF_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image7" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.modify?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/modify_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string">
+                        <value>%origin%/images/modify_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image8" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.serverparam?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/logo_1.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string" oor:width="100">
+                        <value>%origin%/images/logo_s.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image9" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.about?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/aboutus_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string" oor:width="100">
+                        <value>%origin%/images/aboutus_b.png</value>
+                    </prop>
+                </node>
+            </node>
+            <node oor:name="org.openoffice.openerp.report.image10" oor:op="replace">
+                <prop oor:name="URL">
+                    <value>service:org.openoffice.openerp.report.langtag?execute</value>
+                </prop>
+                <node oor:name="UserDefinedImages">
+                    <prop oor:name="ImageSmallURL" oor:type="xs:string">
+                        <value>%origin%/images/lang_s.png</value>
+                    </prop>
+                    <prop oor:name="ImageBigURL" oor:type="xs:string" oor:width="100">
+                        <value>%origin%/images/lang_b.png</value>
+                    </prop>
+                </node>
+            </node>
+        </node>
+
+    </node>
+</oor:component-data>
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/About.py
new file mode 100644 (file)
index 0000000..319a1d6
--- /dev/null
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+from com.sun.star.task import XJobExecutor
+
+if __name__<>'package':
+    from lib.gui import *
+
+class About(unohelper.Base, XJobExecutor):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        self.win = DBModalDialog(60, 50, 175, 115, "About OpenERP Report Designer")
+
+        fdBigFont = createUnoStruct("com.sun.star.awt.FontDescriptor")
+        fdBigFont.Width = 20
+        fdBigFont.Height = 25
+        fdBigFont.Weight = 120
+        fdBigFont.Family= 3
+
+        oLabelTitle1 = self.win.addFixedText("lblTitle1", 1, 1, 35, 30)
+        oLabelTitle1.Model.TextColor = 16056320
+        oLabelTitle1.Model.FontDescriptor = fdBigFont
+        oLabelTitle1.Model.FontRelief = 1
+        oLabelTitle1.Text = "Open"
+
+        oLabelTitle2 = self.win.addFixedText("lblTitle2", 35, 1, 30, 30)
+        oLabelTitle2.Model.TextColor = 1
+        oLabelTitle2.Model.FontDescriptor = fdBigFont
+        oLabelTitle2.Model.FontRelief = 1
+        oLabelTitle2.Text = "ERP"
+
+        oLabelProdDesc = self.win.addFixedText("lblProdDesc", 1, 30, 173, 75)
+        oLabelProdDesc.Model.TextColor = 1
+        fdBigFont.Width = 10
+        fdBigFont.Height = 11
+        fdBigFont.Weight = 76
+        oLabelProdDesc.Model.FontDescriptor = fdBigFont
+        oLabelProdDesc.Model.Align = 1
+        oLabelProdDesc.Model.FontRelief = 1
+        oLabelProdDesc.Model.MultiLine = True
+        oLabelProdDesc.Text = "This  package  helps  you  to  create  or  modify\nreports  in  OpenERP.  Once  connected  to  the\nserver, you can design your template of reports\nusing fields  and expressions  and  browsing the\ncomplete structure of OpenERP object database."
+
+        oLabelFooter = self.win.addFixedText("lblFooter", -1, -1, 173, 25)
+        oLabelFooter.Model.TextColor = 255
+        #oLabelFooter.Model.BackgroundColor = 1
+        oLabelFooter.Model.Border = 2
+        oLabelFooter.Model.BorderColor = 255
+        fdBigFont.Width = 8
+        fdBigFont.Height = 9
+        fdBigFont.Weight = 100
+        oLabelFooter.Model.FontDescriptor = fdBigFont
+        oLabelFooter.Model.Align = 1
+        oLabelFooter.Model.FontRelief = 1
+        oLabelFooter.Model.MultiLine = True
+        sMessage = "OpenERP Report Designer v1.0 \nCopyright 2007-TODAY Tiny sprl \nThis product is free software, under the GNU Affero General Public License."
+        oLabelFooter.Text = sMessage
+
+        self.win.doModalDialog("",None)
+
+if __name__<>"package" and __name__=="__main__":
+    About(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( About, "org.openoffice.openerp.report.about", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/AddAttachment.py
new file mode 100644 (file)
index 0000000..d42cb46
--- /dev/null
@@ -0,0 +1,277 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import os
+import uno
+import unohelper
+import xmlrpclib
+import base64
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.error import ErrorDialog
+    from lib.tools import *
+    from LoginTest import *
+    from lib.rpc import *
+    database="test"
+    uid = 3
+
+class AddAttachment(unohelper.Base, XJobExecutor ):
+    Kind = {
+        'PDF' : 'pdf',
+        'OpenOffice': 'sxw',
+    }
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        self.aSearchResult = []
+        desktop=getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo=oDoc2.getDocumentInfo()
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        if docinfo.getUserFieldValue(2) <> "" and docinfo.getUserFieldValue(3) <> "":
+            self.win = DBModalDialog(60, 50, 180, 70, "Add Attachment to Server")
+            self.win.addFixedText("lblResourceType", 2 , 5, 100, 10, "Select Appropriate Resource Type:")
+            self.win.addComboListBox("lstResourceType", -2, 25, 176, 15,True)
+            self.win.addButton('btnOkWithoutInformation', -2 , -5, 25 , 15,'OK' ,actionListenerProc = self.btnOkWithoutInformation_clicked )
+        else:
+            self.win = DBModalDialog(60, 50, 180, 190, "Add Attachment to Server")
+            self.win.addFixedText("lblModuleName",2 , 9, 42, 20, "Select Module:")
+            self.win.addComboListBox("lstmodel", -2, 5, 134, 15,True)
+            self.lstModel = self.win.getControl( "lstmodel" )
+            self.dModel = {}
+
+            # Open a new connexion to the server
+
+            ids = self.sock.execute(database, uid, self.password, 'ir.module.module', 'search', [('name','=','base_report_model'),('state', '=', 'installed')])
+            if not len(ids):
+                # If the module 'base_report_model' is not installed, use the default model
+                self.dModel = {
+                    "Partner":'res.partner',
+                }
+            else:
+
+                ids =self.sock.execute(database, uid, self.password, 'base.report.model' , 'search', [])
+                res = self.sock.execute(database, uid, self.password, 'base.report.model' , 'read', ids, ['name','model_id'])
+                models = self.sock.execute(database, uid, self.password, 'ir.model' , 'read', map(lambda x:x['model_id'][0], res), ['model'])
+                models = dict(map(lambda x:(x['id'],x['model']), models))
+                self.dModel = dict(map(lambda x: (x['name'],models[x['model_id'][0]]), res))
+
+            for item in self.dModel.keys():
+                self.lstModel.addItem(item, self.lstModel.getItemCount())
+
+            self.win.addFixedText("lblSearchName",2 , 25, 60, 10, "Enter Search String:")
+            self.win.addEdit("txtSearchName", 2, 35, 149, 15,)
+            self.win.addButton('btnSearch', -2 , 35, 25 , 15,'Search' ,actionListenerProc = self.btnSearch_clicked )
+
+            self.win.addFixedText("lblSearchRecord", 2 , 55, 60, 10, "Search Result:")
+            self.win.addComboListBox("lstResource", -2, 65, 176, 70, False )
+            self.lstResource = self.win.getControl( "lstResource" )
+
+            self.win.addFixedText("lblResourceType", 2 , 137, 100, 20, "Select Appropriate Resource Type:")
+            self.win.addComboListBox("lstResourceType", -2, 147, 176, 15,True )
+
+            self.win.addButton('btnOkWithInformation', -2 , -5, 25 , 15,'OK' ,actionListenerProc = self.btnOkWithInformation_clicked )
+
+        self.lstResourceType = self.win.getControl( "lstResourceType" )
+        for kind in self.Kind.keys():
+            self.lstResourceType.addItem( kind, self.lstResourceType.getItemCount() )
+
+        self.win.addButton('btnCancel', -2 - 27 , -5 , 30 , 15, 'Cancel' ,actionListenerProc = self.btnCancel_clicked )
+        self.win.doModalDialog("lstResourceType", self.Kind.keys()[0])
+
+    def btnSearch_clicked( self, oActionEvent ):
+        modelSelectedItem = self.win.getListBoxSelectedItem("lstmodel")
+        if modelSelectedItem == "":
+            return
+
+        desktop=getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo=oDoc2.getDocumentInfo()
+
+
+        self.aSearchResult =self.sock.execute( database, uid, self.password, self.dModel[modelSelectedItem], 'name_search', self.win.getEditText("txtSearchName"))
+        self.win.removeListBoxItems("lstResource", 0, self.win.getListBoxItemCount("lstResource"))
+        if self.aSearchResult == []:
+            ErrorDialog("No search result found !!!", "", "Search ERROR" )
+            return
+
+        for result in self.aSearchResult:
+            self.lstResource.addItem(result[1],result[0])
+
+    def _send_attachment( self, name, data, res_model, res_id ):
+        desktop = getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo = oDoc2.getDocumentInfo()
+
+        params = {
+            'name': name,
+            'datas': base64.encodestring( data ),
+            'datas_fname': name,
+            'res_model' : res_model,
+            'res_id' : int(res_id),
+        }
+
+        return self.sock.execute( database, uid, self.password, 'ir.attachment', 'create', params )
+
+    def send_attachment( self, model, resource_id ):
+        desktop = getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo = oDoc2.getDocumentInfo()
+
+        if oDoc2.getURL() == "":
+            ErrorDialog("Please save your file", "", "Saving ERROR" )
+            return None
+
+        url = oDoc2.getURL()
+        if self.Kind[self.win.getListBoxSelectedItem("lstResourceType")] == "pdf":
+            url = self.doc2pdf(url[7:])
+
+        if url == None:
+            ErrorDialog( "Ploblem in creating PDF", "", "PDF Error" )
+            return None
+
+        url = url[7:]
+        data = read_data_from_file( get_absolute_file_path( url ) )
+        return self._send_attachment( os.path.basename( url ), data, model, resource_id )
+
+    def btnOkWithoutInformation_clicked( self, oActionEvent ):
+        desktop = getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo = oDoc2.getDocumentInfo()
+
+        if self.win.getListBoxSelectedItem("lstResourceType") == "":
+            ErrorDialog("Please select resource type", "", "Selection ERROR" )
+            return
+
+        res = self.send_attachment( docinfo.getUserFieldValue(3), docinfo.getUserFieldValue(2) )
+        self.win.endExecute()
+
+    def btnOkWithInformation_clicked(self,oActionEvent):
+        if self.win.getListBoxSelectedItem("lstResourceType") == "":
+            ErrorDialog( "Please select resource type", "", "Selection ERROR" )
+            return
+
+        if self.win.getListBoxSelectedItem("lstResource") == "" or self.win.getListBoxSelectedItem("lstmodel") == "":
+            ErrorDialog("Please select Model and Resource","","Selection ERROR")
+            return
+
+        resourceid = None
+        for s in self.aSearchResult:
+            if s[1] == self.win.getListBoxSelectedItem("lstResource"):
+                resourceid = s[0]
+                break
+
+        if resourceid == None:
+            ErrorDialog("No resource selected !!!", "", "Resource ERROR" )
+            return
+
+        res = self.send_attachment( self.dModel[self.win.getListBoxSelectedItem('lstmodel')], resourceid )
+        self.win.endExecute()
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+    def doc2pdf(self, strFile):
+        oDoc = None
+        strFilterSubName = ''
+
+        strUrl = convertToURL( strFile )
+        desktop = getDesktop()
+        oDoc = desktop.loadComponentFromURL( strUrl, "_blank", 0, Array(self._MakePropertyValue("Hidden",True)))
+        if oDoc:
+            strFilterSubName = ""
+            # select appropriate filter
+            if oDoc.supportsService("com.sun.star.presentation.PresentationDocument"):
+                strFilterSubName = "impress_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument"):
+                strFilterSubName = "calc_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.text.WebDocument"):
+                strFilterSubName = "writer_web_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.text.GlobalDocument"):
+                strFilterSubName = "writer_globaldocument_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.text.TextDocument"):
+                strFilterSubName = "writer_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.drawing.DrawingDocument"):
+                strFilterSubName = "draw_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.formula.FormulaProperties"):
+                strFilterSubName = "math_pdf_Export"
+            elif oDoc.supportsService("com.sun.star.chart.ChartDocument"):
+                strFilterSubName = "chart_pdf_Export"
+            else:
+                pass
+
+            filename = len(strFilterSubName) > 0 and convertToURL( os.path.splitext( strFile )[0] + ".pdf" ) or None
+
+            if len(strFilterSubName) > 0:
+                oDoc.storeToURL( filename, Array(self._MakePropertyValue("FilterName", strFilterSubName ),self._MakePropertyValue("CompressMode", "1" )))
+
+            oDoc.close(True)
+            # Can be None if len(strFilterSubName) <= 0
+            return filename
+
+    def _MakePropertyValue(self, cName = "", uValue = u"" ):
+       oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" )
+       if cName:
+          oPropertyValue.Name = cName
+       if uValue:
+          oPropertyValue.Value = uValue
+       return oPropertyValue
+
+
+if __name__<>"package" and __name__=="__main__":
+    AddAttachment(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( AddAttachment, "org.openoffice.openerp.report.addattachment", ("com.sun.star.task.Job",),)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Change.py
new file mode 100644 (file)
index 0000000..7dc26c7
--- /dev/null
@@ -0,0 +1,109 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+if __name__<>"package":
+    from lib.gui import *
+    from lib.functions import *
+    from lib.rpc import *
+
+class Change:
+    def __init__(self, aVal= None, sURL=""):
+        self.win=DBModalDialog(60, 50, 120, 90, "Connect to Open ERP Server")
+
+        self.win.addFixedText("lblVariable", 38, 12, 60, 15, "Server")
+
+        self.win.addEdit("txtHost",-2,9,60,15,sURL[sURL.find("/")+2:sURL.rfind(":")])
+
+        self.win.addFixedText("lblReportName",45 , 31, 60, 15, "Port")
+        self.win.addEdit("txtPort",-2,28,60,15,sURL[sURL.rfind(":")+1:])
+
+        self.win.addFixedText("lblLoginName", 2, 51, 60, 15, "Protocol Connection")
+
+        self.win.addComboListBox("lstProtocol", -2, 48, 60, 15, True)
+        self.lstProtocol = self.win.getControl( "lstProtocol" )
+
+#        self.lstProtocol.addItem( "XML-RPC", 0)
+        #self.lstProtocol.addItem( "XML-RPC secure", 1)
+        #self.lstProtocol.addItem( "NET-RPC (faster)", 2)
+
+        self.win.addButton( 'btnOK', -2, -5, 30, 15, 'Ok', actionListenerProc = self.btnOk_clicked )
+
+        self.win.addButton( 'btnCancel', -2 - 30 - 5 ,-5, 30, 15, 'Cancel', actionListenerProc = self.btnCancel_clicked )
+        self.aVal=aVal
+        self.protocol = {
+            'XML-RPC': 'http://',
+            'XML-RPC secure': 'https://',
+            'NET-RPC': 'socket://',
+        }
+        for i in self.protocol.keys():
+            self.lstProtocol.addItem(i,self.lstProtocol.getItemCount() )
+
+        sValue=self.protocol.keys()[0]
+        if sURL<>"":
+            sValue=self.protocol.keys()[self.protocol.values().index(sURL[:sURL.find("/")+2])]
+
+        self.win.doModalDialog( "lstProtocol", sValue)
+
+    def btnOk_clicked(self,oActionEvent):
+        global url
+        url = self.protocol[self.win.getListBoxSelectedItem("lstProtocol")]+self.win.getEditText("txtHost")+":"+self.win.getEditText("txtPort")
+        self.sock=RPCSession(url)
+        docinfo=doc.getDocumentInfo()        
+        docinfo.setUserFieldValue(0,url)
+        res=self.sock.listdb()
+        if res == -1:
+            self.aVal.append(url)
+        elif res == 0:
+            self.aVal.append("No Database found !!!")
+        else:
+            self.aVal.append(url)
+        self.aVal.append(res)
+        self.win.endExecute()
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertBracesToField.py
new file mode 100644 (file)
index 0000000..d4e8b58
--- /dev/null
@@ -0,0 +1,285 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import uno
+import unohelper
+import string
+import re
+import base64
+
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from LoginTest import *
+    from lib.logreport import *
+    from lib.rpc import *
+    database="test"
+    uid = 1
+
+
+
+class ConvertBracesToField( unohelper.Base, XJobExecutor ):
+
+    def __init__(self,ctx):
+
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        self.logobj=Logger()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        self.aReportSyntex=[]
+        self.getBraces(self.aReportSyntex)
+
+        self.setValue()
+
+
+    def setValue(self):
+
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=  doc.getDocumentInfo()
+        count = 0
+        regexes = [
+            ['[a-zA-Z0-9_]+\.[a-zA-Z0-9_.]+',"Field"],
+            ['\\[\\[ *repeatIn\\( *([a-zA-Z0-9_\.]+), *\'([a-zA-Z0-9_]+)\' *\\) *\\]\\]', "RepeatIn"],
+            ['\\[\\[ *([a-zA-Z0-9_\.]+) *\\]\\]', "Field"]
+            # ['\\[\\[ ([a-zA-Z0-9_]+\.[a-zA-Z1-9]) \\]\\]',"Field"],
+            # ['\\[\\[ [a-zA-Z0-9_\.]+ and ([a-zA-Z0-9_\.]+) or .+? \\]\\]',"Field"],
+            # ['\\[\\[ ([a-zA-Z0-9_\.]+) or .+? \\]\\]',"Field"],
+            # ['\\[\\[ ([a-zA-Z0-9_\.]+) and .+? \\]\\]',"Field"],
+            # ['\\[\\[ .+? or ([a-zA-Z0-9_\.]+) \\]\\]',"Field"],
+            # ['\\[\\[ (.+?) and ([a-zA-Z0-9_\.]+) \\]\\]',"Field"],
+            # ['\\[\\[ .+? % ([a-zA-Z0-9_\.]+) \\]\\]',"Field"]
+        ]
+        oFieldObject = []
+        oRepeatInObjects = []
+        saRepeatInList = []
+        sHost = docinfo.getUserFieldValue(0)
+        nCount = 0
+        oParEnum = doc.getTextFields().createEnumeration()
+        while oParEnum.hasMoreElements():
+            oPar = oParEnum.nextElement()
+            nCount += 1
+        getList(oRepeatInObjects,sHost,nCount)
+        for ro in oRepeatInObjects:
+            if ro.find("(")<>-1:
+                saRepeatInList.append( [ ro[:ro.find("(")], ro[ro.find("(")+1:ro.find(")")] ])
+        try:
+            oParEnum = doc.getTextFields().createEnumeration()
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    for reg in regexes:
+                        res=re.findall(reg[0],oPar.Items[1])
+                        if len(res) <> 0:
+                            if res[0][0] == "objects":
+                                sTemp = docinfo.getUserFieldValue(3)
+                                sTemp = "|-." + sTemp[sTemp.rfind(".")+1:] + ".-|"
+                                oPar.Items=(sTemp.encode("utf-8"),oPar.Items[1].replace(' ',""))
+                                oPar.update()
+                            elif type(res[0]) <> type(u''):
+
+                                sObject = self.getRes(self.sock, docinfo.getUserFieldValue(3), res[0][0][res[0][0].find(".")+1:].replace(".","/"))
+                                r = self.sock.execute(database, uid, self.password, docinfo.getUserFieldValue(3) , 'fields_get')
+                                sExpr="|-." + r[res[0][0][res[0][0].rfind(".")+1:]]["string"] + ".-|"
+                                oPar.Items=(sExpr.encode("utf-8"),oPar.Items[1].replace(' ',""))
+                                oPar.update()
+                            else:
+
+                                obj = None
+                                for rl in saRepeatInList:
+                                    if rl[0] == res[0][:res[0].find(".")]:
+                                        obj=rl[1]
+                                try:
+                                    sObject = self.getRes(self.sock, obj, res[0][res[0].find(".")+1:].replace(".","/"))
+                                    r = self.sock.execute(database, uid, self.password, sObject , 'read',[1])
+                                except Exception,e:
+                                    r = "TTT"
+                                    self.logobj.log_write('ConvertBracesToField', LOG_ERROR, str(e))
+                                if len(r) <> 0:
+                                    if r <> "TTT":
+                                        if len(res)>1:
+                                            sExpr=""
+                                            print res
+                                            if reg[1] == 'Field':
+                                                for ires in res:
+                                                    try:
+                                                        sExpr=r[0][ires[ires.rfind(".")+1:]]
+                                                        break
+                                                    except Exception,e:
+                                                        import traceback,sys
+                                                        info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                                                        self.logobj.log_write('ConvertBracesToField', LOG_ERROR,info)
+                                                try:
+                                                    oPar.Items=(sExpr.encode("utf-8") ,oPar.Items[1])
+                                                    oPar.update()
+                                                except:
+                                                    oPar.Items=(str(sExpr) ,oPar.Items[1])
+                                                    oPar.update()
+                                                    import traceback,sys
+                                                    info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                                                    self.logobj.log_write('ConvertBracesToField', LOG_ERROR, info)
+
+                                        else:
+                                            sExpr=r[0][res[0][res[0].rfind(".")+1:]]
+                                            try:
+
+                                                if sExpr:
+                                                    oPar.Items=(sExpr.encode("utf-8") ,oPar.Items[1])
+                                                    oPar.update()
+                                                else:
+                                                     oPar.Items=(u"/",oPar.Items[1])
+                                                     oPar.update()
+                                            except:
+                                                oPar.Items=(str(sExpr) ,oPar.Items[1])
+                                                oPar.update()
+                                                import traceback,sys
+                                                info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                                                self.logobj.log_write('ConvertBracesToField', LOG_ERROR,info)
+
+                                    else:
+                                        oPar.Items=(u""+r,oPar.Items[1])
+                                        oPar.update()
+                                else:
+                                    oPar.Items=(u"TTT",oPar.Items[1])
+                                    oPar.update()
+        except:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('ConvertBraceToField', LOG_ERROR, info)
+
+    def getRes(self,sock,sObject,sVar):
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        res = sock.execute(database, uid, self.password, sObject , 'fields_get')
+        key = res.keys()
+        key.sort()
+        myval=None
+        if not sVar.find("/")==-1:
+            myval=sVar[:sVar.find("/")]
+        else:
+            myval=sVar
+        for k in key:
+            if (res[k]['type'] in ['many2one']) and k==myval:
+                sObject = self.getRes(sock,res[myval]['relation'], sVar[sVar.find("/")+1:])
+        return sObject
+
+    def getBraces(self,aReportSyntex=[]):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        aSearchString=[]
+        aReplaceString=[]
+        aRes=[]
+
+        try:
+            regexes = [
+                ['\\[\\[ *repeatIn\\( *([a-zA-Z0-9_\.]+), *\'([a-zA-Z0-9_]+)\' *\\) *\\]\\]', "RepeatIn"],
+                ['\\[\\[ *([a-zA-Z0-9_\.]+) *\\]\\]', "Field"],
+                ['\\[\\[ *.+? *\\]\\]', "Expression"]
+            ]
+
+            search = doc.createSearchDescriptor()
+            search.SearchRegularExpression = True
+
+            for reg in regexes:
+                search.SearchString = reg[0]
+                found = doc.findFirst( search )
+                while found:
+                    res=re.findall(reg[0],found.String)
+                    print len(res)
+
+                    if found.String not in [r[0] for r in aReportSyntex] and len(res) == 1 :
+                        text=found.getText()
+                        oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+                        if reg[1]<>"Expression":
+                            oInputList.Items=(u""+found.String,u""+found.String)
+                        else:
+                            oInputList.Items=(u"?",u""+found.String)
+                        aReportSyntex.append([oInputList,reg[1]])
+                        text.insertTextContent(found,oInputList,False)
+                        found.String =""
+
+                    else:
+                        aRes.append([res,reg[1]])
+                        found = doc.findNext(found.End, search)
+            search = doc.createSearchDescriptor()
+            search.SearchRegularExpression = False
+
+            for res in aRes:
+                for r in res[0]:
+                    search.SearchString=r
+                    found=doc.findFirst(search)
+                    while found:
+
+                        text=found.getText()
+
+                        oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+                        if res[1]<>"Expression":
+                            oInputList.Items=(u""+found.String,u""+found.String)
+                        else:
+                            oInputList.Items=(u"?",u""+found.String)
+                        aReportSyntex.append([oInputList,res[1]])
+                        text.insertTextContent(found,oInputList,False)
+                        found.String =""
+                        found = doc.findNext(found.End, search)
+        except:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('ConvertBraceToField', LOG_ERROR, info)
+
+if __name__<>"package":
+    ConvertBracesToField(None)
+else:
+    g_ImplementationHelper.addImplementation( ConvertBracesToField, "org.openoffice.openerp.report.convertBF", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ConvertFieldsToBraces.py
new file mode 100644 (file)
index 0000000..05a7944
--- /dev/null
@@ -0,0 +1,85 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import unohelper
+import string
+import re
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from LoginTest import *
+    database="test"
+    uid = 3
+
+class ConvertFieldsToBraces( unohelper.Base, XJobExecutor ):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+        self.aReportSyntex=[]
+        self.getFields()
+
+    def getFields(self):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+
+        oParEnum = doc.getTextFields().createEnumeration()
+        while oParEnum.hasMoreElements():
+            oPar = oParEnum.nextElement()
+            if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                oPar.getAnchor().Text.insertString(oPar.getAnchor(),oPar.Items[1],False)
+                oPar.dispose()
+
+if __name__<>"package":
+    ConvertFieldsToBraces(None)
+else:
+    g_ImplementationHelper.addImplementation( ConvertFieldsToBraces, "org.openoffice.openerp.report.convertFB", ("com.sun.star.task.Job",),) 
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ExportToRML.py
new file mode 100644 (file)
index 0000000..875fe21
--- /dev/null
@@ -0,0 +1,132 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import os
+import uno
+import unohelper
+import string
+import tempfile
+import base64
+import sys
+
+reload(sys)
+sys.setdefaultencoding("utf8")
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from LoginTest import *
+    from lib.error import *
+    from lib.tools import *
+    from lib.logreport import *
+    from lib.rpc import *
+    database="test"
+    uid = 3
+
+
+class ExportToRML( unohelper.Base, XJobExecutor ):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        global url
+        self.sock=RPCSession(url)
+
+        # Read Data from sxw file
+        tmpsxw = tempfile.mktemp('.'+"sxw")
+
+        if not doc.hasLocation():
+            mytype = Array(makePropertyValue("MediaType","application/vnd.sun.xml.writer"),)
+            doc.storeAsURL("file://"+tmpsxw,mytype)
+        data = read_data_from_file( get_absolute_file_path( doc.getURL()[7:] ) )
+        file_type = doc.getURL()[7:].split(".")[-1]
+        if docinfo.getUserFieldValue(2) == "":
+            ErrorDialog("Please Save this file on server","Use Send To Server Option in OpenERP Report Menu","Error")
+            exit(1)
+       filename = self.GetAFileName()
+       if not filename:
+           exit(1)
+        global passwd
+        self.password = passwd
+        try:
+
+            res = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'sxwtorml',base64.encodestring(data),file_type)
+            if res['report_rml_content']:
+                write_data_to_file( get_absolute_file_path( filename[7:] ), res['report_rml_content'] )
+        except Exception,e:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('ExportToRML',LOG_ERROR, info)
+            ErrorDialog("Can't save the file to the hard drive.", "Exception: %s" % e, "Error" )
+
+    def GetAFileName(self):
+        sFilePickerArgs = Array(10)
+        oFileDialog = createUnoService("com.sun.star.ui.dialogs.FilePicker")
+        oFileDialog.initialize(sFilePickerArgs)
+        oFileDialog.appendFilter("OpenERP Report File Save To ....","*.rml")
+
+        f_path = "OpenERP-"+ os.path.basename( tempfile.mktemp("","") ) + ".rml"
+        initPath = tempfile.gettempdir()
+        oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess")
+        if oUcb.exists(initPath):
+           oFileDialog.setDisplayDirectory('file://' + ( os.name == 'nt' and '/' or '' ) + initPath )
+
+        oFileDialog.setDefaultName(f_path )
+
+        sPath = oFileDialog.execute() == 1 and oFileDialog.Files[0] or None
+        oFileDialog.dispose()
+        return sPath
+
+if __name__<>"package" and __name__=="__main__":
+    ExportToRML(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( ExportToRML, "org.openoffice.openerp.report.exporttorml", ("com.sun.star.task.Job",),)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Expression.py
new file mode 100644 (file)
index 0000000..43531d1
--- /dev/null
@@ -0,0 +1,115 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import uno
+import string
+import unohelper
+import xmlrpclib
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.error import ErrorDialog
+    from lib.functions import *
+    database="test"
+    uid = 3
+
+class Expression(unohelper.Base, XJobExecutor ):
+    def __init__(self,sExpression="",sName="", bFromModify=False):
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+        self.win = DBModalDialog(60, 50, 180, 65, "Expression Builder")
+        self.win.addFixedText("lblExpression",17 , 10, 35, 15, "Expression :")
+        self.win.addEdit("txtExpression", -5, 5, 123, 15)
+        self.win.addFixedText("lblName", 2, 30, 50, 15, "Displayed Name :")
+        self.win.addEdit("txtName", -5, 25, 123, 15)
+        self.win.addButton( "btnOK", -5, -5, 40, 15, "OK", actionListenerProc = self.btnOk_clicked )
+        self.win.addButton( "btnCancel", -5 - 40 -5, -5, 40, 15, "Cancel", actionListenerProc = self.btnCancel_clicked )
+        self.bModify=bFromModify
+        if self.bModify==True:
+            self.win.setEditText("txtExpression",sExpression)
+            self.win.setEditText("txtName",sName)
+        self.win.doModalDialog("",None)
+
+
+    def btnOk_clicked( self, oActionEvent ):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        text = doc.Text
+        cursor = doc.getCurrentController().getViewCursor()
+        if self.bModify==True:
+            oCurObj=cursor.TextField
+            sKey=u""+self.win.getEditText("txtName")
+            sValue=u"[[ " + self.win.getEditText("txtExpression") + " ]]"
+            oCurObj.Items = (sKey,sValue)
+            oCurObj.update()
+            self.win.endExecute()
+        else:
+            oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+            if self.win.getEditText("txtName")!="" and self.win.getEditText("txtExpression")!="":
+                sKey=u""+self.win.getEditText("txtName")
+                sValue=u"[[ " + self.win.getEditText("txtExpression") + " ]]"
+                if cursor.TextTable==None:
+                    oInputList.Items = (sKey,sValue)
+                    text.insertTextContent(cursor,oInputList,False)
+                else:
+                    oTable = cursor.TextTable
+                    oCurCell = cursor.Cell
+                    tableText = oTable.getCellByName( oCurCell.CellName )
+                    oInputList.Items = (sKey,sValue)
+                    tableText.insertTextContent(cursor,oInputList,False)
+                self.win.endExecute()
+            else:
+                ErrorDialog("Please Fill appropriate data in Name field or \nExpression field")
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+if __name__<>"package" and __name__=="__main__":
+    Expression()
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( Expression, "org.openoffice.openerp.report.expression", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Fields.py
new file mode 100644 (file)
index 0000000..4e2f408
--- /dev/null
@@ -0,0 +1,291 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+
+import uno
+import string
+import unohelper
+import xmlrpclib
+
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.functions import *
+    from lib.error import ErrorDialog
+    from LoginTest import *
+    from lib.logreport import *
+    from lib.rpc import *
+    database="report"
+    uid = 3
+
+
+class Fields(unohelper.Base, XJobExecutor ):
+    def __init__(self,sVariable="",sFields="",sDisplayName="",bFromModify=False):
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+        self.logobj=Logger()
+        self.win = DBModalDialog(60, 50, 200, 225, "Field Builder")
+
+        self.win.addFixedText("lblVariable", 27, 12, 60, 15, "Variable :")
+        self.win.addComboBox("cmbVariable", 180-120-2, 10, 130, 15,True, itemListenerProc=self.cmbVariable_selected)
+        self.insVariable = self.win.getControl( "cmbVariable" )
+
+        self.win.addFixedText("lblFields", 10, 32, 60, 15, "Variable Fields :")
+        self.win.addComboListBox("lstFields", 180-120-2, 30, 130, 150, False,True,itemListenerProc=self.lstbox_selected)
+        self.insField = self.win.getControl( "lstFields" )
+
+        self.win.addFixedText("lblUName", 8, 187, 60, 15, "Displayed name :")
+        self.win.addEdit("txtUName", 180-120-2, 185, 130, 15,)
+
+        self.win.addButton('btnOK',-5 ,-5,45,15,'Ok' ,actionListenerProc = self.btnOk_clicked )
+        self.win.addButton('btnCancel',-5 - 45 - 5 ,-5,45,15,'Cancel' ,actionListenerProc = self.btnCancel_clicked )
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+
+        self.sValue=None
+        self.sObj=None
+        self.aSectionList=[]
+        self.sGDisplayName=sDisplayName
+        self.aItemList=[]
+        self.aComponentAdd=[]
+        self.aObjectList=[]
+        self.aListFields=[]
+        self.aVariableList=[]
+        EnumDocument(self.aItemList,self.aComponentAdd)
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        self.sMyHost= ""
+
+        if not docinfo.getUserFieldValue(3) == "" and not docinfo.getUserFieldValue(0)=="":
+            self.sMyHost = docinfo.getUserFieldValue(0)
+            self.count = 0
+            oParEnum = doc.getTextFields().createEnumeration()
+
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    self.count += 1
+
+            getList(self.aObjectList, self.sMyHost,self.count)
+            cursor = doc.getCurrentController().getViewCursor()
+            text = cursor.getText()
+            tcur = text.createTextCursorByRange(cursor)
+
+            self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == "Objects", self.aObjectList ) )
+
+            for i in range(len(self.aItemList)):
+                try:
+                    anItem = self.aItemList[i][1]
+                    component = self.aComponentAdd[i]
+
+                    if component == "Document":
+                        sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                        self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                    if tcur.TextSection:
+                        getRecersiveSection(tcur.TextSection,self.aSectionList)
+                        if component in self.aSectionList:
+                            sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                            self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                    if tcur.TextTable:
+                        if not component == "Document" and component[component.rfind(".")+1:] == tcur.TextTable.Name:
+                            VariableScope(tcur, self.aVariableList, self.aObjectList, self.aComponentAdd, self.aItemList, component)
+                except:
+                    import traceback,sys
+                    info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                    self.logobj.log_write('Fields', LOG_ERROR, info)
+
+            self.bModify=bFromModify
+            if self.bModify==True:
+                sItem=""
+                for anObject in self.aObjectList:
+                    if anObject[:anObject.find("(")] == sVariable:
+                        sItem = anObject
+                        self.insVariable.setText(sItem)
+                genTree(
+                    sItem[sItem.find("(")+1:sItem.find(")")],
+                    self.aListFields,
+                    self.insField,
+                    self.sMyHost,
+                    2,
+                    ending_excl=['one2many','many2one','many2many','reference'],
+                    recur=['many2one']
+                )
+                self.sValue= self.win.getListBoxItem("lstFields",self.aListFields.index(sFields))
+            for var in self.aVariableList:
+
+                    self.model_ids =self.sock.execute(database, uid, self.password, 'ir.model' ,  'search', [('model','=',var[var.find("(")+1:var.find(")")])])
+                    fields=['name','model']
+                    self.model_res = self.sock.execute(database, uid, self.password, 'ir.model', 'read', self.model_ids,fields)
+                    if self.model_res <> []:
+                        self.insVariable.addItem(var[:var.find("(")+1] + self.model_res[0]['name'] + ")" ,self.insVariable.getItemCount())
+                    else:
+                        self.insVariable.addItem(var ,self.insVariable.getItemCount())
+
+            self.win.doModalDialog("lstFields",self.sValue)
+        else:
+            ErrorDialog("Please insert user define field Field-1 or Field-4","Just go to File->Properties->User Define \nField-1 Eg. http://localhost:8069 \nOR \nField-4 Eg. account.invoice")
+            self.win.endExecute()
+
+    def lstbox_selected(self,oItemEvent):
+        try:
+
+            desktop=getDesktop()
+            doc =desktop.getCurrentComponent()
+            docinfo=doc.getDocumentInfo()
+            sItem= self.win.getComboBoxText("cmbVariable")
+            for var in self.aVariableList:
+                if var[:var.find("(")+1]==sItem[:sItem.find("(")+1]:
+                    sItem = var
+            sMain=self.aListFields[self.win.getListBoxSelectedItemPos("lstFields")]
+            sObject=self.getRes(self.sock,sItem[sItem.find("(")+1:-1],sMain[1:])
+            ids = self.sock.execute(database, uid, self.password, sObject ,  'search', [])
+            res = self.sock.execute(database, uid, self.password, sObject , 'read',[ids[0]])
+            self.win.setEditText("txtUName",res[0][sMain[sMain.rfind("/")+1:]])
+        except:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('Fields', LOG_ERROR, info)
+            self.win.setEditText("txtUName","TTT")
+        if self.bModify:
+            self.win.setEditText("txtUName",self.sGDisplayName)
+
+    def getRes(self,sock ,sObject,sVar):
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        res = sock.execute(database, uid, self.password, sObject , 'fields_get')
+        key = res.keys()
+        key.sort()
+        myval=None
+        if not sVar.find("/")==-1:
+           myval=sVar[:sVar.find("/")]
+        else:
+            myval=sVar
+        if myval in key:
+            if (res[myval]['type'] in ['many2one']):
+                sObject = res[myval]['relation']
+               return self.getRes(sock,res[myval]['relation'], sVar[sVar.find("/")+1:])
+            else:
+                return sObject
+
+    def cmbVariable_selected(self,oItemEvent):
+        if self.count > 0 :
+            try:
+                desktop=getDesktop()
+                doc =desktop.getCurrentComponent()
+                docinfo=doc.getDocumentInfo()
+                self.win.removeListBoxItems("lstFields", 0, self.win.getListBoxItemCount("lstFields"))
+                self.aListFields=[]
+                tempItem = self.win.getComboBoxText("cmbVariable")
+                for var in self.aVariableList:
+                    if var[:var.find("(")] == tempItem[:tempItem.find("(")]:
+                        sItem=var
+
+                genTree(
+                    sItem[sItem.find("(")+1:sItem.find(")")],
+                    self.aListFields,
+                    self.insField,
+                    self.sMyHost,
+                    2,
+                    ending_excl=['one2many','many2one','many2many','reference'],
+                    recur=['many2one']
+                )
+            except:
+                import traceback,sys
+                info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                self.logobj.log_write('Fields', LOG_ERROR, info)
+
+    def btnOk_clicked( self, oActionEvent ):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        cursor = doc.getCurrentController().getViewCursor()
+        for i in self.win.getListBoxSelectedItemsPos("lstFields"):
+                itemSelected = self.aListFields[i]
+                itemSelectedPos = i
+                txtUName=self.win.getEditText("txtUName")
+                sKey=u""+txtUName
+                if itemSelected != "" and txtUName != "" and self.bModify==True :
+                    txtUName=self.sGDisplayName
+                    sKey=u""+txtUName
+                    txtUName=self.sGDisplayName
+                    oCurObj=cursor.TextField
+                    sObjName=self.insVariable.getText()
+                    sObjName=sObjName[:sObjName.find("(")]
+                    sValue=u"[[ " + sObjName + self.aListFields[itemSelectedPos].replace("/",".") + " ]]"
+                    oCurObj.Items = (sKey,sValue)
+                    oCurObj.update()
+                    self.win.endExecute()
+                elif itemSelected != "" and txtUName != "" :
+
+                    oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+                    sObjName=self.win.getComboBoxText("cmbVariable")
+                    sObjName=sObjName[:sObjName.find("(")]
+
+                    widget = ( cursor.TextTable and cursor.TextTable.getCellByName( cursor.Cell.CellName ) or doc.Text )
+
+                    sValue = u"[[ " + sObjName + self.aListFields[itemSelectedPos].replace("/",".") + " ]]"
+                    oInputList.Items = (sKey,sValue)
+                    widget.insertTextContent(cursor,oInputList,False)
+                    self.win.endExecute()
+                else:
+                    ErrorDialog("Please Fill appropriate data in Name field \nor select perticular value from the list of fields")
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+if __name__<>"package" and __name__=="__main__":
+    Fields()
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( Fields, "org.openoffice.openerp.report.fields", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/LoginTest.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/LoginTest.py
new file mode 100644 (file)
index 0000000..507ec28
--- /dev/null
@@ -0,0 +1,55 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+if __name__<>"package":
+    from ServerParameter import *
+    from lib.gui import *
+
+class LoginTest:
+    def __init__(self):
+        if not loginstatus:
+            ServerParameter(None)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ModifyExistingReport.py
new file mode 100644 (file)
index 0000000..cc1d30b
--- /dev/null
@@ -0,0 +1,213 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import string
+import unohelper
+import xmlrpclib
+import base64, tempfile
+
+
+from com.sun.star.task import XJobExecutor
+import os
+import sys
+if __name__<>'package':
+    from lib.gui import *
+    from lib.error import *
+    from LoginTest import *
+    from lib.logreport import *
+    from lib.rpc import *
+    database="test"
+    uid = 3
+
+#
+class ModifyExistingReport(unohelper.Base, XJobExecutor):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        self.win = DBModalDialog(60, 50, 180, 120, "Modify Existing Report")
+        self.win.addFixedText("lblReport", 2, 3, 60, 15, "Report Selection")
+        self.win.addComboListBox("lstReport", -1,15,178,80 , False )
+        self.lstReport = self.win.getControl( "lstReport" )
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        self.logobj=Logger()
+        self.hostname = docinfo.getUserFieldValue(0)
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        # Open a new connexion to the server
+
+
+        ids = self.sock.execute(database, uid, self.password, 'ir.module.module', 'search', [('name','=','base_report_designer'),('state', '=', 'installed')])
+        if not len(ids):
+            ErrorDialog("Please Install base_report_designer module", "", "Module Uninstalled Error")
+            exit(1)
+
+        ids = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'search', [('report_xsl', '=', False),('report_xml', '=', False)])
+
+        fields=['id', 'name','report_name','model']
+
+        self.reports = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'read', ids, fields)
+        self.report_with_id = []
+
+        for report in self.reports:
+            if report['name']<>"":
+                model_ids = self.sock.execute(database, uid, self.password, 'ir.model' ,  'search', [('model','=', report['model'])])
+                model_res_other =self.sock.execute(database, uid, self.password, 'ir.model', 'read', model_ids, [ 'name', 'model' ] )
+                if model_res_other <> []:
+                    name = model_res_other[0]['name'] + " - " + report['name']
+                else:
+                    name = report['name'] + " - " + report['model']
+                self.report_with_id.append( (report['id'], name, report['model'] ) )
+
+        self.report_with_id.sort( lambda x, y: cmp( x[1], y[1] ) )
+
+        for id, report_name, model_name in self.report_with_id:
+            self.lstReport.addItem( report_name, self.lstReport.getItemCount() )
+
+        self.win.addButton('btnSave',10,-5,50,15,'Open Report' ,actionListenerProc = self.btnOk_clicked )
+        self.win.addButton('btnCancel',-10 ,-5,50,15,'Cancel' ,actionListenerProc = self.btnCancel_clicked )
+        self.win.addButton('btnDelete',15 -80 ,-5,50,15,'Delete Report',actionListenerProc = self.btnDelete_clicked)
+        self.win.doModalDialog("lstReport",self.report_with_id[0][1] )
+
+    def btnOk_clicked(self, oActionEvent):
+        try:
+            desktop=getDesktop()
+            doc = desktop.getCurrentComponent()
+            docinfo=doc.getDocumentInfo()
+
+            selectedItemPos = self.win.getListBoxSelectedItemPos( "lstReport" )
+            id = self.report_with_id[ selectedItemPos ][0]
+
+            res = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'report_get', id)
+
+            if res['file_type'] in ['sxw','odt'] :
+               file_type = res['file_type']
+            else :
+               file_type = 'sxw'
+
+            fp_name = tempfile.mktemp('.'+file_type)
+            fp_name1="r"+fp_name
+            fp_path=os.path.join(fp_name1).replace("\\","/")
+            fp_win=fp_path[1:]
+
+            filename = ( os.name == 'nt' and fp_win or fp_name )
+            if res['report_sxw_content']:
+                write_data_to_file( filename, base64.decodestring(res['report_sxw_content']))
+            url = "file:///%s" % filename
+
+            arr=Array(makePropertyValue("MediaType","application/vnd.sun.xml.writer"),)
+            oDoc2 = desktop.loadComponentFromURL(url, "openerp", 55, arr)
+            docinfo2=oDoc2.getDocumentInfo()
+            docinfo2.setUserFieldValue(0, self.hostname)
+            docinfo2.setUserFieldValue(1,self.password)
+            docinfo2.setUserFieldValue(2,id)
+            docinfo2.setUserFieldValue(3,self.report_with_id[selectedItemPos][2])
+
+            oParEnum = oDoc2.getTextFields().createEnumeration()
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    oPar.SelectedItem = oPar.Items[0]
+                    oPar.update()
+            if oDoc2.isModified():
+                if oDoc2.hasLocation() and not oDoc2.isReadonly():
+                    oDoc2.store()
+
+            ErrorDialog("Download is Completed","Your file has been placed here :\n"+ fp_name,"Download Message")
+            obj=Logger()
+            obj.log_write('Modify Existing Report',LOG_INFO, ':successful download report  %s  using database %s' % (self.report_with_id[selectedItemPos][2], database))
+        except Exception, e:
+            ErrorDialog("Report has not been downloaded", "Report: %s\nDetails: %s" % ( fp_name, str(e) ),"Download Message")
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('ModifyExistingReport', LOG_ERROR, info)
+
+        self.win.endExecute()
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+    def btnDelete_clicked( self, oActionEvent ):
+         desktop=getDesktop()
+         doc = desktop.getCurrentComponent()
+         docinfo=doc.getDocumentInfo()
+
+         selectedItemPos = self.win.getListBoxSelectedItemPos( "lstReport" )
+         name=self.win.getListBoxSelectedItem ("lstReport")
+         id = self.report_with_id[ selectedItemPos ][0]
+         temp = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'unlink', id,)
+         str_value='ir.actions.report.xml,'+str(id)
+         ids = self.sock.execute(database, uid, self.password, 'ir.values' ,  'search',[('value','=',str_value)])
+         if ids:
+              rec = self.sock.execute(database, uid, self.password, 'ir.values', 'unlink', ids,)
+         else :
+            pass
+         if temp:
+              ErrorDialog("Report","Report has been Delete:\n "+name,"Message")
+              self.logobj.log_write('Delete Report',LOG_INFO, ':successful delete report  %s  using database %s' % (name, database))
+
+         else:
+             ErrorDialog("Report","Report has not Delete:\n"+name," Message")
+         self.win.endExecute()
+
+
+
+if __name__<>"package" and __name__=="__main__":
+    ModifyExistingReport(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( ModifyExistingReport, "org.openoffice.openerp.report.modifyreport", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/NewReport.py
new file mode 100644 (file)
index 0000000..06ba552
--- /dev/null
@@ -0,0 +1,119 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import uno
+import string
+import unohelper
+import xmlrpclib
+
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.error import ErrorDialog
+    from lib.functions import *
+    from lib.logreport import *
+    from LoginTest import *
+    from lib.rpc import *
+    database="test"
+    uid = 3
+#
+#
+#
+# Start OpenOffice.org, listen for connections and open testing document
+#
+#
+class NewReport(unohelper.Base, XJobExecutor):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        self.logobj=Logger()
+        if not loginstatus and __name__=="package":
+            exit(1)
+        self.win=DBModalDialog(60, 50, 180, 115, "Open New Report")
+        self.win.addFixedText("lblModuleSelection", 2, 2, 60, 15, "Module Selection")
+        self.win.addComboListBox("lstModule", -2,13,176,80 , False)
+        self.lstModule = self.win.getControl( "lstModule" )
+        self.aModuleName=[]
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        ids = self.sock.execute(database, uid, self.password, 'ir.model' , 'search',[])
+        fields = [ 'model','name']
+        res = self.sock.execute(database, uid, self.password, 'ir.model' , 'read', ids, fields)
+        res.sort(lambda x, y: cmp(x['name'],y['name']))
+
+        for i in range(len(res)):
+            self.lstModule.addItem(res[i]['name'],self.lstModule.getItemCount())
+            self.aModuleName.append(res[i]['model'])
+        self.win.addButton('btnOK',-2 ,-5, 70,15,'Use Module in Report' ,actionListenerProc = self.btnOk_clicked )
+        self.win.addButton('btnCancel',-2 - 70 - 5 ,-5, 35,15,'Cancel' ,actionListenerProc = self.btnCancel_clicked )
+        self.win.doModalDialog("",None)
+
+    def btnOk_clicked(self,oActionEvent):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        docinfo.setUserFieldValue(3,self.aModuleName[self.lstModule.getSelectedItemPos()])
+        self.logobj.log_write('Module Name',LOG_INFO, ':Module use in creating a report %s  using database %s' % (self.aModuleName[self.lstModule.getSelectedItemPos()], database))
+        self.win.endExecute()
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+if __name__<>"package" and __name__=="__main__":
+    NewReport(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( \
+            NewReport,
+            "org.openoffice.openerp.report.opennewreport",
+            ("com.sun.star.task.Job",),)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Repeatln.py
new file mode 100644 (file)
index 0000000..4e26508
--- /dev/null
@@ -0,0 +1,300 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import uno
+import string
+import unohelper
+import xmlrpclib
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.error import ErrorDialog
+    from lib.functions import *
+    from ServerParameter import *
+    from lib.logreport import *
+    from lib.rpc import *
+    from LoginTest import *
+
+    database="test_db1"
+    uid = 3
+
+
+#class RepeatIn:
+class RepeatIn( unohelper.Base, XJobExecutor ):
+    def __init__(self,sObject="",sVariable="",sFields="",sDisplayName="",bFromModify=False):
+        # Interface Design
+        LoginTest()
+        self.logobj=Logger()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        self.win = DBModalDialog(60, 50, 180, 250, "RepeatIn Builder")
+        self.win.addFixedText("lblVariable", 2, 12, 60, 15, "Objects to loop on :")
+        self.win.addComboBox("cmbVariable", 180-120-2, 10, 120, 15,True, itemListenerProc=self.cmbVariable_selected)
+        self.insVariable = self.win.getControl( "cmbVariable" )
+
+        self.win.addFixedText("lblFields", 10, 32, 60, 15, "Field to loop on :")
+        self.win.addComboListBox("lstFields", 180-120-2, 30, 120, 150, False,itemListenerProc=self.lstbox_selected)
+        self.insField = self.win.getControl( "lstFields" )
+
+        self.win.addFixedText("lblName", 12, 187, 60, 15, "Variable name :")
+        self.win.addEdit("txtName", 180-120-2, 185, 120, 15,)
+
+        self.win.addFixedText("lblUName", 8, 207, 60, 15, "Displayed name :")
+        self.win.addEdit("txtUName", 180-120-2, 205, 120, 15,)
+
+        self.win.addButton('btnOK',-2 ,-10,45,15,'Ok', actionListenerProc = self.btnOk_clicked )
+
+        self.win.addButton('btnCancel',-2 - 45 - 5 ,-10,45,15,'Cancel', actionListenerProc = self.btnCancel_clicked )
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        # Variable Declaration
+        self.sValue=None
+        self.sObj=None
+        self.aSectionList=[]
+        self.sGVariable=sVariable
+        self.sGDisplayName=sDisplayName
+        self.aItemList=[]
+        self.aComponentAdd=[]
+        self.aObjectList=[]
+        self.aListRepeatIn=[]
+        self.aVariableList=[]
+        # Call method to perform Enumration on Report Document
+        EnumDocument(self.aItemList,self.aComponentAdd)
+        # Perform checking that Field-1 and Field - 4 is available or not alos get Combobox
+        # filled if condition is true
+        desktop = getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo = doc.getDocumentInfo()
+        # Check weather Field-1 is available if not then exit from application
+        self.sMyHost= ""
+
+        if not docinfo.getUserFieldValue(3) == "" and not docinfo.getUserFieldValue(0)=="":
+            self.sMyHost= docinfo.getUserFieldValue(0)
+            self.count=0
+            oParEnum = doc.getTextFields().createEnumeration()
+
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    self.count += 1
+
+            getList(self.aObjectList, self.sMyHost,self.count)
+            cursor = doc.getCurrentController().getViewCursor()
+            text = cursor.getText()
+            tcur = text.createTextCursorByRange(cursor)
+
+            self.aVariableList.extend( filter( lambda obj: obj[:obj.find(" ")] == "List", self.aObjectList ) )
+
+            for i in range(len(self.aItemList)):
+                try:
+                    anItem = self.aItemList[i][1]
+                    component = self.aComponentAdd[i]
+
+                    if component == "Document":
+                        sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                        self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                    if tcur.TextSection:
+                        getRecersiveSection(tcur.TextSection,self.aSectionList)
+                        if component in self.aSectionList:
+                            sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                            self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                    if tcur.TextTable:
+                        if not component == "Document" and component[component.rfind(".") + 1:] == tcur.TextTable.Name:
+                            VariableScope( tcur, self.aVariableList, self.aObjectList, self.aComponentAdd, self.aItemList, component )
+                except :
+                    import traceback,sys
+                    info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                    self.logobj.log_write('RepeatIn', LOG_ERROR, info)
+            self.bModify=bFromModify
+
+            if self.bModify==True:
+
+                if sObject=="":
+                    self.insVariable.setText("List of "+docinfo.getUserFieldValue(3))
+                    self.insField.addItem("objects",self.win.getListBoxItemCount("lstFields"))
+                    self.win.setEditText("txtName", sVariable)
+                    self.win.setEditText("txtUName",sDisplayName)
+                    self.sValue= "objects"
+                else:
+                    sItem=""
+                   for anObject in self.aObjectList:
+                       if anObject[:anObject.find("(")] == sObject:
+                           sItem = anObject
+                           self.insVariable.setText( sItem )
+
+                   genTree(
+                       sItem[sItem.find("(")+1:sItem.find(")")],
+                       self.aListRepeatIn,
+                       self.insField,
+                       self.sMyHost,
+                       2,
+                       ending=['one2many','many2many'],
+                       recur=['one2many','many2many']
+                   )
+
+                    self.sValue= self.win.getListBoxItem("lstFields",self.aListRepeatIn.index(sFields))
+
+            for var in self.aVariableList:
+
+               if var[:8] <> 'List of ':
+                   self.model_ids = self.sock.execute(database, uid, self.password, 'ir.model' ,  'search', [('model','=',var[var.find("(")+1:var.find(")")])])
+                else:
+                   self.model_ids = self.sock.execute(database, uid, self.password, 'ir.model' ,  'search', [('model','=',var[8:])])
+                fields=['name','model']
+                self.model_res = self.sock.execute(database, uid, self.password, 'ir.model', 'read', self.model_ids,fields)
+                if self.model_res <> []:
+                   if var[:8]<>'List of ':
+                        self.insVariable.addItem(var[:var.find("(")+1] + self.model_res[0]['name'] + ")" ,self.insVariable.getItemCount())
+                    else:
+                        self.insVariable.addItem('List of ' + self.model_res[0]['name'] ,self.insVariable.getItemCount())
+                else:
+                    self.insVariable.addItem(var ,self.insVariable.getItemCount())
+
+            self.win.doModalDialog("lstFields",self.sValue)
+        else:
+            ErrorDialog("Please Select Appropriate module" ,"Create new report from: \nOpenERP -> Open a New Report")
+            self.win.endExecute()
+
+    def lstbox_selected(self,oItemEvent):
+        sItem=self.win.getListBoxSelectedItem("lstFields")
+        sMain=self.aListRepeatIn[self.win.getListBoxSelectedItemPos("lstFields")]
+
+        if self.bModify==True:
+            self.win.setEditText("txtName", self.sGVariable)
+            self.win.setEditText("txtUName",self.sGDisplayName)
+        else:
+           self.win.setEditText("txtName",sMain[sMain.rfind("/")+1:])
+           self.win.setEditText("txtUName","|-."+sItem[sItem.rfind("/")+1:]+".-|")
+
+    def cmbVariable_selected(self,oItemEvent):
+
+        if self.count > 0 :
+
+            desktop=getDesktop()
+            doc =desktop.getCurrentComponent()
+            docinfo=doc.getDocumentInfo()
+            self.win.removeListBoxItems("lstFields", 0, self.win.getListBoxItemCount("lstFields"))
+            sItem=self.win.getComboBoxText("cmbVariable")
+            for var in self.aVariableList:
+               if var[:8]=='List of ':
+                   if var[:8]==sItem[:8]:
+                        sItem = var
+               elif var[:var.find("(")+1] == sItem[:sItem.find("(")+1]:
+                    sItem = var
+            self.aListRepeatIn=[]
+
+           data = ( sItem[sItem.rfind(" ") + 1:] == docinfo.getUserFieldValue(3) ) and docinfo.getUserFieldValue(3) or sItem[sItem.find("(")+1:sItem.find(")")]
+           genTree( data, self.aListRepeatIn, self.insField, self.sMyHost, 2, ending=['one2many','many2many'], recur=['one2many','many2many'] )
+
+            self.win.selectListBoxItemPos("lstFields", 0, True )
+
+        else:
+            sItem=self.win.getComboBoxText("cmbVariable")
+            for var in self.aVariableList:
+                if var[:8]=='List of ' and var[:8] == sItem[:8]:
+                    sItem = var
+            if sItem.find(".")==-1:
+                temp=sItem[sItem.rfind("x_"):]
+            else:
+                temp=sItem[sItem.rfind(".")+1:]
+            self.win.setEditText("txtName",temp)
+            self.win.setEditText("txtUName","|-."+temp+".-|")
+            self.insField.addItem("objects",self.win.getListBoxItemCount("lstFields"))
+            self.win.selectListBoxItemPos("lstFields", 0, True )
+
+    def btnOk_clicked(self, oActionEvent):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        cursor = doc.getCurrentController().getViewCursor()
+        selectedItem = self.win.getListBoxSelectedItem( "lstFields" )
+        selectedItemPos = self.win.getListBoxSelectedItemPos( "lstFields" )
+        txtName = self.win.getEditText( "txtName" )
+        txtUName = self.win.getEditText( "txtUName" )
+        if selectedItem != "" and txtName != "" and txtUName != "":
+            sKey=u""+ txtUName
+            if selectedItem == "objects":
+                sValue=u"[[ repeatIn(" + selectedItem + ",'" + txtName + "') ]]"
+            else:
+                sObjName=self.win.getComboBoxText("cmbVariable")
+                sObjName=sObjName[:sObjName.find("(")]
+                sValue=u"[[ repeatIn(" + sObjName + self.aListRepeatIn[selectedItemPos].replace("/",".") + ",'" + txtName +"') ]]"
+
+            if self.bModify == True:
+                oCurObj = cursor.TextField
+                oCurObj.Items = (sKey,sValue)
+                oCurObj.update()
+            else:
+                oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+                if self.win.getListBoxSelectedItem("lstFields") == "objects":
+                    oInputList.Items = (sKey,sValue)
+                    doc.Text.insertTextContent(cursor,oInputList,False)
+                else:
+                    sValue=u"[[ repeatIn(" + sObjName + self.aListRepeatIn[selectedItemPos].replace("/",".") + ",'" + txtName +"') ]]"
+                    if cursor.TextTable==None:
+                        oInputList.Items = (sKey,sValue)
+                        doc.Text.insertTextContent(cursor,oInputList,False)
+                    else:
+                        oInputList.Items = (sKey,sValue)
+                        widget = ( cursor.TextTable or selectedItem <> 'objects' ) and cursor.TextTable.getCellByName( cursor.Cell.CellName ) or doc.Text
+                        widget.insertTextContent(cursor,oInputList,False)
+                self.win.endExecute()
+        else:
+            ErrorDialog("Please Fill appropriate data in Object Field or Name field \nor select perticular value from the list of fields")
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+if __name__<>"package" and __name__=="__main__":
+    RepeatIn()
+elif __name__=="package":
+    g_ImplementationHelper = unohelper.ImplementationHelper()
+    g_ImplementationHelper.addImplementation( RepeatIn, "org.openoffice.openerp.report.repeatln", ("com.sun.star.task.Job",),)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/SendToServer.py
new file mode 100644 (file)
index 0000000..fd8a874
--- /dev/null
@@ -0,0 +1,241 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import string
+import unohelper
+import random
+import xmlrpclib
+import base64, tempfile
+from com.sun.star.task import XJobExecutor
+import os
+import sys
+if __name__<>'package':
+    from lib.gui import *
+    from lib.error import *
+    from lib.functions import *
+    from lib.logreport import *
+    from lib.tools import *
+    from LoginTest import *
+    from lib.rpc import *
+    database="report"
+    uid = 3
+
+#
+#
+class SendtoServer(unohelper.Base, XJobExecutor):
+    Kind = {
+        'PDF' : 'pdf',
+        'OpenOffice': 'sxw',
+        'HTML' : 'html'
+    }
+
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        LoginTest()
+        self.logobj=Logger()
+        if not loginstatus and __name__=="package":
+            exit(1)
+
+        global passwd
+        self.password = passwd
+        global url
+        self.sock=RPCSession(url)
+        desktop=getDesktop()
+        oDoc2 = desktop.getCurrentComponent()
+        docinfo=oDoc2.getDocumentInfo()
+
+        self.ids = self.sock.execute(database, uid, self.password, 'ir.module.module', 'search', [('name','=','base_report_designer'),('state', '=', 'installed')])
+        if not len(self.ids):
+            ErrorDialog("Please Install base_report_designer module", "", "Module Uninstalled Error")
+            exit(1)
+
+        report_name = ""
+        name=""
+        if docinfo.getUserFieldValue(2)<>"" :
+            try:
+                fields=['name','report_name']
+                self.res_other = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'read', [int(docinfo.getUserFieldValue(2))],fields)
+                name = self.res_other[0]['name']
+                report_name = self.res_other[0]['report_name']
+            except:
+                import traceback,sys
+                info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                self.logob.log_write('ServerParameter', LOG_ERROR, info)
+        elif docinfo.getUserFieldValue(3) <> "":
+            name = ""
+            result =  "rnd"
+            for i in range(5):
+                result =result + random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
+
+            report_name = docinfo.getUserFieldValue(3) + "." + result
+        else:
+            ErrorDialog("Please select appropriate module...","Note: use OpenERP Report -> Open a new Report", "Module selection ERROR");
+            exit(1)
+
+        self.win = DBModalDialog(60, 50, 180, 100, "Send To Server")
+        self.win.addFixedText("lblName",10 , 9, 40, 15, "Report Name :")
+        self.win.addEdit("txtName", -5, 5, 123, 15,name)
+        self.win.addFixedText("lblReportName", 2, 30, 50, 15, "Technical Name :")
+        self.win.addEdit("txtReportName", -5, 25, 123, 15,report_name)
+        self.win.addCheckBox("chkHeader", 51, 45, 70 ,15, "Corporate Header")
+        self.win.addFixedText("lblResourceType", 2 , 60, 50, 15, "Select Rpt. Type :")
+        self.win.addComboListBox("lstResourceType", -5, 58, 123, 15,True,itemListenerProc=self.lstbox_selected)
+        self.lstResourceType = self.win.getControl( "lstResourceType" )
+        self.txtReportName=self.win.getControl( "txtReportName" )
+        self.txtReportName.Enable=False
+        for kind in self.Kind.keys():
+            self.lstResourceType.addItem( kind, self.lstResourceType.getItemCount() )
+
+        self.win.addButton( "btnSend", -5, -5, 80, 15, "Send Report to Server", actionListenerProc = self.btnOk_clicked)
+        self.win.addButton( "btnCancel", -5 - 80 -5, -5, 40, 15, "Cancel", actionListenerProc = self.btnCancel_clicked)
+
+        self.win.doModalDialog("lstResourceType", self.Kind.keys()[0])
+
+    def lstbox_selected(self,oItemEvent):
+        pass
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+    def btnOk_clicked(self, oActionEvent):
+        if self.win.getEditText("txtName") <> "" and self.win.getEditText("txtReportName") <> "":
+            desktop=getDesktop()
+            oDoc2 = desktop.getCurrentComponent()
+            docinfo=oDoc2.getDocumentInfo()
+            self.getInverseFieldsRecord(1)
+            fp_name = tempfile.mktemp('.'+"sxw")
+            if not oDoc2.hasLocation():
+                oDoc2.storeAsURL("file://"+fp_name,Array(makePropertyValue("MediaType","application/vnd.sun.xml.writer"),))
+
+            if docinfo.getUserFieldValue(2)=="":
+                name=self.win.getEditText("txtName"),
+                name_id={}
+                try:
+                    name_id = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml' , 'search',[('name','=',name)])
+                    if not name_id:
+                        id=self.getID()
+                        docinfo.setUserFieldValue(2,id)
+                        rec = {
+                                'name': self.win.getEditText("txtReportName"),
+                                'key': 'action',
+                                'model': docinfo.getUserFieldValue(3),
+                                'value': 'ir.actions.report.xml,'+str(id),
+                                'key2': 'client_print_multi',
+                                'object': True
+                            }
+                        res = self.sock.execute(database, uid, self.password, 'ir.values' , 'create',rec )
+                    else :
+                        ErrorDialog(" Report Name is all ready given !!!\n\n\n Please specify other Name","","Report Name")
+                        self.logobj.log_write('SendToServer',LOG_WARNING, ':Report name all ready given DB %s' % (database))
+                        self.win.endExecute()
+                except Exception,e:
+                    import traceback,sys
+                    info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                    self.logobj.log_write('ServerParameter', LOG_ERROR, info)
+            else:
+
+                id = docinfo.getUserFieldValue(2)
+                vId = self.sock.execute(database, uid, self.password, 'ir.values' ,  'search', [('value','=','ir.actions.report.xml,'+str(id))])
+                rec = { 'name': self.win.getEditText("txtReportName") }
+                res = self.sock.execute(database, uid, self.password, 'ir.values' , 'write',vId,rec)
+            oDoc2.store()
+            data = read_data_from_file( get_absolute_file_path( oDoc2.getURL()[7:] ) )
+            self.getInverseFieldsRecord(0)
+            #sock = xmlrpclib.ServerProxy(docinfo.getUserFieldValue(0) +'/xmlrpc/object')
+
+            file_type = oDoc2.getURL()[7:].split(".")[-1]
+            res = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'upload_report', int(docinfo.getUserFieldValue(2)),base64.encodestring(data),file_type,{})
+            params = {
+                'name': self.win.getEditText("txtName"),
+                'model': docinfo.getUserFieldValue(3),
+                'report_name': self.win.getEditText("txtReportName"),
+                'header': (self.win.getCheckBoxState("chkHeader") <> 0),
+                'report_type': self.Kind[self.win.getListBoxSelectedItem("lstResourceType")],
+            }
+            if self.win.getListBoxSelectedItem("lstResourceType")=='OpenOffice':
+                params['report_type']=file_type
+            res = self.sock.execute(database, uid, self.password, 'ir.actions.report.xml', 'write', int(docinfo.getUserFieldValue(2)), params)
+            self.logobj.log_write('SendToServer',LOG_INFO, ':Report %s successfully send using %s'%(params['name'],database))
+            self.win.endExecute()
+        else:
+            ErrorDialog("Either Report Name or Technical Name is blank !!!\nPlease specify appropriate Name","","Blank Field ERROR")
+            self.logobj.log_write('SendToServer',LOG_WARNING, ':Either Report Name or Technical Name is blank')
+            self.win.endExecute()
+
+    def getID(self):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        params = {
+            'name': self.win.getEditText("txtName"),
+            'model': docinfo.getUserFieldValue(3),
+            'report_name': self.win.getEditText('txtReportName')
+        }
+
+
+        id=self.sock.execute(database, uid, self.password, 'ir.actions.report.xml' ,'create', params)
+        return id
+
+    def getInverseFieldsRecord(self,nVal):
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        count=0
+        oParEnum = doc.getTextFields().createEnumeration()
+        while oParEnum.hasMoreElements():
+            oPar = oParEnum.nextElement()
+            if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                oPar.SelectedItem = oPar.Items[nVal]
+                if nVal==0:
+                    oPar.update()
+
+if __name__<>"package" and __name__=="__main__":
+    SendtoServer(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( SendtoServer, "org.openoffice.openerp.report.sendtoserver", ("com.sun.star.task.Job",),)
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/ServerParameter.py
new file mode 100644 (file)
index 0000000..659357e
--- /dev/null
@@ -0,0 +1,208 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import uno
+import string
+import unohelper
+import xmlrpclib
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.error import ErrorDialog
+    from lib.functions import *
+    from lib.logreport import *
+    from lib.rpc import *
+    from Change import *
+    database="test"
+
+class ServerParameter( unohelper.Base, XJobExecutor ):
+    def __init__(self,ctx):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+        desktop=getDesktop()
+        log_detail(self)
+        self.logobj=Logger()
+        doc = desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        self.win=DBModalDialog(60, 50, 160, 108, "Server Connection Parameter")
+
+        self.win.addFixedText("lblVariable", 2, 12, 35, 15, "Server URL")
+        if docinfo.getUserFieldValue(0)=="":
+            docinfo.setUserFieldValue(0,"http://localhost:8069")
+        self.win.addEdit("txtHost",-34,9,91,15,docinfo.getUserFieldValue(0))
+        self.win.addButton('btnChange',-2 ,9,30,15,'Change', actionListenerProc = self.btnChange_clicked )
+
+        self.win.addFixedText("lblDatabaseName", 6, 31, 31, 15, "Database")
+        #self.win.addFixedText("lblMsg", -2,28,123,15)
+#        self.win.addComboListBox("lstDatabase", -2,28,123,15, True)
+#        self.lstDatabase = self.win.getControl( "lstDatabase" )
+        #self.win.selectListBoxItem( "lstDatabase", docinfo.getUserFieldValue(2), True )
+        #self.win.setEnabled("lblMsg",False)
+
+        self.win.addFixedText("lblLoginName", 17, 51, 20, 15, "Login")
+        self.win.addEdit("txtLoginName",-2,48,123,15,docinfo.getUserFieldValue(1))
+
+        self.win.addFixedText("lblPassword", 6, 70, 31, 15, "Password")
+        self.win.addEdit("txtPassword",-2,67,123,15,)
+        self.win.setEchoChar("txtPassword",42)
+
+
+        self.win.addButton('btnOK',-2 ,-5, 60,15,'Connect' ,actionListenerProc = self.btnOk_clicked )
+
+        self.win.addButton('btnCancel',-2 - 60 - 5 ,-5, 35,15,'Cancel' ,actionListenerProc = self.btnCancel_clicked )
+        sValue=""
+        if docinfo.getUserFieldValue(0)<>"":
+            global url
+            global result
+            url=docinfo.getUserFieldValue(0)
+            self.sock=RPCSession(url)
+            res=self.sock.listdb()
+            result=res
+            if res == -1:
+                self.win.addEdit("lstDatabase",-2,28,123,15)
+#                sValue="Could not connect to the server!"
+#                self.lstDatabase.addItem("Could not connect to the server!",0)
+            elif res == 0:
+                sValue="No Database found !!!"
+                self.lstDatabase.addItem("No Database found !!!",0)
+            else:
+                self.win.addComboListBox("lstDatabase", -2,28,123,15, True)
+                self.lstDatabase = self.win.getControl( "lstDatabase" )
+                self.win.removeListBoxItems("lstDatabase", 0, self.win.getListBoxItemCount("lstDatabase"))
+                for i in range(len(res)):
+                    self.lstDatabase.addItem(res[i],i)
+                sValue = database
+        if sValue:
+            self.win.doModalDialog("lstDatabase",sValue)
+        else:
+            self.win.doModalDialog("lstDatabase",None)
+
+        #self.win.doModalDialog("lstDatabase",docinfo.getUserFieldValue(2))
+
+    def btnOk_clicked(self,oActionEvent):
+
+
+        sLogin=self.win.getEditText("txtLoginName")
+        sPassword=self.win.getEditText("txtPassword")
+        global url
+        global result
+        if result==-1:
+            sDatabase=self.win.getEditText("lstDatabase")
+        else:
+            sDatabase=self.win.getListBoxSelectedItem("lstDatabase")
+        self.sock=RPCSession(url)
+        UID = self.sock.login(sDatabase,sLogin,sPassword)
+        if not UID :
+            ErrorDialog("Connection Refuse...","Please enter valid Login/Password")
+            self.win.endExecute()
+        try:
+
+            ids  = self.sock.execute(sDatabase,UID,sPassword, 'res.groups' ,  'search', [('name','=','OpenOfficeReportDesigner')])
+            ids_module =self.sock.execute(sDatabase, UID, sPassword, 'ir.module.module', 'search', [('name','=','base_report_designer'),('state', '=', 'installed')])
+            dict_groups =self.sock.execute(sDatabase, UID,sPassword, 'res.groups' , 'read',ids,['users'])
+        except :
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            self.logobj.log_write('ServerParameter', LOG_ERROR, info)
+
+        if not len(ids) :
+            ErrorDialog("Group Not Found!!!  Create a group  named  \n\n"'"OpenOfficeReportDesigner"'"  \n\n  ","","Group Name Error")
+            self.logobj.log_write('Group Error',LOG_WARNING, ':Create a  group OpenOfficeReportDesigner   using database %s' % (sDatabase))
+            self.win.endExecute()
+        if not len(ids_module):
+            ErrorDialog("Please Install base_report_designer module", "", "Module Uninstalled Error")
+            self.logobj.log_write('Module Not Found',LOG_WARNING, ':base_report_designer not install in  database %s' % (sDatabase))
+            self.win.endExecute()
+
+        if UID not in dict_groups[0]['users']:
+            ErrorDialog("Connection Refuse...","You have not access these Report Designer")
+            self.logobj.log_write('Connection Refuse',LOG_WARNING, " Not Access Report Designer ")
+            self.win.endExecute()
+        else:
+            desktop=getDesktop()
+            doc = desktop.getCurrentComponent()
+            docinfo=doc.getDocumentInfo()
+            docinfo.setUserFieldValue(0,self.win.getEditText("txtHost"))
+            docinfo.setUserFieldValue(1,self.win.getEditText("txtLoginName"))
+            global passwd
+            passwd=self.win.getEditText("txtPassword")
+            global loginstatus
+            loginstatus=True
+            global database
+            database=sDatabase
+            global uid
+            uid=UID
+            #docinfo.setUserFieldValue(2,self.win.getListBoxSelectedItem("lstDatabase"))
+            #docinfo.setUserFieldValue(3,"")
+
+            ErrorDialog(" You can start creating your report in \n  \t the current document.","After Creating  sending to the server.","Message")
+            self.logobj.log_write('successful login',LOG_INFO, ':successful login from %s  using database %s' % (sLogin, sDatabase))
+            self.win.endExecute()
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+    def btnChange_clicked(self,oActionEvent):
+        aVal=[]
+        url= self.win.getEditText("txtHost")
+        Change(aVal,url)
+        if aVal[1]== -1:
+           self.win.getEditText("lstDatabase")
+        elif aVal[1]==0:
+            ErrorDialog(aVal[0],"")
+        else:
+            self.win.setEditText("txtHost",aVal[0])
+            self.win.removeListBoxItems("lstDatabase", 0, self.win.getListBoxItemCount("lstDatabase"))
+            for i in range(len(aVal[1])):
+                self.lstDatabase.addItem(aVal[1][i],i)
+
+
+if __name__<>"package" and __name__=="__main__":
+    ServerParameter(None)
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( ServerParameter, "org.openoffice.openerp.report.serverparam", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/Translation.py
new file mode 100644 (file)
index 0000000..e1df582
--- /dev/null
@@ -0,0 +1,274 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import string
+import unohelper
+import xmlrpclib
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from lib.functions import *
+    from lib.error import ErrorDialog
+    from LoginTest import *
+    from lib.rpc import *
+    database="test_001"
+    uid = 3
+
+
+class AddLang(unohelper.Base, XJobExecutor ):
+    def __init__(self,sVariable="",sFields="",sDisplayName="",bFromModify=False):
+        LoginTest()
+        if not loginstatus and __name__=="package":
+            exit(1)
+        global passwd
+        self.password = passwd
+        self.win = DBModalDialog(60, 50, 180, 225, "Set Lang Builder")
+
+        self.win.addFixedText("lblVariable", 27, 12, 60, 15, "Variable :")
+        self.win.addComboBox("cmbVariable", 180-120-2, 10, 120, 15,True,
+                            itemListenerProc=self.cmbVariable_selected)
+        self.insVariable = self.win.getControl( "cmbVariable" )
+
+        self.win.addFixedText("lblFields", 10, 32, 60, 15, "Variable Fields :")
+        self.win.addComboListBox("lstFields", 180-120-2, 30, 120, 150, False,itemListenerProc=self.lstbox_selected)
+        self.insField = self.win.getControl( "lstFields" )
+        self.win.addFixedText("lblUName", 8, 187, 60, 15, "Displayed name :")
+        self.win.addEdit("txtUName", 180-120-2, 185, 120, 15,)
+
+        self.win.addButton('btnOK',-5 ,-5, 45, 15, 'Ok', actionListenerProc = self.btnOk_clicked )
+        self.win.addButton('btnCancel',-5 - 45 - 5 ,-5,45,15,'Cancel', actionListenerProc = self.btnCancel_clicked )
+        self.sValue=None
+        self.sObj=None
+        self.aSectionList=[]
+        self.sGDisplayName=sDisplayName
+        self.aItemList=[]
+        self.aComponentAdd=[]
+        self.aObjectList=[]
+        self.aListFields=[]
+        self.aVariableList=[]
+        EnumDocument(self.aItemList,self.aComponentAdd)
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        self.sMyHost= ""
+        global url
+        self.sock=RPCSession(url)
+
+        if not docinfo.getUserFieldValue(3) == "" and not docinfo.getUserFieldValue(0)=="":
+            self.sMyHost= docinfo.getUserFieldValue(0)
+            self.count=0
+            oParEnum = doc.getTextFields().createEnumeration()
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    self.count += 1
+            getList(self.aObjectList, self.sMyHost,self.count)
+            cursor = doc.getCurrentController().getViewCursor()
+            text=cursor.getText()
+            tcur=text.createTextCursorByRange(cursor)
+
+           self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == "Objects", self.aObjectList ) )
+
+            for i in range(len(self.aItemList)):
+               anItem = self.aItemList[i][1]
+               component = self.aComponentAdd[i]
+
+                if component == "Document":
+                   sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                   self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                if tcur.TextSection:
+                    getRecersiveSection(tcur.TextSection,self.aSectionList)
+                    if component in self.aSectionList:
+                       sLVal = anItem[anItem.find(",'") + 2:anItem.find("')")]
+                       self.aVariableList.extend( filter( lambda obj: obj[:obj.find("(")] == sLVal, self.aObjectList ) )
+
+                if tcur.TextTable:
+                   if not component == "Document" and component[component.rfind(".") + 1:] == tcur.TextTable.Name:
+                        VariableScope(tcur,self.insVariable,self.aObjectList,self.aComponentAdd,self.aItemList,component)
+
+            self.bModify=bFromModify
+            if self.bModify==True:
+                sItem=""
+               for anObject in self.aObjectList:
+                   if anObject[:anObject.find("(")] == sVariable:
+                       sItem = anObject
+                       self.insVariable.setText( sItem )
+               genTree(sItem[sItem.find("(")+1:sItem.find(")")],self.aListFields, self.insField,self.sMyHost,2,ending_excl=['one2many','many2one','many2many','reference'], recur=['many2one'])
+                self.sValue= self.win.getListBoxItem("lstFields",self.aListFields.index(sFields))
+
+            for var in self.aVariableList:
+
+                   self.model_ids = self.sock.execute(database, uid, self.password, 'ir.model' ,  'search', [('model','=',var[var.find("(")+1:var.find(")")])])
+                    fields=['name','model']
+                    self.model_res = self.sock.execute(database, uid, self.password, 'ir.model', 'read', self.model_ids,fields)
+                    if self.model_res <> []:
+                       self.insVariable.addItem(var[:var.find("(")+1] + self.model_res[0]['name'] + ")" ,self.insVariable.getItemCount())
+                    else:
+                        self.insVariable.addItem(var ,self.insVariable.getItemCount())
+
+            self.win.doModalDialog("lstFields",self.sValue)
+        else:
+            ErrorDialog("Please insert user define field Field-1 or Field-4","Just go to File->Properties->User Define \nField-1 Eg. http://localhost:8069 \nOR \nField-4 Eg. account.invoice")
+            self.win.endExecute()
+
+    def lstbox_selected(self,oItemEvent):
+        try:
+
+            desktop=getDesktop()
+            doc =desktop.getCurrentComponent()
+            docinfo=doc.getDocumentInfo()
+            sItem= self.win.getComboBoxText("cmbVariable")
+            for var in self.aVariableList:
+               if var[:var.find("(")+1]==sItem[:sItem.find("(")+1]:
+                    sItem = var
+            sMain=self.aListFields[self.win.getListBoxSelectedItemPos("lstFields")]
+            t=sMain.rfind('/lang')
+            if t!=-1:
+               sObject=self.getRes(self.sock,sItem[sItem.find("(")+1:-1],sMain[1:])
+                ids = self.sock.execute(database, uid, self.password, sObject ,  'search', [])
+                res = self.sock.execute(database, uid, self.password, sObject , 'read',[ids[0]])
+               self.win.setEditText("txtUName",res[0][sMain[sMain.rfind("/")+1:]])
+            else:
+                 ErrorDialog("Please select the Language Field")
+
+        except:
+            import traceback;traceback.print_exc()
+            self.win.setEditText("txtUName","TTT")
+        if self.bModify:
+            self.win.setEditText("txtUName",self.sGDisplayName)
+
+    def getRes(self,sock ,sObject,sVar):
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        docinfo=doc.getDocumentInfo()
+        res = sock.execute(database, uid, self.password, sObject , 'fields_get')
+        key = res.keys()
+        key.sort()
+        myval=None
+        if not sVar.find("/")==-1:
+           myval=sVar[:sVar.find("/")]
+        else:
+            myval=sVar
+        if myval in key:
+            if (res[myval]['type'] in ['many2one']):
+                sObject = res[myval]['relation']
+               return self.getRes(sock,res[myval]['relation'], sVar[sVar.find("/")+1:])
+            else:
+                return sObject
+
+
+    def cmbVariable_selected(self,oItemEvent):
+        if self.count > 0 :
+            try:
+                desktop=getDesktop()
+                doc =desktop.getCurrentComponent()
+                docinfo=doc.getDocumentInfo()
+                self.win.removeListBoxItems("lstFields", 0, self.win.getListBoxItemCount("lstFields"))
+                self.aListFields=[]
+                tempItem = self.win.getComboBoxText("cmbVariable")
+                for var in self.aVariableList:
+                   if var[:var.find("(")] == tempItem[:tempItem.find("(")]:
+                        sItem=var
+
+               genTree(
+                   sItem[ sItem.find("(") + 1:sItem.find(")")],
+                   self.aListFields,
+                   self.insField,
+                   self.sMyHost,
+                   2,
+                   ending_excl=['one2many','many2one','many2many','reference'],
+                   recur=['many2one']
+               )
+
+            except:
+                import traceback;traceback.print_exc()
+
+    def btnOk_clicked( self, oActionEvent ):
+        self.bOkay = True
+        desktop=getDesktop()
+        doc = desktop.getCurrentComponent()
+        cursor = doc.getCurrentController().getViewCursor()
+
+        itemSelected = self.win.getListBoxSelectedItem( "lstFields" )
+        itemSelectedPos = self.win.getListBoxSelectedItemPos( "lstFields" )
+        txtUName = self.win.getEditText("txtUName")
+        sKey=u""+ txtUName
+
+        if itemSelected != "" and txtUName != "" and self.bModify==True :
+            oCurObj=cursor.TextField
+            sObjName=self.insVariable.getText()
+            sObjName=sObjName[:sObjName.find("(")]
+            sValue=u"[[ setLang" + sObjName + self.aListFields[itemSelectedPos].replace("/",".") + ")" " ]]"
+            oCurObj.Items = (sKey,sValue)
+            oCurObj.update()
+            self.win.endExecute()
+        elif itemSelected != "" and txtUName != "" :
+            oInputList = doc.createInstance("com.sun.star.text.TextField.DropDown")
+            sObjName=self.win.getComboBoxText("cmbVariable")
+            sObjName=sObjName[:sObjName.find("(")]
+
+            widget = ( cursor.TextTable and cursor.TextTable.getCellByName( cursor.Cell.CellName ) or doc.Text )
+
+            sValue = u"[[setLang" + "(" + sObjName + self.aListFields[itemSelectedPos].replace("/",".") +")" " ]]"
+            oInputList.Items = (sKey,sValue)
+            widget.insertTextContent(cursor,oInputList,False)
+
+            self.win.endExecute()
+        else:
+            ErrorDialog("Please Fill appropriate data in Name field \nor select perticular value from the list of fields")
+
+    def btnCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
+
+if __name__<>"package" and __name__=="__main__":
+    AddLang()
+elif __name__=="package":
+    g_ImplementationHelper.addImplementation( AddLang, "org.openoffice.openerp.report.langtag", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/__init__.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/__init__.py
new file mode 100644 (file)
index 0000000..af5e289
--- /dev/null
@@ -0,0 +1,61 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import Expression
+import lib
+import Fields
+import modify
+import Repeatln
+import ServerParameter
+import NewReport
+import LoginTest
+import Change
+import About
+import AddAttachment
+import ConvertBracesToField
+import ConvertFieldsToBraces
+import ExportToRML
+import SendtoServer
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/compile_all.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/compile_all.py
new file mode 100644 (file)
index 0000000..5a95c61
--- /dev/null
@@ -0,0 +1,49 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+import compileall
+
+compileall.compile_dir('package')
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/import b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/import
new file mode 100644 (file)
index 0000000..e14c925
--- /dev/null
@@ -0,0 +1,2 @@
+__name__="package"
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/__init__.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/__init__.py
new file mode 100644 (file)
index 0000000..b673922
--- /dev/null
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import actions
+import error
+import functions
+import gui
+import logreport
+import rpc
+import tiny_socket
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/actions.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/actions.py
new file mode 100644 (file)
index 0000000..8faec4c
--- /dev/null
@@ -0,0 +1,111 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import unohelper
+import os
+#--------------------------------------------------
+# An ActionListener adapter.
+# This object implements com.sun.star.awt.XActionListener.
+# When actionPerformed is called, this will call an arbitrary
+#  python procedure, passing it...
+#   1. the oActionEvent
+#   2. any other parameters you specified to this object's constructor (as a tuple).
+if __name__<>"package":
+    os.system( "ooffice '-accept=socket,host=localhost,port=2002;urp;'" )
+passwd=""
+database=""
+uid=""
+loginstatus=False
+from com.sun.star.awt import XActionListener
+class ActionListenerProcAdapter( unohelper.Base, XActionListener ):
+    def __init__( self, oProcToCall, tParams=() ):
+        self.oProcToCall = oProcToCall # a python procedure
+        self.tParams = tParams # a tuple
+
+    # oActionEvent is a com.sun.star.awt.ActionEvent struct.
+    def actionPerformed( self, oActionEvent ):
+        if callable( self.oProcToCall ):
+            apply( self.oProcToCall, (oActionEvent,) + self.tParams )
+
+#--------------------------------------------------
+# An ItemListener adapter.
+# This object implements com.sun.star.awt.XItemListener.
+# When itemStateChanged is called, this will call an arbitrary
+#  python procedure, passing it...
+#   1. the oItemEvent
+#   2. any other parameters you specified to this object's constructor (as a tuple).
+from com.sun.star.awt import XItemListener
+class ItemListenerProcAdapter( unohelper.Base, XItemListener ):
+    def __init__( self, oProcToCall, tParams=() ):
+        self.oProcToCall = oProcToCall # a python procedure
+        self.tParams = tParams # a tuple
+
+    # oItemEvent is a com.sun.star.awt.ItemEvent struct.
+    def itemStateChanged( self, oItemEvent ):
+        if callable( self.oProcToCall ):
+            apply( self.oProcToCall, (oItemEvent,) + self.tParams )
+
+#--------------------------------------------------
+# An TextListener adapter.
+# This object implements com.sun.star.awt.XTextistener.
+# When textChanged is called, this will call an arbitrary
+#  python procedure, passing it...
+#   1. the oTextEvent
+#   2. any other parameters you specified to this object's constructor (as a tuple).
+from com.sun.star.awt import XTextListener
+class TextListenerProcAdapter( unohelper.Base, XTextListener ):
+    def __init__( self, oProcToCall, tParams=() ):
+        self.oProcToCall = oProcToCall # a python procedure
+        self.tParams = tParams # a tuple
+
+    # oTextEvent is a com.sun.star.awt.TextEvent struct.
+    def textChanged( self, oTextEvent ):
+        if callable( self.oProcToCall ):
+            apply( self.oProcToCall, (oTextEvent,) + self.tParams )
+
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/error.py
new file mode 100644 (file)
index 0000000..bb51a35
--- /dev/null
@@ -0,0 +1,60 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+if __name__<>"package":
+    from gui import *
+class ErrorDialog:
+    def __init__(self,sErrorMsg, sErrorHelpMsg="",sTitle="Error Message"):
+        self.win = DBModalDialog(50, 50, 150, 90, sTitle)
+        self.win.addFixedText("lblErrMsg", 5, 5, 190, 25, sErrorMsg)
+        self.win.addFixedText("lblErrHelpMsg", 5, 30, 190, 25, sErrorHelpMsg)
+        self.win.addButton('btnOK', 55,-5,40,15,'Ok'
+                     ,actionListenerProc = self.btnOkOrCancel_clicked )
+        self.win.doModalDialog("",None)
+    def btnOkOrCancel_clicked( self, oActionEvent ):
+        self.win.endExecute()
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/functions.py
new file mode 100644 (file)
index 0000000..2f5f518
--- /dev/null
@@ -0,0 +1,264 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import xmlrpclib
+import re
+import socket
+import cPickle
+import marshal
+import tempfile
+if __name__<>"package":
+    from gui import *
+    from logreport import *
+    from rpc import *
+    database="test"
+    uid = 1
+
+def genTree(object,aList,insField,host,level=3, ending=[], ending_excl=[], recur=[], root='', actualroot=""):
+    try:
+        global url
+        sock=RPCSession(url)
+        global passwd
+        res = sock.execute(database, uid, passwd, object , 'fields_get')
+        key = res.keys()
+        key.sort()
+        for k in key:
+            if (not ending or res[k]['type'] in ending) and ((not ending_excl) or not (res[k]['type'] in ending_excl)):
+                insField.addItem(root+'/'+res[k]["string"],len(aList))
+                aList.append(actualroot+'/'+k)
+            if (res[k]['type'] in recur) and (level>0):
+                genTree(res[k]['relation'],aList,insField,host ,level-1, ending, ending_excl, recur,root+'/'+res[k]["string"],actualroot+'/'+k)
+    except:
+        obj=Logger()
+        import traceback,sys
+        info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+        obj.log_write('Function', LOG_ERROR, info)
+
+def VariableScope(oTcur,insVariable,aObjectList,aComponentAdd,aItemList,sTableName=""):
+    if sTableName.find(".") != -1:
+       for i in range(len(aItemList)):
+            if aComponentAdd[i]==sTableName:
+               sLVal=aItemList[i][1][aItemList[i][1].find(",'")+2:aItemList[i][1].find("')")]
+                for j in range(len(aObjectList)):
+                   if aObjectList[j][:aObjectList[j].find("(")] == sLVal:
+                        insVariable.append(aObjectList[j])
+       VariableScope(oTcur,insVariable,aObjectList,aComponentAdd,aItemList, sTableName[:sTableName.rfind(".")])
+    else:
+       for i in range(len(aItemList)):
+            if aComponentAdd[i]==sTableName:
+               sLVal=aItemList[i][1][aItemList[i][1].find(",'")+2:aItemList[i][1].find("')")]
+                for j in range(len(aObjectList)):
+                   if aObjectList[j][:aObjectList[j].find("(")] == sLVal and sLVal!="":
+                        insVariable.append(aObjectList[j])
+
+def getList(aObjectList,host,count):
+    desktop=getDesktop()
+    doc =desktop.getCurrentComponent()
+    docinfo=doc.getDocumentInfo()
+    sMain=""
+    if not count == 0:
+        if count >= 1:
+            oParEnum = doc.getTextFields().createEnumeration()
+            while oParEnum.hasMoreElements():
+                oPar = oParEnum.nextElement()
+                if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                    sItem=oPar.Items[1]
+                    if sItem[sItem.find("(")+1:sItem.find(",")]=="objects":
+                        sMain = sItem[sItem.find(",'")+2:sItem.find("')")]
+                        oParEnum = doc.getTextFields().createEnumeration()
+                        while oParEnum.hasMoreElements():
+                            oPar = oParEnum.nextElement()
+                            if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+                                sItem=oPar.Items[1]
+                                if sItem[sItem.find("[[ ")+3:sItem.find("(")]=="repeatIn":
+                                    if sItem[sItem.find("(")+1:sItem.find(",")]=="objects":
+                                        aObjectList.append(sItem[sItem.rfind(",'")+2:sItem.rfind("')")] + "(" + docinfo.getUserFieldValue(3) + ")")
+                                    else:
+                                        sTemp=sItem[sItem.find("(")+1:sItem.find(",")]
+                                        if sMain == sTemp[:sTemp.find(".")]:
+                                            getRelation(docinfo.getUserFieldValue(3), sItem[sItem.find(".")+1:sItem.find(",")], sItem[sItem.find(",'")+2:sItem.find("')")],aObjectList,host)
+                                        else:
+                                            sPath=getPath(sItem[sItem.find("(")+1:sItem.find(",")], sMain)
+                                            getRelation(docinfo.getUserFieldValue(3), sPath, sItem[sItem.find(",'")+2:sItem.find("')")],aObjectList,host)
+    else:
+        aObjectList.append("List of " + docinfo.getUserFieldValue(3))
+
+def getRelation(sRelName, sItem, sObjName, aObjectList, host ):
+        global url
+        sock=RPCSession(url)
+        global passwd
+        res = sock.execute(database, uid, passwd, sRelName , 'fields_get')
+        key = res.keys()
+        for k in key:
+            if sItem.find(".") == -1:
+                if k == sItem:
+                    aObjectList.append(sObjName + "(" + res[k]['relation'] + ")")
+                    return 0
+           if k == sItem[:sItem.find(".")]:
+               getRelation(res[k]['relation'], sItem[sItem.find(".")+1:], sObjName,aObjectList,host)
+
+
+def getPath(sPath,sMain):
+    desktop=getDesktop()
+    doc =desktop.getCurrentComponent()
+    oParEnum = doc.getTextFields().createEnumeration()
+    while oParEnum.hasMoreElements():
+        oPar = oParEnum.nextElement()
+        if oPar.supportsService("com.sun.star.text.TextField.DropDown"):
+            sItem=oPar.Items[1]
+           if sPath[:sPath.find(".")] == sMain:
+                break;
+            else:
+                res = re.findall('\\[\\[ *([a-zA-Z0-9_\.]+) *\\]\\]',sPath)
+                if len(res) <> 0:
+                   if sItem[sItem.find(",'")+2:sItem.find("')")] == sPath[:sPath.find(".")]:
+                       sPath =  sItem[sItem.find("(")+1:sItem.find(",")] + sPath[sPath.find("."):]
+                        getPath(sPath, sMain)
+    return sPath
+
+def EnumDocument(aItemList,aComponentAdd):
+    desktop = getDesktop()
+    parent=""
+    bFlag = False
+    Doc =desktop.getCurrentComponent()
+    #oVC = Doc.CurrentController.getViewCursor()
+    oParEnum = Doc.getTextFields().createEnumeration()
+    while oParEnum.hasMoreElements():
+        oPar = oParEnum.nextElement()
+        if oPar.Anchor.TextTable:
+            #parent = oPar.Anchor.TextTable.Name
+            getChildTable(oPar.Anchor.TextTable,aItemList,aComponentAdd)
+        elif oPar.Anchor.TextSection:
+            parent = oPar.Anchor.TextSection.Name
+        elif oPar.Anchor.Text:
+            parent = "Document"
+        sItem=oPar.Items[1].replace(' ',"")
+        if sItem[sItem.find("[[ ")+3:sItem.find("(")]=="repeatIn" and not oPar.Items in aItemList:
+            templist=oPar.Items[0],sItem
+            aItemList.append( templist )
+        aComponentAdd.append( parent )
+
+def getChildTable(oPar,aItemList,aComponentAdd,sTableName=""):
+    sNames = oPar.getCellNames()
+    bEmptyTableFlag=True
+    for val in sNames:
+        oCell = oPar.getCellByName(val)
+        oCurEnum = oCell.createEnumeration()
+        while oCurEnum.hasMoreElements():
+            try:
+                oCur = oCurEnum.nextElement()
+
+                if oCur.supportsService("com.sun.star.text.TextTable"):
+                    if sTableName=="":
+                        getChildTable(oCur,aItemList,aComponentAdd,oPar.Name)
+                    else:
+                        getChildTable(oCur,aItemList,aComponentAdd,sTableName+"."+oPar.Name)
+                else:
+                    oSecEnum = oCur.createEnumeration()
+                    while oSecEnum.hasMoreElements():
+                        oSubSection = oSecEnum.nextElement()
+                        if oSubSection.supportsService("com.sun.star.text.TextField"):
+                            bEmptyTableFlag=False
+                            sItem=oSubSection.TextField.Items[1]
+                            if sItem[sItem.find("[[ ")+3:sItem.find("(")]=="repeatIn":
+                                if aItemList.__contains__(oSubSection.TextField.Items)==False:
+                                    aItemList.append(oSubSection.TextField.Items)
+                                if sTableName=="":
+                                    if  aComponentAdd.__contains__(oPar.Name)==False:
+                                        aComponentAdd.append(oPar.Name)
+                                else:
+                                    if aComponentAdd.__contains__(sTableName+"."+oPar.Name)==False:
+                                        aComponentAdd.append(sTableName+"."+oPar.Name)
+            except:
+                obj=Logger()
+                import traceback,sys
+                info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+                obj.log_write('Function', LOG_ERROR, info)
+    if bEmptyTableFlag==True:
+        aItemList.append((u'',u''))
+        if sTableName=="":
+            if  aComponentAdd.__contains__(oPar.Name)==False:
+                aComponentAdd.append(oPar.Name)
+        else:
+            if aComponentAdd.__contains__(sTableName+"."+oPar.Name)==False:
+                aComponentAdd.append(sTableName+"."+oPar.Name)
+    return 0
+
+def getRecersiveSection(oCurrentSection,aSectionList):
+        desktop=getDesktop()
+        doc =desktop.getCurrentComponent()
+        oParEnum=doc.getText().createEnumeration()
+        aSectionList.append(oCurrentSection.Name)
+        if oCurrentSection.ParentSection:
+            getRecersiveSection(oCurrentSection.ParentSection,aSectionList)
+        else:
+            return
+
+def GetAFileName():
+    oFileDialog=None
+    iAccept=None
+    sPath=""
+    InitPath=""
+    oUcb=None
+    oFileDialog = createUnoService("com.sun.star.ui.dialogs.FilePicker")
+    oUcb = createUnoService("com.sun.star.ucb.SimpleFileAccess")
+    oFileDialog.appendFilter("OpenERP Report File","*.sxw")
+    oFileDialog.setCurrentFilter("OpenERP Report File")
+    if InitPath == "":
+        InitPath =tempfile.gettempdir()
+    #End If
+    if oUcb.exists(InitPath):
+        oFileDialog.setDisplayDirectory(InitPath)
+    #End If
+    iAccept = oFileDialog.execute()
+    if iAccept == 1:
+        sPath = oFileDialog.Files[0]
+    oFileDialog.dispose()
+    return sPath
+
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/gui.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/gui.py
new file mode 100644 (file)
index 0000000..4210f2a
--- /dev/null
@@ -0,0 +1,822 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import uno
+import unohelper
+import pythonloader
+if __name__<>"package":
+    from actions import *
+
+
+#------------------------------------------------------------
+#   Uno ServiceManager access
+#   A different version of this routine and global variable
+#    is needed for code running inside a component.
+#------------------------------------------------------------
+
+
+# The ServiceManager of the running OOo.
+# It is cached in a global variable.
+goServiceManager = False
+pythonloader.DEBUG = 0
+def getServiceManager( cHost="localhost", cPort="2002" ):
+    """Get the ServiceManager from the running OpenOffice.org.
+        Then retain it in the global variable goServiceManager for future use.
+        This is similar to the GetProcessServiceManager() in OOo Basic.
+    """
+    global goServiceManager
+    global pythonloader
+    if not goServiceManager:
+        # Get the uno component context from the PyUNO runtime
+        oLocalContext = uno.getComponentContext()
+        # Create the UnoUrlResolver on the Python side.
+
+        # Connect to the running OpenOffice.org and get its context.
+        if __name__<>"package":
+            oLocalResolver = oLocalContext.ServiceManager.createInstanceWithContext(
+                                    "com.sun.star.bridge.UnoUrlResolver", oLocalContext )
+            oContext = oLocalResolver.resolve( "uno:socket,host=" + cHost + ",port=" + cPort + ";urp;StarOffice.ComponentContext" )
+        # Get the ServiceManager object
+            goServiceManager = oContext.ServiceManager
+        else:
+            goServiceManager=oLocalContext.ServiceManager
+
+    return goServiceManager
+
+
+#------------------------------------------------------------
+#   Uno convenience functions
+#   The stuff in this section is just to make
+#    python progrmaming of OOo more like using OOo Basic.
+#------------------------------------------------------------
+
+
+# This is the same as ServiceManager.createInstance( ... )
+def createUnoService( cClass ):
+    """A handy way to create a global objects within the running OOo.
+    Similar to the function of the same name in OOo Basic.
+    """
+    oServiceManager = getServiceManager()
+    oObj = oServiceManager.createInstance( cClass )
+    return oObj
+
+
+# The StarDesktop object.  (global like in OOo Basic)
+# It is cached in a global variable.
+StarDesktop = None
+def getDesktop():
+    """An easy way to obtain the Desktop object from a running OOo.
+    """
+    global StarDesktop
+    if StarDesktop == None:
+        StarDesktop = createUnoService( "com.sun.star.frame.Desktop" )
+    return StarDesktop
+# preload the StarDesktop variable.
+#getDesktop()
+
+
+# The CoreReflection object.
+# It is cached in a global variable.
+goCoreReflection = False
+def getCoreReflection():
+    global goCoreReflection
+    if not goCoreReflection:
+        goCoreReflection = createUnoService( "com.sun.star.reflection.CoreReflection" )
+    return goCoreReflection
+
+
+def createUnoStruct( cTypeName ):
+    """Create a UNO struct and return it.
+    Similar to the function of the same name in OOo Basic.
+    """
+    oCoreReflection = getCoreReflection()
+    # Get the IDL class for the type name
+    oXIdlClass = oCoreReflection.forName( cTypeName )
+    # Create the struct.
+    oReturnValue, oStruct = oXIdlClass.createObject( None )
+    return oStruct
+
+#------------------------------------------------------------
+#   API helpers
+#------------------------------------------------------------
+
+def hasUnoInterface( oObject, cInterfaceName ):
+    """Similar to Basic's HasUnoInterfaces() function, but singular not plural."""
+
+    # Get the Introspection service.
+    oIntrospection = createUnoService( "com.sun.star.beans.Introspection" )
+
+    # Now inspect the object to learn about it.
+    oObjInfo = oIntrospection.inspect( oObject )
+
+    # Obtain an array describing all methods of the object.
+    oMethods = oObjInfo.getMethods( uno.getConstantByName( "com.sun.star.beans.MethodConcept.ALL" ) )
+    # Now look at every method.
+    for oMethod in oMethods:
+        # Check the method's interface to see if
+        #  these aren't the droids you're looking for.
+        cMethodInterfaceName = oMethod.getDeclaringClass().getName()
+        if cMethodInterfaceName == cInterfaceName:
+            return True
+    return False
+
+def hasUnoInterfaces( oObject, *cInterfaces ):
+    """Similar to the function of the same name in OOo Basic."""
+    for cInterface in cInterfaces:
+        if not hasUnoInterface( oObject, cInterface ):
+            return False
+    return True
+
+#------------------------------------------------------------
+#   High level general purpose functions
+#------------------------------------------------------------
+
+
+def makePropertyValue( cName=None, uValue=None, nHandle=None, nState=None ):
+    """Create a com.sun.star.beans.PropertyValue struct and return it.
+    """
+    oPropertyValue = createUnoStruct( "com.sun.star.beans.PropertyValue" )
+
+    if cName != None:
+        oPropertyValue.Name = cName
+    if uValue != None:
+        oPropertyValue.Value = uValue
+    if nHandle != None:
+        oPropertyValue.Handle = nHandle
+    if nState != None:
+        oPropertyValue.State = nState
+
+    return oPropertyValue
+
+
+def makePoint( nX, nY ):
+    """Create a com.sun.star.awt.Point struct."""
+    oPoint = createUnoStruct( "com.sun.star.awt.Point" )
+    oPoint.X = nX
+    oPoint.Y = nY
+    return oPoint
+
+
+def makeSize( nWidth, nHeight ):
+    """Create a com.sun.star.awt.Size struct."""
+    oSize = createUnoStruct( "com.sun.star.awt.Size" )
+    oSize.Width = nWidth
+    oSize.Height = nHeight
+    return oSize
+
+
+def makeRectangle( nX, nY, nWidth, nHeight ):
+    """Create a com.sun.star.awt.Rectangle struct."""
+    oRect = createUnoStruct( "com.sun.star.awt.Rectangle" )
+    oRect.X = nX
+    oRect.Y = nY
+    oRect.Width = nWidth
+    oRect.Height = nHeight
+    return oRect
+
+
+def Array( *args ):
+    """This is just sugar coating so that code from OOoBasic which
+    contains the Array() function can work perfectly in python."""
+    tArray = ()
+    for arg in args:
+        tArray += (arg,)
+    return tArray
+
+
+def loadComponentFromURL( cUrl, tProperties=() ):
+    """Open or Create a document from it's URL.
+    New documents are created from URL's such as:
+        private:factory/sdraw
+        private:factory/swriter
+        private:factory/scalc
+        private:factory/simpress
+    """
+    StarDesktop = getDesktop()
+    oDocument = StarDesktop.loadComponentFromURL( cUrl, "_blank", 0, tProperties )
+    return oDocument
+
+
+#------------------------------------------------------------
+#   Styles
+#------------------------------------------------------------
+
+
+def defineStyle( oDrawDoc, cStyleFamily, cStyleName, cParentStyleName=None ):
+    """Add a new style to the style catalog if it is not already present.
+    This returns the style object so that you can alter its properties.
+    """
+
+    oStyleFamily = oDrawDoc.getStyleFamilies().getByName( cStyleFamily )
+
+    # Does the style already exist?
+    if oStyleFamily.hasByName( cStyleName ):
+        # then get it so we can return it.
+        oStyle = oStyleFamily.getByName( cStyleName )
+    else:
+        # Create new style object.
+        oStyle = oDrawDoc.createInstance( "com.sun.star.style.Style" )
+
+        # Set its parent style
+        if cParentStyleName != None:
+            oStyle.setParentStyle( cParentStyleName )
+
+        # Add the new style to the style family.
+        oStyleFamily.insertByName( cStyleName, oStyle )
+
+    return oStyle
+
+
+def getStyle( oDrawDoc, cStyleFamily, cStyleName ):
+    """Lookup and return a style from the document.
+    """
+    return oDrawDoc.getStyleFamilies().getByName( cStyleFamily ).getByName( cStyleName )
+
+#------------------------------------------------------------
+#   General Utility functions
+#------------------------------------------------------------
+
+
+def convertToURL( cPathname ):
+    """Convert a Windows or Linux pathname into an OOo URL."""
+    if len( cPathname ) > 1:
+        if cPathname[1:2] == ":":
+            cPathname = "/" + cPathname[0] + "|" + cPathname[2:]
+    cPathname = cPathname.replace( "\\", "/" )
+    cPathname = "file://" + cPathname
+    return cPathname
+
+# The global Awt Toolkit.
+# This is initialized the first time it is needed.
+#goAwtToolkit = createUnoService( "com.sun.star.awt.Toolkit" )
+goAwtToolkit = None
+
+def getAwtToolkit():
+    global goAwtToolkit
+    if goAwtToolkit == None:
+        goAwtToolkit = createUnoService( "com.sun.star.awt.Toolkit" )
+    return goAwtToolkit
+
+# This class builds dialog boxes.
+# This can be used in two different ways...
+# 1. by subclassing it (elegant)
+# 2. without subclassing it (less elegant)
+class DBModalDialog:
+    """Class to build a dialog box from the com.sun.star.awt.* services.
+    This doesn't do anything you couldn't already do using OOo's UNO API,
+     this just makes it much easier.
+    You can change the dialog box size, position, title, etc.
+    You can add controls, and listeners for those controls to the dialog box.
+    This class can be used by subclassing it, or without subclassing it.
+    """
+    def __init__( self, nPositionX=None, nPositionY=None, nWidth=None, nHeight=None, cTitle=None ):
+        self.oDialogModel = createUnoService( "com.sun.star.awt.UnoControlDialogModel" )
+        if nPositionX != None:  self.oDialogModel.PositionX = nPositionX
+        if nPositionY != None:  self.oDialogModel.PositionY = nPositionY
+        if nWidth     != None:  self.oDialogModel.Width     = nWidth
+        if nHeight    != None:  self.oDialogModel.Height    = nHeight
+        if cTitle     != None:  self.oDialogModel.Title     = cTitle
+        self.oDialogControl = createUnoService( "com.sun.star.awt.UnoControlDialog" )
+        self.oDialogControl.setModel( self.oDialogModel )
+
+    def release( self ):
+        """Release resources.
+        After calling this, you can no longer use this object.
+        """
+        self.oDialogControl.dispose()
+
+    #--------------------------------------------------
+    #   Dialog box adjustments
+    #--------------------------------------------------
+
+    def setDialogPosition( self, nX, nY ):
+        self.oDialogModel.PositionX = nX
+        self.oDialogModel.PositionY = nY
+
+    def setDialogSize( self, nWidth, nHeight ):
+        self.oDialogModel.Width = nWidth
+        self.oDialogModel.Height = nHeight
+
+    def setDialogTitle( self, cCaption ):
+        self.oDialogModel.Title = cCaption
+
+    def setVisible( self, bVisible ):
+        self.oDialogControl.setVisible( bVisible )
+
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoControlButton
+    #--------------------------------------------------
+
+    # After you add a Button control, you can call self.setControlModelProperty()
+    #  passing any of the properties for a...
+    #       com.sun.star.awt.UnoControlButtonModel
+    #       com.sun.star.awt.UnoControlDialogElement
+    #       com.sun.star.awt.UnoControlModel
+    def addButton( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                       cLabel=None,
+                       actionListenerProc=None,
+                       nTabIndex=None ):
+        self.addControl( "com.sun.star.awt.UnoControlButtonModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight, bDropdown=None, bMultiSelection=None,
+                         cLabel=cLabel,
+                         nTabIndex=nTabIndex )
+        if actionListenerProc != None:
+            self.addActionListenerProc( cCtrlName, actionListenerProc )
+
+    def setButtonLabel( self, cCtrlName, cLabel ):
+        """Set the label of the control."""
+        oControl = self.getControl( cCtrlName )
+        oControl.setLabel( cLabel )
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoControlEditModel
+    #--------------------------------------------------
+    def addEdit( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        cText=None,
+                        textListenerProc=None ):
+        """Add a Edit control to the window."""
+        self.addControl( "com.sun.star.awt.UnoControlEditModel",
+            cCtrlName, nPositionX, nPositionY, nWidth, nHeight, bDropdown=None)
+
+        if cText != None:
+            self.setEditText( cCtrlName, cText )
+        if textListenerProc != None:
+            self.addTextListenerProc( cCtrlName, textListenerProc )
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoControlCheckBox
+    #--------------------------------------------------
+
+    # After you add a CheckBox control, you can call self.setControlModelProperty()
+    #  passing any of the properties for a...
+    #       com.sun.star.awt.UnoControlCheckBoxModel
+    #       com.sun.star.awt.UnoControlDialogElement
+    #       com.sun.star.awt.UnoControlModel
+    def addCheckBox( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                       cLabel=None,
+                       itemListenerProc=None,
+                       nTabIndex=None ):
+        self.addControl( "com.sun.star.awt.UnoControlCheckBoxModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight, bDropdown=None,  bMultiSelection=None,
+                         cLabel=cLabel,
+                         nTabIndex=nTabIndex )
+        if itemListenerProc != None:
+            self.addItemListenerProc( cCtrlName, itemListenerProc )
+
+    def setEditText( self, cCtrlName, cText ):
+        """Set the text of the edit box."""
+        oControl = self.getControl( cCtrlName )
+        oControl.setText( cText )
+
+    def getEditText( self, cCtrlName):
+        """Set the text of the edit box."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getText()
+
+    def setCheckBoxLabel( self, cCtrlName, cLabel ):
+        """Set the label of the control."""
+        oControl = self.getControl( cCtrlName )
+        oControl.setLabel( cLabel )
+
+    def getCheckBoxState( self, cCtrlName ):
+        """Get the state of the control."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getState();
+
+    def setCheckBoxState( self, cCtrlName, nState ):
+        """Set the state of the control."""
+        oControl = self.getControl( cCtrlName )
+        oControl.setState( nState )
+
+    def enableCheckBoxTriState( self, cCtrlName, bTriStateEnable ):
+        """Enable or disable the tri state mode of the control."""
+        oControl = self.getControl( cCtrlName )
+        oControl.enableTriState( bTriStateEnable )
+
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoControlFixedText
+    #--------------------------------------------------
+
+    def addFixedText( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        cLabel=None ):
+        self.addControl( "com.sun.star.awt.UnoControlFixedTextModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                         bDropdown=None, bMultiSelection=None,
+                         cLabel=cLabel )
+
+        return self.getControl( cCtrlName )
+
+    #--------------------------------------------------
+    #   Add Controls to dialog
+    #--------------------------------------------------
+
+    def addControl( self, cCtrlServiceName,
+                        cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        bDropdown=None,
+                        bMultiSelection=None,
+                        cLabel=None,
+                        nTabIndex=None,
+                        sImagePath=None,
+                         ):
+        oControlModel = self.oDialogModel.createInstance( cCtrlServiceName )
+        self.oDialogModel.insertByName( cCtrlName, oControlModel )
+        # if negative coordinates are given for X or Y position,
+        #  then make that coordinate be relative to the right/bottom
+        #  edge of the dialog box instead of to the left/top.
+        if nPositionX < 0: nPositionX = self.oDialogModel.Width  + nPositionX - nWidth
+        if nPositionY < 0: nPositionY = self.oDialogModel.Height + nPositionY - nHeight
+        oControlModel.PositionX = nPositionX
+        oControlModel.PositionY = nPositionY
+        oControlModel.Width = nWidth
+        oControlModel.Height = nHeight
+        oControlModel.Name = cCtrlName
+
+        if bDropdown != None:
+            oControlModel.Dropdown = bDropdown
+
+        if bMultiSelection!=None:
+            oControlModel.MultiSelection=bMultiSelection
+
+        if cLabel != None:
+            oControlModel.Label = cLabel
+
+        if nTabIndex != None:
+            oControlModel.TabIndex = nTabIndex
+
+        if sImagePath != None:
+            oControlModel.ImageURL = sImagePath
+    #--------------------------------------------------
+    #   Access controls and control models
+    #--------------------------------------------------
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoContorlListBoxModel
+    #--------------------------------------------------
+
+
+    def addComboListBox( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        bDropdown=True,
+                        bMultiSelection=False,
+                        itemListenerProc=None,
+                        actionListenerProc=None,
+                        ):
+
+        mod = self.addControl( "com.sun.star.awt.UnoControlListBoxModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight,bDropdown,bMultiSelection )
+
+        if itemListenerProc != None:
+            self.addItemListenerProc( cCtrlName, itemListenerProc )
+
+    def addListBoxItems( self, cCtrlName, tcItemTexts, nPosition=0 ):
+        """Add a tupple of items to the ListBox at specified position."""
+        oControl = self.getControl( cCtrlName )
+        oControl.addItems( tcItemTexts, nPosition )
+
+    def selectListBoxItem( self, cCtrlName, cItemText, bSelect=True ):
+        """Selects/Deselects the ispecified item."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.selectItem( cItemText, bSelect )
+
+    def selectListBoxItemPos( self, cCtrlName, nItemPos, bSelect=True ):
+        """Select/Deselect the item at the specified position."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.selectItemPos( nItemPos, bSelect )
+
+    def removeListBoxItems( self, cCtrlName, nPosition, nCount=1 ):
+        """Remove items from a ListBox."""
+        oControl = self.getControl( cCtrlName )
+        oControl.removeItems( nPosition, nCount )
+
+    def getListBoxItemCount( self, cCtrlName ):
+        """Get the number of items in a ListBox."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getItemCount()
+
+    def getListBoxSelectedItem( self, cCtrlName ):
+        """Returns the currently selected item."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getSelectedItem()
+
+    def getListBoxItem( self, cCtrlName, nPosition ):
+        """Return the item at specified position within the ListBox."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getItem( nPosition )
+
+    def getListBoxSelectedItemPos(self,cCtrlName):
+
+        oControl = self.getControl( cCtrlName )
+        return oControl.getSelectedItemPos()
+
+    def getListBoxSelectedItems(self,cCtrlName):
+        oControl = self.getControl( cCtrlName )
+        return oControl.getSelectedItems()
+
+    def getListBoxSelectedItemsPos(self,cCtrlName):
+
+        oControl = self.getControl( cCtrlName )
+        return oControl.getSelectedItemsPos()
+
+    #--------------------------------------------------
+    #   com.sun.star.awt.UnoControlComboBoxModel
+    #--------------------------------------------------
+    def addComboBox( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        bDropdown=True,
+                        itemListenerProc=None,
+                        actionListenerProc=None ):
+
+        mod = self.addControl( "com.sun.star.awt.UnoControlComboBoxModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight,bDropdown)
+        if itemListenerProc != None:
+            self.addItemListenerProc( cCtrlName, itemListenerProc )
+        if actionListenerProc != None:
+            self.addActionListenerProc( cCtrlName, actionListenerProc )
+
+
+    def setComboBoxText( self, cCtrlName, cText ):
+        """Set the text of the ComboBox."""
+        oControl = self.getControl( cCtrlName )
+        oControl.setText( cText )
+
+    def getComboBoxText( self, cCtrlName):
+        """Set the text of the ComboBox."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getText()
+
+    def getComboBoxSelectedText( self, cCtrlName ):
+        """Get the selected text of the ComboBox."""
+        oControl = self.getControl( cCtrlName )
+        return oControl.getSelectedText();
+
+    def getControl( self, cCtrlName ):
+        """Get the control (not its model) for a particular control name.
+        The control returned includes the service com.sun.star.awt.UnoControl,
+         and another control-specific service which inherits from it.
+        """
+        oControl = self.oDialogControl.getControl( cCtrlName )
+        return oControl
+
+    def getControlModel( self, cCtrlName ):
+        """Get the control model (not the control) for a particular control name.
+        The model returned includes the service UnoControlModel,
+         and another control-specific service which inherits from it.
+        """
+        oControl = self.getControl( cCtrlName )
+        oControlModel = oControl.getModel()
+        return oControlModel
+    #---------------------------------------------------
+    #    com.sun.star.awt.UnoControlImageControlModel
+    #---------------------------------------------------
+    def addImageControl( self, cCtrlName, nPositionX, nPositionY, nWidth, nHeight,
+                        sImagePath="",
+                        itemListenerProc=None,
+                        actionListenerProc=None ):
+
+        mod = self.addControl( "com.sun.star.awt.UnoControlImageControlModel",
+                         cCtrlName, nPositionX, nPositionY, nWidth, nHeight, sImagePath=sImagePath)
+
+        if itemListenerProc != None:
+            self.addItemListenerProc( cCtrlName, itemListenerProc )
+        if actionListenerProc != None:
+            self.addActionListenerProc( cCtrlName, actionListenerProc )
+
+
+    #--------------------------------------------------
+    #   Adjust properties of control models
+    #--------------------------------------------------
+
+    def setControlModelProperty( self, cCtrlName, cPropertyName, uValue ):
+        """Set the value of a property of a control's model.
+        This affects the control model, not the control.
+        """
+        oControlModel = self.getControlModel( cCtrlName )
+        oControlModel.setPropertyValue( cPropertyName, uValue )
+
+    def getControlModelProperty( self, cCtrlName, cPropertyName ):
+        """Get the value of a property of a control's model.
+        This affects the control model, not the control.
+        """
+        oControlModel = self.getControlModel( cCtrlName )
+        return oControlModel.getPropertyValue( cPropertyName )
+
+    #--------------------------------------------------
+    #   Sugar coated property adjustments to control models.
+    #--------------------------------------------------
+
+    def setEnabled( self, cCtrlName, bEnabled=True ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        self.setControlModelProperty( cCtrlName, "Enabled", bEnabled )
+
+    def getEnabled( self, cCtrlName ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+
+        return self.getControlModelProperty( cCtrlName, "Enabled" )
+
+    def setState( self, cCtrlName, nState ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        self.setControlModelProperty( cCtrlName, "State", nState )
+
+    def getState( self, cCtrlName ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        return self.getControlModelProperty( cCtrlName, "State" )
+
+    def setLabel( self, cCtrlName, cLabel ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        self.setControlModelProperty( cCtrlName, "Label", cLabel )
+
+    def getLabel( self, cCtrlName ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        return self.getControlModelProperty( cCtrlName, "Label" )
+
+    def setHelpText( self, cCtrlName, cHelpText ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        self.setControlModelProperty( cCtrlName, "HelpText", cHelpText )
+
+    def getHelpText( self, cCtrlName ):
+        """Supported controls...
+            UnoControlButtonModel
+            UnoControlCheckBoxModel
+        """
+        return self.getControlModelProperty( cCtrlName, "HelpText" )
+
+
+    #--------------------------------------------------
+    #   Adjust controls (not models)
+    #--------------------------------------------------
+
+    # The following apply to all controls which are a
+    #   com.sun.star.awt.UnoControl
+
+    def setDesignMode( self, cCtrlName, bDesignMode=True ):
+        oControl = self.getControl( cCtrlName )
+        oControl.setDesignMode( bDesignMode )
+
+    def isDesignMode( self, cCtrlName, bDesignMode=True ):
+        oControl = self.getControl( cCtrlName )
+        return oControl.isDesignMode()
+
+    def isTransparent( self, cCtrlName, bDesignMode=True ):
+        oControl = self.getControl( cCtrlName )
+        return oControl.isTransparent()
+
+
+    # The following apply to all controls which are a
+    #   com.sun.star.awt.UnoControlDialogElement
+
+    def setPosition( self, cCtrlName, nPositionX, nPositionY ):
+        self.setControlModelProperty( cCtrlName, "PositionX", nPositionX )
+        self.setControlModelProperty( cCtrlName, "PositionY", nPositionY )
+    def setPositionX( self, cCtrlName, nPositionX ):
+        self.setControlModelProperty( cCtrlName, "PositionX", nPositionX )
+    def setPositionY( self, cCtrlName, nPositionY ):
+        self.setControlModelProperty( cCtrlName, "PositionY", nPositionY )
+    def getPositionX( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "PositionX" )
+    def getPositionY( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "PositionY" )
+
+    def setSize( self, cCtrlName, nWidth, nHeight ):
+        self.setControlModelProperty( cCtrlName, "Width", nWidth )
+        self.setControlModelProperty( cCtrlName, "Height", nHeight )
+    def setWidth( self, cCtrlName, nWidth ):
+        self.setControlModelProperty( cCtrlName, "Width", nWidth )
+    def setHeight( self, cCtrlName, nHeight ):
+        self.setControlModelProperty( cCtrlName, "Height", nHeight )
+    def getWidth( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "Width" )
+    def getHeight( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "Height" )
+
+    def setTabIndex( self, cCtrlName, nWidth, nTabIndex ):
+        self.setControlModelProperty( cCtrlName, "TabIndex", nTabIndex )
+    def getTabIndex( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "TabIndex" )
+
+    def setStep( self, cCtrlName, nWidth, nStep ):
+        self.setControlModelProperty( cCtrlName, "Step", nStep )
+    def getStep( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "Step" )
+
+    def setTag( self, cCtrlName, nWidth, cTag ):
+        self.setControlModelProperty( cCtrlName, "Tag", cTag )
+    def getTag( self, cCtrlName ):
+        return self.getControlModelProperty( cCtrlName, "Tag" )
+
+    def setEchoChar(self, cCtrlName , cVal):
+        self.setControlModelProperty(cCtrlName, "EchoChar", cVal)
+    def getEchoChar(self, cCtrlName):
+        return self.setControlModelProperty(cCtrlName, "EchoChar")
+
+    #--------------------------------------------------
+    #   Add listeners to controls.
+    #--------------------------------------------------
+
+    # This applies to...
+    #   UnoControlButton
+    def addActionListenerProc( self, cCtrlName, actionListenerProc ):
+        """Create an com.sun.star.awt.XActionListener object and add it to a control.
+        A listener object is created which will call the python procedure actionListenerProc.
+        The actionListenerProc can be either a method or a global procedure.
+        The following controls support XActionListener:
+            UnoControlButton
+        """
+        oControl = self.getControl( cCtrlName )
+        oActionListener = ActionListenerProcAdapter( actionListenerProc )
+        oControl.addActionListener( oActionListener )
+
+    # This applies to...
+    #   UnoControlCheckBox
+    def addItemListenerProc( self, cCtrlName, itemListenerProc ):
+        """Create an com.sun.star.awt.XItemListener object and add it to a control.
+        A listener object is created which will call the python procedure itemListenerProc.
+        The itemListenerProc can be either a method or a global procedure.
+        The following controls support XActionListener:
+            UnoControlCheckBox
+        """
+        oControl = self.getControl( cCtrlName )
+        oActionListener = ItemListenerProcAdapter( itemListenerProc )
+        oControl.addItemListener( oActionListener )
+
+    #--------------------------------------------------
+    #   Display the modal dialog.
+    #--------------------------------------------------
+
+    def doModalDialog( self, sObjName,sValue):
+        """Display the dialog as a modal dialog."""
+        self.oDialogControl.setVisible( True )
+        if not sValue==None:
+            self.selectListBoxItem( sObjName, sValue, True )
+        self.oDialogControl.execute()
+
+    def endExecute( self ):
+        """Call this from within one of the listeners to end the modal dialog.
+        For instance, the listener on your OK or Cancel button would call this to end the dialog.
+        """
+        self.oDialogControl.endExecute()
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/logreport.py
new file mode 100644 (file)
index 0000000..0e47ab6
--- /dev/null
@@ -0,0 +1,48 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import logging
+import tempfile
+LOG_DEBUG='debug'
+LOG_INFO='info'
+LOG_WARNING='warn'
+LOG_ERROR='error'
+LOG_CRITICAL='critical'
+
+def log_detail(self):
+    import os
+    logger = logging.getLogger()
+    logfile_name = os.path.join(tempfile.gettempdir(), "openerp_report_designer.log")
+    hdlr = logging.FileHandler(logfile_name)
+    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
+    hdlr.setFormatter(formatter)
+    logger.addHandler(hdlr)
+    logger.setLevel(logging.INFO)
+
+class Logger(object):
+    def log_write(self,name,level,msg):
+        log = logging.getLogger(name)
+        getattr(log,level)(msg)
+
+    def shutdown(self):
+        logging.shutdown()
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/rpc.py
new file mode 100644 (file)
index 0000000..446d000
--- /dev/null
@@ -0,0 +1,204 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import time
+import socket
+import xmlrpclib
+#import tiny_socket
+import re
+
+class RPCGateway(object):
+    def __init__(self, host, port, protocol):
+
+        self.protocol = protocol
+        self.host = host
+        self.port = port
+
+    def get_url(self):
+
+        """Get the url
+        """
+        return "%s://%s:%s/"%(self.protocol, self.host, self.port)
+
+    def listdb(self):
+        """Get the list of databases.
+        """
+        pass
+
+    def login(self, db, user, password):
+        pass
+
+    def execute(self, obj, method, *args):
+        pass
+
+
+
+class RPCSession(object):
+    def __init__(self,url):
+
+        m = re.match('^(http[s]?://|socket://)([\w.\-]+):(\d{1,5})$', url or '')
+
+        host = m.group(2)
+        port = m.group(3)
+        protocol = m.group(1)
+        if not m:
+            return -1
+        if protocol == 'http://' or protocol == 'http://':
+            self.gateway = XMLRPCGateway(host, port, 'http')
+        elif protocol == 'socket://':
+
+            self.gateway = NETRPCGateway(host, port)
+
+    def listdb(self):
+        return self.gateway.listdb()
+
+    def login(self, db, user, password):
+
+        if password is None:
+            return -1
+
+        uid = self.gateway.login(db, user or '', password or '')
+
+        if uid <= 0:
+            return -1
+
+        self.uid = uid
+        self.db = db
+        self.password = password
+        self.open = True
+        return uid
+
+
+    def execute(self, obj, method, *args):
+        try:
+            result = self.gateway.execute(obj, method, *args)
+            return self.__convert(result)
+        except Exception,e:
+          import traceback,sys
+          info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+
+    def __convert(self, result):
+
+        if isinstance(result, basestring):
+            # try to convert into unicode string
+            try:
+                return ustr(result)
+            except Exception, e:
+                return result
+
+        elif isinstance(result, list):
+            return [self.__convert(val) for val in result]
+
+        elif isinstance(result, tuple):
+            return tuple([self.__convert(val) for val in result])
+
+        elif isinstance(result, dict):
+            newres = {}
+            for key, val in result.items():
+                newres[key] = self.__convert(val)
+
+            return newres
+
+        else:
+            return result
+
+class XMLRPCGateway(RPCGateway):
+    """XML-RPC implementation.
+    """
+    def __init__(self, host, port, protocol='http'):
+
+        super(XMLRPCGateway, self).__init__(host, port, protocol)
+        global rpc_url
+        rpc_url =  self.get_url() + 'xmlrpc/'
+
+    def listdb(self):
+        global rpc_url
+        sock = xmlrpclib.ServerProxy(rpc_url + 'db')
+        try:
+            return sock.list()
+        except Exception, e:
+            return -1
+
+    def login(self, db, user, password):
+
+        global rpc_url
+
+        sock = xmlrpclib.ServerProxy(rpc_url + 'common')
+
+        try:
+            res = sock.login(db, user, password)
+        except Exception, e:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+            return -1
+
+        return res
+
+    def execute(self, sDatabase,UID,sPassword,obj, method, *args):
+        global rpc_url
+
+        sock = xmlrpclib.ServerProxy(rpc_url + 'object')
+
+        return sock.execute(sDatabase,UID,sPassword, obj ,method,*args)
+
+
+
+class NETRPCGateway(RPCGateway):
+    def __init__(self, host, port):
+
+        super(NETRPCGateway, self).__init__(host, port, 'socket')
+
+    def listdb(self):
+        sock = mysocket()
+        try:
+            sock.connect(self.host, self.port)
+            sock.mysend(('db', 'list'))
+            res = sock.myreceive()
+            sock.disconnect()
+            return res
+        except Exception, e:
+            return -1
+
+    def login(self, db, user, password):
+        sock =  mysocket()
+        try:
+            sock.connect(self.host, self.port)
+            sock.mysend(('common', 'login', db, user, password))
+            res = sock.myreceive()
+            sock.disconnect()
+        except Exception, e:
+            return -1
+        return res
+    def execute(self,obj, method, *args):
+        sock = mysocket()
+        try:
+            sock.connect(self.host, self.port)
+            data=(('object', 'execute',obj,method,)+args)
+            sock.mysend(data)
+            res=sock.myreceive()
+            sock.disconnect()
+            return res
+
+        except Exception,e:
+            import traceback,sys
+            info = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
+
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tiny_socket.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tiny_socket.py
new file mode 100644 (file)
index 0000000..38ed007
--- /dev/null
@@ -0,0 +1,93 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import socket
+import cPickle
+import cStringIO
+import marshal
+
+class Myexception(Exception):
+    def __init__(self, faultCode, faultString):
+        self.faultCode = faultCode
+        self.faultString = faultString
+        self.args = (faultCode, faultString)
+
+class mysocket:
+    def __init__(self, sock=None):
+        if sock is None:
+            self.sock = socket.socket(
+            socket.AF_INET, socket.SOCK_STREAM)
+        else:
+            self.sock = sock
+        self.sock.settimeout(120)
+    def connect(self, host, port=False):
+        if not port:
+            protocol, buf = host.split('//')
+            host, port = buf.split(':')
+        self.sock.connect((host, int(port)))
+    def disconnect(self):
+        self.sock.shutdown(socket.SHUT_RDWR)
+        self.sock.close()
+    def mysend(self, msg, exception=False, traceback=None):
+
+        msg = cPickle.dumps([msg,traceback])
+        size = len(msg)
+        self.sock.send('%8d' % size)
+        self.sock.send(exception and "1" or "0")
+        totalsent = 0
+        while totalsent < size:
+            sent = self.sock.send(msg[totalsent:])
+            if sent == 0:
+                raise RuntimeError, "socket connection broken"
+            totalsent = totalsent + sent
+    def myreceive(self):
+        buf=''
+        while len(buf) < 8:
+            chunk = self.sock.recv(8 - len(buf))
+            if chunk == '':
+                raise RuntimeError, "socket connection broken"
+            buf += chunk
+        size = int(buf)
+        buf = self.sock.recv(1)
+        if buf != "0":
+            exception = buf
+        else:
+            exception = False
+        msg = ''
+        while len(msg) < size:
+            chunk = self.sock.recv(size-len(msg))
+            if chunk == '':
+                raise RuntimeError, "socket connection broken"
+            msg = msg + chunk
+        msgio = cStringIO.StringIO(msg)
+        unpickler = cPickle.Unpickler(msgio)
+        unpickler.find_global = None
+        res = unpickler.load()
+
+        if isinstance(res[0],Exception):
+            if exception:
+                raise Myexception(str(res[0]), str(res[1]))
+            raise res[0]
+        else:
+            return res[0]
+
+
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/lib/tools.py
new file mode 100644 (file)
index 0000000..e5fa0d9
--- /dev/null
@@ -0,0 +1,40 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import urllib
+
+def get_absolute_file_path( url ):
+       url_unquoted = urllib.unquote(url)
+       return os.name == 'nt' and url_unquoted[1:] or url_unquoted 
+
+# This function reads the content of a file and return it to the caller
+def read_data_from_file( filename ):
+       fp = file( filename, "rb" )
+       data = fp.read()
+       fp.close()
+       return data
+
+# This function writes the content to a file
+def write_data_to_file( filename, data ):
+       fp = file( filename, 'wb' )
+       fp.write( data )
+       fp.close()
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py b/addons/base_report_designer/plugin/openerp_report_designer/bin/script/modify.py
new file mode 100644 (file)
index 0000000..730d5b3
--- /dev/null
@@ -0,0 +1,138 @@
+##########################################################################
+#
+# Portions of this file are under the following copyright and license:
+#
+#
+#   Copyright (c) 2003-2004 Danny Brewer 
+#   d29583@groovegarden.com 
+# 
+#   This library is free software; you can redistribute it and/or 
+#   modify it under the terms of the GNU Lesser General Public 
+#   License as published by the Free Software Foundation; either 
+#   version 2.1 of the License, or (at your option) any later version. 
+# 
+#   This library is distributed in the hope that it will be useful, 
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#   Lesser General Public License for more details. 
+# 
+#   You should have received a copy of the GNU Lesser General Public 
+#   License along with this library; if not, write to the Free Software 
+#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#   See:  http://www.gnu.org/licenses/lgpl.html 
+#
+# 
+# and other portions are under the following copyright and license:
+#
+#
+#    OpenERP, Open Source Management Solution>..
+#    Copyright (C) 2004-2010 OpenERP SA (<http://openerp.com>). 
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#
+##############################################################################
+
+import re
+import uno
+import string
+import unohelper
+import xmlrpclib
+from com.sun.star.task import XJobExecutor
+if __name__<>"package":
+    from lib.gui import *
+    from Expression import Expression
+    from Fields import Fields
+    from Repeatln import RepeatIn
+    from lib.error import *
+    database="test"
+    uid = 3
+
+class modify(unohelper.Base, XJobExecutor ):
+    def __init__( self, ctx ):
+        self.ctx     = ctx
+        self.module  = "openerp_report"
+        self.version = "0.1"
+
+        # Variable Declaration
+        desktop = getDesktop()
+        doc = desktop.getCurrentComponent()
+        docinfo = doc.getDocumentInfo()
+        self.oVC = doc.CurrentController.getViewCursor()
+        if not docinfo.getUserFieldValue(0)=="":
+            self.sMyHost= docinfo.getUserFieldValue(0)
+        else:
+            ErrorDialog(
+               "Please insert user define field Field-1",
+               "Just go to File->Properties->User Define \n"
+               "Field-1 Eg. http://localhost:8069"
+           )
+            exit(1)
+
+        # Check weather Field-4 is available or not otherwise exit from application
+        if not docinfo.getUserFieldValue(3) == "" and not docinfo.getUserFieldValue(0)=="":
+            if self.oVC.TextField:
+                self.oCurObj=self.oVC.TextField
+               item = self.oCurObj.Items[0]
+
+               kind, group1, group2 = self.getOperation(self.oCurObj.Items[1] )
+
+               start_group1 = group1[:group1.find(".")]
+               stop_group1 = group1[group1.find("."):].replace(".", "/")
+
+                if kind == "field":
+                   Fields( start_group1, stop_group1, item, True )
+                elif kind == "expression":
+                    Expression( group1, item, True )
+                elif kind == "repeatIn":
+                   RepeatIn( start_group1, group2, stop_group1, item, True )
+            else:
+                ErrorDialog(
+                   "Please place your cursor at begaining of field \n"
+                   "which you want to modify",""
+               )
+
+        else:
+            ErrorDialog(
+               "Please insert user define field Field-1 or Field-4",
+               "Just go to File->Properties->User Define \n"
+               "Field-1 Eg. http://localhost:8069 \n"
+               "OR \n"
+               "Field-4 Eg. account.invoice"
+           )
+            exit(1)
+
+    def getOperation(self, str):
+        #str = "[[ RepeatIn(objects, 'variable') ]]" #repeatIn
+        #str = "[[ saleorder.partner_id.name ]]" # field
+        #str = "[[ some thing complex ]]" # expression
+        method1 = lambda x: (u'repeatIn', x.group(1), x.group(2))
+        method2 = lambda x: (u'field', x.group(1), None)
+        method3 = lambda x: (u'expression', x.group(1), None)
+        regexes = [
+           ('\\[\\[ *repeatIn\\( *(.+)*, *\'([a-zA-Z0-9_]+)\' *\\) *\\]\\]', method1),
+           ('\\[\\[ *([a-zA-Z0-9_\.]+) *\\]\\]', method2),
+           ('\\[\\[ *(.+) *\\]\\]', method3)
+        ]
+        for (rule,method) in regexes:
+           res = re.match(rule, str)
+           if res:
+               return method(res)
+
+if __name__<>"package":
+    modify(None)
+else:
+    g_ImplementationHelper.addImplementation( modify, "org.openoffice.openerp.report.modify", ("com.sun.star.task.Job",),)
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/test/test.txt b/addons/base_report_designer/plugin/openerp_report_designer/test/test.txt
new file mode 100644 (file)
index 0000000..2d054ca
--- /dev/null
@@ -0,0 +1,57 @@
+Test Case of OpenERP Report Desinger Plugin into OpenOffice Writer
+====================================================================
+1. Connecting to the OpenERP Server
+-> OpenERP server ok
+-> OpenERP server not running
+-> Warning if base_report_designer not installed.
+
+2. Creating Report
+-> List of objects in sorted order by name
+
+3. Existing Report
+-> Exception if open non modifiable report (no sxw)
+-> List of exisiting report in sorted order
+
+4. Fields to Brackets
+-> Find the data correctly.
+-> Data for things like [[ '%.2f' % o.amount ]] is completed.
+-> Test on normal Sale Order
+-> Test on normal Purchase Order
+
+5. Modifying report
+-> Adding field if no initial repeatIn
+-> Adding fields (demo data correct)
+-> Adding loop
+-> Adding field within a loop
+-> Adding loop in a section
+-> Adding loop in a table
+-> Adding a loop in a table within a loop in a section
+-> Adding fields within a loop within a loop
+-> check context correct or not
+
+6. Modifying a field
+-> modify a field.
+-> modify a loop.
+-> modify an expression corretly
+-> Display correct data in all these cases
+
+7. Sending Report
+-> send in .SXW if user forgot to save as sxw
+-> Select with/without header
+-> Select between sxw/pdf
+-> Save as .odt and send to the server (check it is converted to sxw or warning)
+
+8. Printing Report into OpenERP clients
+-> Print report 
+-> check images appears in report correctly or not.
+-> check report With or Without Header.
+-> check SXW working or not.
+-> check PDF working or not
+
+9. Print as SXW
+-> Check Send as attachment working or not and also check it is Attached to the right document.
+
+10. Miscelleanous
+-> check the translation tag working.
+-> Save to RML. 
+
diff --git a/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py b/addons/base_report_designer/plugin/openerp_report_designer/test/test_fields.py
new file mode 100644 (file)
index 0000000..8afd773
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Use this module to retrive the fields you need according to the type
+# of the OpenOffice operation:
+#  * Insert a Field
+#  * Insert a RepeatIn
+#
+
+import xmlrpclib
+import time
+
+sock = xmlrpclib.ServerProxy('http://localhost:8069/xmlrpc/object')
+
+def get(object, level=3, ending=[], ending_excl=[], recur=[], root=''):
+       res = sock.execute('terp', 3, 'admin', 'account.invoice', 'fields_get')
+       key = res.keys()
+       key.sort()
+       for k in key:
+               if (not ending or res[k]['type'] in ending) and ((not ending_excl) or not (res[k]['type'] in ending_excl)):
+                       print root+'/'+k
+
+               if res[k]['type'] in recur:
+                       print root+'/'+k
+               if (res[k]['type'] in recur) and (level>0):
+                       get(res[k]['relation'], level-1, ending, ending_excl, recur, root+'/'+k)
+
+print 'Field selection for a rields', '='*40
+get('account.invoice', level=0, ending_excl=['one2many','many2one','many2many','reference'], recur=['many2one'])
+
+print
+print 'Field selection for a repeatIn', '='*40
+get('account.invoice', level=0, ending=['one2many','many2many'], recur=['many2one'])
+
diff --git a/addons/base_report_designer/security/base_report_security.xml b/addons/base_report_designer/security/base_report_security.xml
new file mode 100644 (file)
index 0000000..bd3854e
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<openerp>
+       <data noupdate="1">
+               <record id="res_groups_openofficereportdesigner0" model="res.groups">
+                       <field eval="[(6,0,[])]" name="menu_access"/>
+                       <field eval="[(6,0,[])]" name="rule_groups"/>
+                       <field eval="[(6,0,[ref('base.user_root')])]" name="users"/>
+                       <field eval="&quot;&quot;&quot;OpenOfficeReportDesigner&quot;&quot;&quot;" name="name"/>
+               </record>
+
+       <record id="ir_model_access_openofficereportdesigner0" model="ir.model.access">
+           <field name="model_id" ref="base.model_ir_actions_report_xml"/>
+           <field eval="1" name="perm_read"/>
+           <field eval="&quot;&quot;&quot;OpenOfficeReportDesigner&quot;&quot;&quot;" name="name"/>
+           <field eval="1" name="perm_unlink"/>
+           <field eval="1" name="perm_write"/>
+           <field eval="1" name="perm_create"/>
+           <field name="group_id" ref="res_groups_openofficereportdesigner0"/>
+       </record>
+       </data>
+
+</openerp>
index f80f87d..d2b008e 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 ##############################################################################
-#    
+#
 #    OpenERP, Open Source Management Solution
 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
 #
@@ -15,7 +15,7 @@
 #    GNU Affero General Public License for more details.
 #
 #    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
diff --git a/addons/base_report_designer/wizard/base_report_design_view.xml b/addons/base_report_designer/wizard/base_report_design_view.xml
new file mode 100644 (file)
index 0000000..504f0ab
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+     
+        <record id="view_base_report_sxw" model="ir.ui.view">
+            <field name="name">Base Report sxw</field>
+            <field name="model">base.report.sxw</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+            <form string="Get a report">
+                   <separator string="Select your report" colspan="4"/>
+                   <field name="report_id"/>
+                    <separator string="" colspan="4"/>
+                      <button special="cancel" string="Cancel" icon="gtk-cancel"/>
+                      <button name="get_report" string="Continue" type="object" icon="gtk-ok"/>
+            </form>
+            </field>
+       </record>
+
+        <record id="action_view_base_report_sxw" model="ir.actions.act_window">
+            <field name="name">Base Report sxw</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">base.report.sxw</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+        <record id="view_base_report_file_sxw" model="ir.ui.view">
+            <field name="name">Base Report File sxw</field>
+            <field name="model">base.report.file.sxw</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+            <form string="Get a report">
+            <separator string="The .SXW report" colspan="4"/>
+            <field name="report_id"/>
+            <newline/>
+            <field name="file_sxw"/>
+            <newline/>
+            <field name="file_sxw_upload"/>
+            <newline/>
+            <label colspan="4" string="This is the template of your requested report.\nSave it as a .SXW file and open it with OpenOffice.\nDon't forget to install the OpenERP SA OpenOffice package to modify it.\nOnce it is modified, re-upload it in OpenERP using this wizard." align="0.0"/>
+              <separator string="" colspan="4"/>
+              <button special="cancel" string="Cancel" icon="gtk-cancel"/>
+              <button name="upload_report" string="Upload the modified report" type="object" icon="gtk-go-forward"/>
+
+            </form>
+            </field>
+       </record>
+        <record id="view_base_report_file_rml" model="ir.ui.view">
+            <field name="name">Base Report File sxw</field>
+            <field name="model">base.report.rml.save</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+            <form string="Save RML FIle">
+                   <separator string="The RML report" colspan="4"/>
+                   <field name="file_rml"/>
+                   <newline/>
+                    <separator string="" colspan="4"/>
+               <button special="cancel" string="Cancel" icon="gtk-cancel"/>
+            </form>
+            </field>
+       </record>
+
+
+    </data>
+</openerp>
index 1af7208..e65a386 100644 (file)
@@ -2,23 +2,23 @@
 ##############################################################################
 #
 #    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
 #
 #    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
 #
 #    This program is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
+#    GNU General Public License for more details.
 #
-#    You should have received a copy of the GNU Affero General Public License
+#    You should have received a copy of the GNU General Public License
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
-
 import time
 import wizard
 import osv
@@ -27,246 +27,125 @@ import urllib
 import base64
 import tools
 from tools.translate import _
+from osv import osv, fields
 
-intro_form = '''<?xml version="1.0"?>
-<form string="Report designer">
-    <separator string="Report designer introduction" colspan="4"/>
-    <field name="text" colspan="4" nolabel="1"/>
-</form>'''
-
-intro_fields = {
-    'text': {
-        'string': 'Introduction',
-        'type': 'text',
-        'readonly': True,
-        'default': lambda *args: """This system must be used with the OpenERP SA OpenOffice plugin. If you
-did not installed yet, you can find this package on:
-    http://www.openerp.com
-
-This wizard will provide you the .SXW report that you can modify
-in OpenOffice. After having modified it, you will be able to reupload
-it to the OpenERP server.
-"""},
-    'operation': {
-        'string': 'Operation',
-        'type': 'selection',
-        'selection': [
-            ('create','Create a new report'),
-            ('modify','Modify an existing report')
-            ],
-        'size': 32,
-        'required': True,
-        'default': lambda *args: 'create',
-    },
-}
-
-get_form = '''<?xml version="1.0"?>
-<form string="Get a report">
-    <separator string="Select your report" colspan="4"/>
-    <field name="report_id"/>
-</form>'''
-
-get_fields = {
-    'report_id': {
-        'string': 'Report',
-        'type': 'many2one',
-        'relation': 'ir.actions.report.xml',
-        'required': True,
-        'domain': [('report_sxw_content','<>',False)],
-    },
-}
-
-get_form_result = '''<?xml version="1.0"?>
-<form string="Get a report">
-    <separator string="The .SXW report" colspan="4"/>
-    <field name="report_id"/>
-    <newline/>
-    <field name="file_sxw"/>
-    <newline/>
-    <label colspan="4" string="This is the template of your requested report.\nSave it as a .SXW file and open it with OpenOffice.\nDon't forget to install the OpenERP SA OpenOffice package to modify it.\nOnce it is modified, re-upload it in OpenERP using this wizard." align="0.0"/>
-</form>'''
+class base_report_sxw(osv.osv_memory):
+    """Base Report sxw """
+    _name = 'base.report.sxw'
 
-get_form_fields = {
-    'report_id': {
-        'string': 'Report',
-        'type': 'many2one',
-        'relation': 'ir.actions.report.xml',
-        'readonly': True,
-    },
-    'file_sxw': {
-        'string': 'Your .SXW file',
-        'type': 'binary',
-        'readonly': True,
+    _columns = {
+        'report_id': fields.many2one('ir.actions.report.xml', "Report", required=True,domain=[('report_sxw_content','<>',False)],),
     }
-}
 
 
-send_form_result_arch = '''<?xml version="1.0"?>
-<form string="Report modified">
-    <separator string="Report modified" colspan="4"/>
-    <label string="Your report has been modified."/>
-</form>'''
-
-send_form_result_fields = {
-}
-
-
-send_form_arch = '''<?xml version="1.0"?>
-<form string="Get a report">
-    <separator string="Upload your modified report" colspan="4"/>
-    <field name="report_id"/>
-    <newline/>
-    <field name="file_sxw"/>
-</form>'''
-
-send_form_fields = {
-    'report_id': {
-        'string': 'Report',
-        'type': 'many2one',
-        'relation': 'ir.actions.report.xml',
-        'required': True,
-        'domain': [('report_sxw_content','<>',False)]
-    },
-    'file_sxw': {
-        'string': 'Your .SXW file',
-        'type': 'binary',
-        'required': True
+    def get_report(self, cr, uid, ids, context):
+        data=self.read(cr,uid,ids)[0]
+        data_obj = self.pool.get('ir.model.data')
+        id2 = data_obj._get_id(cr, uid, 'base_report_designer', 'view_base_report_file_sxw')
+        report = self.pool.get('ir.actions.report.xml').browse(cr, uid, data['report_id'], context)
+        if id2:
+            id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+        return {
+            'view_type': 'form',
+            'view_mode': 'form',
+            'res_model': 'base.report.file.sxw',
+            'views': [(id2, 'form')],
+            'view_id': False,
+            'type': 'ir.actions.act_window',
+            'target': 'new',
+        }
+
+base_report_sxw()
+
+class base_report_file_sxw(osv.osv_memory):
+    """Base Report File sxw """
+    _name = 'base.report.file.sxw'
+
+    def default_get(self, cr, uid, fields, context=None):
+        """
+             To get default values for the object.
+
+             @param self: The object pointer.
+             @param cr: A database cursor
+             @param uid: ID of the user currently logged in
+             @param fields: List of fields for which we want default values
+             @param context: A standard dictionary
+
+             @return: A dictionary which of fields with values.
+
+        """
+
+        res = super(base_report_file_sxw, self).default_get(cr, uid, fields, context=context)
+        report_id1 = self.pool.get('base.report.sxw').search(cr,uid,[])
+        data=self.pool.get('base.report.sxw').read(cr,uid,report_id1)[0]
+        report = self.pool.get('ir.actions.report.xml').browse(cr, uid, data['report_id'], context)
+        if not context:
+            context={}
+        if 'report_id' in fields:
+            res['report_id'] = data['report_id']
+            res['file_sxw'] = base64.encodestring(report.report_sxw_content)
+        return res
+
+    _columns = {
+        'report_id': fields.many2one('ir.actions.report.xml', "Report", readonly=True),
+        'file_sxw':fields.binary('Your .SXW file',readonly=True),
+        'file_sxw_upload':fields.binary('Your .SXW file',required=True)
     }
-}
-
-rml_form_arch = '''<?xml version="1.0"?>
-<form string="Save As" colspan="4">
-    <field name="file_rml"/>
-</form>
-'''
 
-rml_form_fields = {
-       'file_rml': {
-        'string': 'Save As',
-        'type': 'binary',
-    }
-}
-
-save_rml_arch = '''<?xml version="1.0"?>
-<form string="File saved">
-    <separator string="File saved" colspan="4"/>
-    <label string="Your .rml file is saved and report has been modified."/>
-</form>'''
-
-def _get_default(obj, cursor, user, data, context):
-    return {}
-
-
-class base_report_designer_modify(wizard.interface):
-    def _upload_report_clear(self, cr, uid, data, context):
-        return {'file_sxw': False}
-
-    def _upload_report(self, cr, uid, data, context):
-        import tiny_sxw2rml
+    def upload_report(self, cr, uid, ids, context):
+        from base_report_designer import  openerp_sxw2rml
         import StringIO
-        pool = pooler.get_pool(cr.dbname)
-        sxwval = StringIO.StringIO(base64.decodestring(data['form']['file_sxw']))
-        fp = tools.file_open('normalized_oo2rml.xsl',subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
-        newrmlcontent = str(tiny_sxw2rml.sxw2rml(sxwval, xsl=fp.read()))
-        report = pool.get('ir.actions.report.xml').write(cr, uid, [data['form']['report_id']], {
-            'report_sxw_content': base64.decodestring(data['form']['file_sxw']),
+        data=self.read(cr,uid,ids)[0]
+        sxwval = StringIO.StringIO(base64.decodestring(data['file_sxw_upload']))
+        fp = tools.file_open('normalized_oo2rml.xsl',subdir='addons/base_report_designer/openerp_sxw2rml')
+        newrmlcontent = str(openerp_sxw2rml.sxw2rml(sxwval, xsl=fp.read()))
+        report = self.pool.get('ir.actions.report.xml').write(cr, uid, [data['report_id']], {
+            'report_sxw_content': base64.decodestring(data['file_sxw_upload']),
             'report_rml_content': newrmlcontent
         })
-        return {'file_rml': base64.encodestring(newrmlcontent)}
-
-    def _get_report(self, cr, uid, data, context):
-        pool = pooler.get_pool(cr.dbname)
-        report = pool.get('ir.actions.report.xml').browse(cr, uid, data['form']['report_id'], context)
-        try:
-            return {'file_sxw': base64.encodestring(report.report_sxw_content)}
-        except:
-            raise wizard.except_wizard(_('Error'), _('Report does not contain the sxw content!'))
-
-    states = {
-        'init': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': intro_form,
-                'fields': intro_fields,
-                'state': [
-                    ('end','Cancel'),
-                    ('get_form','Modify a report')
-                ]
-            }
-        },
-        'get_form': {
-            'actions': [_get_default],
-            'result': {
-                'type': 'form',
-                'arch': get_form,
-                'fields': get_fields,
-                'state': [
-                    ('end','Cancel'),
-                    ('get_form_result', 'Continue'),
-                ]
-            }
-        },
-        'get_form_result': {
-            'actions': [_get_report],
-            'result': {
-                'type': 'form',
-                'arch': get_form_result,
-                'fields': get_form_fields,
-                'state': [
-                    ('end','Close'),
-                    ('send_form', 'Upload the modified report'),
-                ]
-            }
-        },
-        'send_form': {
-            'actions': [_upload_report_clear],
-            'result': {
-                'type': 'form',
-                'arch': send_form_arch,
-                'fields': send_form_fields,
-                'state': [
-                    ('end','Close'),
-                    ('save_rml_to', 'Update the report'),
-                ]
-            }
-        },
-        'save_rml_to': {
-            'actions': [_upload_report],
-            'result': {
-                    'type': 'form',
-                    'arch': rml_form_arch,
-                    'fields': rml_form_fields,
-                    'state': [
-                            ('save_rml', 'Save rml'),
-                            ('send_form_result','Skip'),
-                        ]
-            }
-        },
-        'send_form_result': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': send_form_result_arch,
-                'fields': send_form_result_fields,
-                'state': [
-                    ('end','Close'),
-                ]
-            }
-        },
-        'save_rml': {
-            'actions': [],
-            'result': {
-                'type': 'form',
-                'arch': save_rml_arch, 'fields': {},
-                'state': [
-                    ('end','Close'),
-                ]
-            }
-        },
-    }
-
-base_report_designer_modify('base_report_designer.modify')
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
+        cr.commit()
+        data_obj = self.pool.get('ir.model.data')
+        id2 = data_obj._get_id(cr, uid, 'base_report_designer', 'view_base_report_file_rml')
+        report = self.pool.get('ir.actions.report.xml').browse(cr, uid, data['report_id'], context)
+        if id2:
+            id2 = data_obj.browse(cr, uid, id2, context=context).res_id
+        return {
+            'view_type': 'form',
+            'view_mode': 'form',
+            'res_model': 'base.report.rml.save',
+            'views': [(id2, 'form')],
+            'view_id': False,
+            'type': 'ir.actions.act_window',
+            'target': 'new',
+        }
+base_report_file_sxw()
+
+class base_report_rml_save(osv.osv_memory):
+    """Base Report file Save"""
+    _name = 'base.report.rml.save'
+    def default_get(self, cr, uid, fields, context=None):
+        """
+             To get default values for the object.
+
+             @param self: The object pointer.
+             @param cr: A database cursor
+             @param uid: ID of the user currently logged in
+             @param fields: List of fields for which we want default values
+             @param context: A standard dictionary
+             @return: A dictionary which of fields with values.
+
+        """
+        res = super(base_report_rml_save, self).default_get(cr, uid, fields, context=context)
+        report_id = self.pool.get('base.report.sxw').search(cr,uid,[])
+        data=self.pool.get('base.report.file.sxw').read(cr,uid,report_id)[0]
+        report = self.pool.get('ir.actions.report.xml').browse(cr, uid, data['report_id'], context)
+        if not context:
+            context={}
+        if 'file_rml' in fields:
+            res['file_rml'] =  base64.encodestring(report.report_rml_content)
+        return res
+    _columns = {
+         'file_rml':fields.binary('Save As'),
+         }
+
+base_report_rml_save()
diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/__init__.py b/addons/base_report_designer/wizard/tiny_sxw2rml/__init__.py
deleted file mode 100644 (file)
index ce14b22..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#    
-#    OpenERP, Open Source Management Solution
-#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.     
-#
-##############################################################################
-
-from tiny_sxw2rml import sxw2rml
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/normalized_odt2rml.xsl b/addons/base_report_designer/wizard/tiny_sxw2rml/normalized_odt2rml.xsl
deleted file mode 100644 (file)
index 50ffb3d..0000000
+++ /dev/null
@@ -1,696 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xsl:stylesheet
-  version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
-  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
-  xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
-  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
-  xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
-  xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
-  xmlns:xlink="http://www.w3.org/1999/xlink"
-  xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
-  xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
-  xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
-  xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
-  xmlns:math="http://www.w3.org/1998/Math/MathML"
-  xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
-  xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
-  office:class="text" office:version="1.1"
-  exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
-
-  <!--TODO's: indent, picture cache (trml2pdf) -->
-
-<xsl:output method="xml" indent="yes" />
-<xsl:strip-space elements="*"/>
-
-<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
-<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
-<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
-<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
-<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
-<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
-
-<xsl:template match="office:document-content">
-  <document filename="test.pdf">
-    <xsl:apply-templates select="office:automatic-styles" />
-    <xsl:apply-templates select="office:body" />
-  </document>
-</xsl:template>
-
-<xsl:template name="page_size">
-  <xsl:attribute name="pageSize">
-    <xsl:text>(</xsl:text>
-    <xsl:value-of select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
-    <xsl:text>,</xsl:text>
-    <xsl:value-of select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height" />
-    <xsl:text>)</xsl:text>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="fixed_frame">
-       <xsl:for-each select="//draw:text-box">
-               <frame>
-                       <xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
-                       <xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
-                       <xsl:attribute name="y1">
-                               <xsl:value-of
-                                       select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
-                       </xsl:attribute>
-                       <xsl:attribute name="width">
-                               <xsl:value-of select="./@svg:width" />
-                       </xsl:attribute>
-                       <xsl:attribute name="height">
-                               <xsl:value-of select="./@fo:min-height" />
-                       </xsl:attribute>
-               </frame>
-       </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="margin_sizes">
-  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-left" />
-  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-right" />
-  <xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-top" />
-  <xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-bottom" />
-  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
-  <xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-height" />
-  <xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
-  <xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
-  <xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
-  <xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
-</xsl:template>
-
-<xsl:template name="text_width">
-  <!-- You need this for the workaround to make primitive outlines-->
-  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-left" />
-  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:margin-right" />
-  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-layout[1]/style:page-layout-properties/@fo:page-width" />
-  <xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
-</xsl:template>
-
-
-
-<xsl:template match="office:automatic-styles">
-  <!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
-  <template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
-    <xsl:call-template name="page_size" />
-    <pageTemplate id="first">
-         <xsl:call-template name="fixed_frame" />
-      <frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
-        <xsl:call-template name="margin_sizes" />
-      </frame>
-    </pageTemplate>
-  </template>
-  <stylesheet>
-    <!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
-    <blockTableStyle id="Standard_Outline">
-      <blockAlignment value="LEFT"/>
-      <blockValign value="TOP"/>
-    </blockTableStyle>
-    <!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
-    <!--TODO insert table cell colors here, not within the <td> tag - otherwise
-         it will not work with flowables as cell content-->
-    <xsl:call-template name="make_blocktablestyle" />
-    <initialize>
-      <paraStyle name="all" alignment="justify" />
-    </initialize>
-    <xsl:apply-templates select="style:style" />
-  </stylesheet>
-</xsl:template>
-
-<xsl:template name="make_blocktablestyle">
-  <xsl:for-each select="//table:table">
-    <xsl:variable name="test">
-      <xsl:value-of select="./@table:name" />
-    </xsl:variable>
-    <xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
-      <!--Test if this is the first table with this style, nested tables not counted-->
-      <blockTableStyle id="{@table:name}">
-           <xsl:if test=".//draw:image">
-             <blockTopPadding value="0"/>
-             <blockBottomPadding value="0"/>
-           </xsl:if>
-        <blockAlignment value="LEFT" />
-        <blockValign value="TOP" />
-        <xsl:call-template name="make_linestyle" />
-        <xsl:call-template name="make_tablebackground" />
-      </blockTableStyle>
-    </xsl:if>
-  </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="make_linestyle">
-       <xsl:for-each select=".//table:table-row">
-               <xsl:variable name="row" select="position() - 1"/>
-               <xsl:for-each select=".//table:table-cell">
-                       <xsl:variable name="col" select="position() - 1"/>
-                       <xsl:variable name="linebefore">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-left"/>
-                       </xsl:variable>
-                       <xsl:if test="not($linebefore='') and not($linebefore='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($linebefore,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                       </xsl:if>
-                       <xsl:variable name="lineafter">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-right"/>
-                       </xsl:variable>
-                       <xsl:if test="not($lineafter='') and not($lineafter='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($lineafter,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                       </xsl:if>
-                       <xsl:variable name="lineabove">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-top"/>
-                       </xsl:variable>
-                       <xsl:if test="not($lineabove='') and not($lineabove='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($lineabove,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
-                       </xsl:if>
-                       <xsl:variable name="linebelow">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-bottom"/>
-                       </xsl:variable>
-                       <xsl:if test="not($linebelow='') and not($linebelow='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($linebelow,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
-                       </xsl:if>
-                       <xsl:variable name="grid">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border"/>
-                       </xsl:variable>
-                       <xsl:if test="not($grid='') and not($grid='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($grid,'#')"/>
-                               </xsl:variable>
-                               <!-- Don't use grid because we don't need a line between each rows -->
-                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
-                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
-                       </xsl:if>
-               </xsl:for-each>
-       </xsl:for-each>
-</xsl:template>
-
-<!-- Was needed to simulate bulleted lists:
-<xsl:template match="text:ordered-list|text:unordered-list">
-  <xsl:variable name = "text_width">
-    <xsl:call-template name="text_width" />
-  </xsl:variable>
-  <blockTable style="Standard_Outline" colWidths="18,{$text_width}">
-  <xsl:apply-templates match="text:list-item" />
-</blockTable>
-</xsl:template>
-
-<xsl:template match="text:list-item">
-  <tr>
-    <td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
-    <td>
-      <xsl:apply-templates />
-    </td>
-  </tr>
-</xsl:template>
-
--->
-
-
-<xsl:template match="office:body">
-  <story>
-    <xsl:apply-templates />
-       <xsl:for-each select="//draw:text-box">
-               <currentFrame>
-                       <xsl:attribute name="name">
-                               <xsl:value-of select="./@draw:name" />
-                       </xsl:attribute>
-               </currentFrame>
-               <xsl:apply-templates>
-                       <xsl:with-param name="skip_draw" select="0" />
-               </xsl:apply-templates>
-               <frameEnd />
-       </xsl:for-each>
-       <xsl:for-each select="//text:ordered-list">
-               <para><seqReset id="{./@text:style-name}"/></para>
-       </xsl:for-each>
-  </story>
-</xsl:template>
-
-<xsl:template match="table:table">
-  <blockTable>
-    <xsl:attribute name="colWidths">
-      <xsl:call-template name="make_columns" />
-    </xsl:attribute>
-    <xsl:call-template name="make_tableheaders" />
-    <xsl:attribute name="style">
-      <xsl:value-of select="@table:name" />
-    </xsl:attribute>
-    <xsl:apply-templates />
-  </blockTable>
-</xsl:template>
-
-<xsl:template name="make_tableheaders">
-  <xsl:if test="boolean(count(table:table-header-rows))">
-    <xsl:attribute name="repeatRows">1</xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_tablebackground">
-  <xsl:for-each select=".//table:table-row">
-    <!--Be careful when there are table:table-header-rows as
-         parent node of table:table-row -->
-    <xsl:variable name="row" select="position() - 1" />
-    <xsl:for-each select="./table:table-cell">
-      <xsl:variable name="col" select="position() - 1" />
-      <xsl:variable name="background">
-        <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
-      </xsl:variable>
-      <xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
-        <!--only RGB hexcolors are accepted -->
-               <blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},-1" />
-      </xsl:if>
-     </xsl:for-each>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="make_columns">
-  <xsl:variable name="columns" >
-    <xsl:for-each select="table:table-column">
-      <xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
-      <xsl:text>,</xsl:text>
-    </xsl:for-each>
-  </xsl:variable>
-  <xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
-  <!--strip the last comma-->
-</xsl:template>
-
-<xsl:template match="table:table-row">
-  <tr>
-    <xsl:apply-templates />
-  </tr>
-</xsl:template>
-
-<xsl:template match="table:table-cell">
-  <td>
-    <xsl:apply-templates />
-  </td>
-</xsl:template>
-
-<xsl:template match="text:section">
-  <section>
-    <xsl:apply-templates />
-  </section>
-</xsl:template>
-
-
-<xsl:template match="text:span">
-  <font>
-    <xsl:call-template name="make_fontnames_span" />
-    <xsl:call-template name="make_fontsize_span" />
-    <xsl:apply-templates />
-  </font>
-</xsl:template>
-
-<xsl:template name="make_fontsize_span">
-  <xsl:variable name ="fontsize">
-    <xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
-  </xsl:variable>
-  <xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
-    <xsl:attribute name="size">
-      <xsl:value-of select="$fontsize" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontnames_span">
-  <xsl:attribute name="face">
-    <xsl:call-template name="make_fontnames">
-      <xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name"  />
-      <xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight"  />
-      <xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
-    </xsl:call-template>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="make_image">
-  <illustration height="{.//draw:frame/@svg:height}" width="{.//draw:frame/@svg:width}">
-    <image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'Pictures/')}" height="{.//draw:frame/@svg:height}" width="{.//draw:frame/@svg:width}" />
-  </illustration>
-</xsl:template>
-
-<xsl:template name="empty_paragraph">
-  <xsl:if test="not(boolean(count(descendant::node())))">
-    <xsl:call-template name="distance_point">
-      <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
-    </xsl:call-template>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="distance_point">
-  <xsl:param name="background" />
-  <xsl:param name="tab_stop"></xsl:param>
-  <xsl:variable name="local_back">
-    <xsl:choose>
-      <xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
-        <!-- Do not accept OO colors like "transparent", only hex-colors -->
-        <xsl:text>white</xsl:text>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="$background" />
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <font color="{$local_back}">
-    <xsl:text> </xsl:text>
-    <xsl:if test="boolean($tab_stop)">
-      <!-- simulate a tabstop with white/background-color points -->
-      <xsl:text>.........</xsl:text>
-    </xsl:if>
-  </font>
-</xsl:template>
-
-<xsl:template match="text:ordered-list">
-  <xsl:apply-templates />
-
-  <!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
-       so it needs a dummy paragraph to enclose it -->
-</xsl:template>
-
-<xsl:template name="make_listitem">
-  <xsl:if test="(name(..)='text:list-item')">
-    <xsl:attribute name="leftIndent">15</xsl:attribute>
-    <xsl:attribute name="bulletIndent">0</xsl:attribute>
-    <xsl:choose>
-      <xsl:when test="(name(../..)='text:unordered-list')">
-        <xsl:variable name="fontsize">
-          <xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
-        </xsl:variable>
-        <xsl:choose>
-          <xsl:when test="$fontsize='NaN'">
-            <!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
-            <!--use a default bullet font size-->
-            <xsl:attribute name="bulletFontSize">6</xsl:attribute>
-          </xsl:when>
-          <xsl:otherwise>
-            <xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
-          </xsl:otherwise>
-        </xsl:choose>
-        <xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
-        <xsl:attribute name="bulletText">l</xsl:attribute>
-      </xsl:when>
-      <xsl:otherwise>
-        <!-- Generate the numbers for an ordered list -->
-        <xsl:variable name="size">
-          <xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
-        </xsl:variable>
-        <!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
-        <bullet>
-          <xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
-            <xsl:attribute name="size">
-              <!-- adapt the fontsize to the fontsize of the current paragraph -->
-              <xsl:value-of select="$size" />
-            </xsl:attribute>
-          </xsl:if>
-          <seq id="{../../@text:style-name}"/>.</bullet>
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template match="text:drop-down">
-    <xsl:value-of select="text:label[2]/@text:value" />
-</xsl:template>
-
-
-<xsl:template match="text:p|text:h">
-       <xsl:param name="skip_draw" select="1" />
-  <xsl:if test="boolean(key('page_break_before',@text:style-name))" >
-    <pageBreak />
-  </xsl:if>
-  <xsl:choose>
-    <xsl:when test="boolean(.//draw:image)">
-      <xsl:call-template name="make_image" />
-    </xsl:when>
-       <xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
-       </xsl:when>
-    <xsl:otherwise>
-      <para>
-        <xsl:attribute name="style">
-          <xsl:value-of select="@text:style-name" />
-        </xsl:attribute>
-        <xsl:call-template name="make_listitem" />
-        <xsl:apply-templates />
-        <xsl:call-template name="empty_paragraph" />
-      </para>
-    </xsl:otherwise>
-  </xsl:choose>
-  <xsl:if test="boolean(key('page_break_after',@text:style-name))" >
-    <pageBreak />
-  </xsl:if>
-</xsl:template>
-
-<xsl:template match="text:p/text:tab-stop">
-  <!-- simulate a tabstop -->
-  <xsl:call-template name="distance_point">
-    <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
-    <xsl:with-param name="tab_stop">yes</xsl:with-param>
-  </xsl:call-template>
-</xsl:template>
-
-<!-- experimental - switched off
-<xsl:template match="text:h">
-  <para>
-    <xsl:attribute name="style">
-      <xsl:value-of select="@text:style-name" />
-    </xsl:attribute>
-    <xsl:call-template name="make_number" />
-    <xsl:apply-templates />
-    <xsl:call-template name="empty_paragraph" />
-  </para>
-</xsl:template>
-
-<xsl:template name="make_number">
-  <xsl:choose>
-    <xsl:when test="@text:level='1'">
-      <xsl:number format="1. " />
-    </xsl:when>
-    <xsl:when test="@text:level='2'">
-      <xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
-    </xsl:when>
-  </xsl:choose>
-</xsl:template>
-
--->
-
-<xsl:template match="style:style[@style:family='paragraph']">
-  <paraStyle>
-    <xsl:attribute name="name">
-      <xsl:value-of select="@style:name" />
-    </xsl:attribute>
-    <xsl:call-template name="make_indent_paragraph" />
-    <xsl:call-template name="make_fontnames_paragraph" />
-    <xsl:call-template name="make_fontsize" />
-    <!--<xsl:call-template name="make_parent" /> not necessary -
-         parent styles processed by PyOpenOffice -->
-    <xsl:call-template name="make_alignment" />
-    <xsl:call-template name="make_background" />
-    <xsl:call-template name="make_space_beforeafter" />
-    <xsl:call-template name="make_fontcolor" />
-  </paraStyle>
-</xsl:template>
-
-<xsl:template name="make_indent_paragraph">
-  <xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
-  <xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
-  <xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
-    <xsl:attribute name="rightIndent">
-      <xsl:value-of select="$right_indent" />
-    </xsl:attribute>
-  </xsl:if>
-  <xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
-    <xsl:attribute name="leftIndent">
-      <xsl:value-of select="$left_indent" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_background">
-  <xsl:variable name="background">
-    <xsl:value-of select="style:properties/@fo:background-color" />
-  </xsl:variable>
-  <xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
-    <xsl:attribute name="backColor">
-      <xsl:value-of select="$background" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_space_beforeafter">
-  <xsl:variable name="before">
-    <xsl:value-of select="style:properties/@fo:margin-top" />
-  </xsl:variable>
-  <xsl:variable name="after">
-    <xsl:value-of select="style:properties/@fo:margin-bottom" />
-  </xsl:variable>
-  <xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
-    <xsl:attribute name="spaceBefore">
-      <xsl:value-of select="$before" />
-    </xsl:attribute>
-  </xsl:if>
-  <xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
-    <xsl:attribute name="spaceAfter">
-      <xsl:value-of select="$after" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontsize">
-  <xsl:variable name="fontSize">
-    <xsl:value-of select="style:properties/@fo:font-size" />
-  </xsl:variable>
-  <xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
-    <xsl:attribute name="fontSize">
-      <xsl:value-of select="$fontSize" />
-    </xsl:attribute>
-    <xsl:attribute name="leading">
-      <xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
-      <!--use a standard leading related to the font size -->
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<!--this template is not needed anymore for "normalized" sxw files -->
-<xsl:template name="make_parent">
-  <xsl:variable name="parent">
-    <xsl:value-of select="@style:parent-style-name" />
-  </xsl:variable>
-  <xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
-    <xsl:attribute name="parent">
-      <xsl:value-of select="$parent" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_alignment">
-  <xsl:variable name="alignment">
-    <xsl:value-of select="style:properties/@fo:text-align" />
-  </xsl:variable>
-  <xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
-    <xsl:choose>
-      <xsl:when test="$alignment='start'">
-        <xsl:attribute name="alignment">LEFT</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='center'">
-        <xsl:attribute name="alignment">CENTER</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='end'">
-        <xsl:attribute name="alignment">RIGHT</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='justify'">
-        <xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
-      </xsl:when>
-    </xsl:choose>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontnames_paragraph">
-  <xsl:attribute name="fontName">
-    <xsl:call-template name="make_fontnames">
-      <xsl:with-param name="fontName" select="style:properties/@style:font-name" />
-      <xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
-      <xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
-    </xsl:call-template>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="make_fontnames">
-  <!--much too verbose, needs improvement-->
-<xsl:param name="fontName" />
-<xsl:param name="fontWeight" />
-<xsl:param name="fontStyle" />
-<xsl:choose>
-<xsl:when test="not($fontName='') and boolean($fontName)">
-  <xsl:choose>
-    <xsl:when test="contains($fontName,'Courier')">
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Courier-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Courier-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Courier-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Courier</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:when>
-    <xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Helvetica-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Helvetica</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Helvetica-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Helvetica</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:when>
-<xsl:otherwise>
-  <!--Use this as default -->
-  <xsl:text>Helvetica</xsl:text>
-</xsl:otherwise>
-</xsl:choose>
-</xsl:template>
-
-<xsl:template name="make_fontcolor">
-  <xsl:variable name="textColor">
-    <xsl:value-of select="style:properties/@fo:color"/>
-  </xsl:variable>
-  <xsl:if test="not($textColor='') and boolean(style:properties/@fo:color)">
-  <xsl:attribute name="textColor">
-      <xsl:value-of select="$textColor" />
-   </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<!--
-This stylesheet is part of:
-PyOpenOffice Version 0.4
-Copyright (C) 2005: Martin Simon
-Homepage: www.bezirksreiter.de
-
-GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
--->
-
-</xsl:stylesheet>
-
-
diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/normalized_oo2rml.xsl b/addons/base_report_designer/wizard/tiny_sxw2rml/normalized_oo2rml.xsl
deleted file mode 100644 (file)
index 66ef0b5..0000000
+++ /dev/null
@@ -1,696 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<xsl:stylesheet
-  version="1.0"
-  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-  xmlns:fo="http://www.w3.org/1999/XSL/Format"
-  xmlns:office="http://openoffice.org/2000/office"
-  xmlns:style="http://openoffice.org/2000/style"
-  xmlns:text="http://openoffice.org/2000/text"
-  xmlns:table="http://openoffice.org/2000/table"
-  xmlns:draw="http://openoffice.org/2000/drawing"
-  xmlns:xlink="http://www.w3.org/1999/xlink"
-  xmlns:number="http://openoffice.org/2000/datastyle"
-  xmlns:svg="http://www.w3.org/2000/svg"
-  xmlns:chart="http://openoffice.org/2000/chart"
-  xmlns:dr3d="http://openoffice.org/2000/dr3d"
-  xmlns:math="http://www.w3.org/1998/Math/MathML"
-  xmlns:form="http://openoffice.org/2000/form"
-  xmlns:script="http://openoffice.org/2000/script"
-  office:class="text" office:version="1.0"
-  exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
-
-  <!--TODO's: indent, picture cache (trml2pdf) -->
-
-<xsl:output method="xml" indent="yes" />
-<xsl:strip-space elements="*"/>
-
-<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
-<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
-<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
-<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
-<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
-<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
-
-<xsl:template match="office:document-content">
-  <document filename="test.pdf">
-    <xsl:apply-templates select="office:automatic-styles" />
-    <xsl:apply-templates select="office:body" />
-  </document>
-</xsl:template>
-
-<xsl:template name="page_size">
-  <xsl:attribute name="pageSize">
-    <xsl:text>(</xsl:text>
-    <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
-    <xsl:text>,</xsl:text>
-    <xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
-    <xsl:text>)</xsl:text>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="fixed_frame">
-       <xsl:for-each select="//draw:text-box">
-               <frame>
-                       <xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
-                       <xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
-                       <xsl:attribute name="y1">
-                               <xsl:value-of
-                                       select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
-                       </xsl:attribute>
-                       <xsl:attribute name="width">
-                               <xsl:value-of select="./@svg:width" />
-                       </xsl:attribute>
-                       <xsl:attribute name="height">
-                               <xsl:value-of select="./@fo:min-height" />
-                       </xsl:attribute>
-               </frame>
-       </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="margin_sizes">
-  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
-  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
-  <xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-top" />
-  <xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-bottom" />
-  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
-  <xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
-  <xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
-  <xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
-  <xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
-  <xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
-</xsl:template>
-
-<xsl:template name="text_width">
-  <!-- You need this for the workaround to make primitive outlines-->
-  <xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
-  <xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
-  <xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
-  <xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
-</xsl:template>
-
-
-
-<xsl:template match="office:automatic-styles">
-  <!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
-  <template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
-    <xsl:call-template name="page_size" />
-    <pageTemplate id="first">
-         <xsl:call-template name="fixed_frame" />
-      <frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
-        <xsl:call-template name="margin_sizes" />
-      </frame>
-    </pageTemplate>
-  </template>
-  <stylesheet>
-    <!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
-    <blockTableStyle id="Standard_Outline">
-      <blockAlignment value="LEFT"/>
-      <blockValign value="TOP"/>
-    </blockTableStyle>
-    <!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
-    <!--TODO insert table cell colors here, not within the <td> tag - otherwise
-         it will not work with flowables as cell content-->
-    <xsl:call-template name="make_blocktablestyle" />
-    <initialize>
-      <paraStyle name="all" alignment="justify" />
-    </initialize>
-    <xsl:apply-templates select="style:style" />
-  </stylesheet>
-</xsl:template>
-
-<xsl:template name="make_blocktablestyle">
-  <xsl:for-each select="//table:table">
-    <xsl:variable name="test">
-      <xsl:value-of select="./@table:name" />
-    </xsl:variable>
-    <xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
-      <!--Test if this is the first table with this style, nested tables not counted-->
-      <blockTableStyle id="{@table:name}">
-           <xsl:if test=".//draw:image">
-             <blockTopPadding value="0"/>
-             <blockBottomPadding value="0"/>
-           </xsl:if>
-        <blockAlignment value="LEFT" />
-        <blockValign value="TOP" />
-        <xsl:call-template name="make_linestyle" />
-        <xsl:call-template name="make_tablebackground" />
-      </blockTableStyle>
-    </xsl:if>
-  </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="make_linestyle">
-       <xsl:for-each select=".//table:table-row">
-               <xsl:variable name="row" select="position() - 1"/>
-               <xsl:for-each select=".//table:table-cell">
-                       <xsl:variable name="col" select="position() - 1"/>
-                       <xsl:variable name="linebefore">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-left"/>
-                       </xsl:variable>
-                       <xsl:if test="not($linebefore='') and not($linebefore='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($linebefore,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                       </xsl:if>
-                       <xsl:variable name="lineafter">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-right"/>
-                       </xsl:variable>
-                       <xsl:if test="not($lineafter='') and not($lineafter='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($lineafter,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                       </xsl:if>
-                       <xsl:variable name="lineabove">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-top"/>
-                       </xsl:variable>
-                       <xsl:if test="not($lineabove='') and not($lineabove='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($lineabove,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
-                       </xsl:if>
-                       <xsl:variable name="linebelow">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-bottom"/>
-                       </xsl:variable>
-                       <xsl:if test="not($linebelow='') and not($linebelow='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($linebelow,'#')"/>
-                               </xsl:variable>
-                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
-                       </xsl:if>
-                       <xsl:variable name="grid">
-                               <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border"/>
-                       </xsl:variable>
-                       <xsl:if test="not($grid='') and not($grid='none')">
-                               <xsl:variable name="colorname">
-                                       <xsl:value-of select="substring-after($grid,'#')"/>
-                               </xsl:variable>
-                               <!-- Don't use grid because we don't need a line between each rows -->
-                               <lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                               <lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
-                               <lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
-                               <lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
-                       </xsl:if>
-               </xsl:for-each>
-       </xsl:for-each>
-</xsl:template>
-
-<!-- Was needed to simulate bulleted lists:
-<xsl:template match="text:ordered-list|text:unordered-list">
-  <xsl:variable name = "text_width">
-    <xsl:call-template name="text_width" />
-  </xsl:variable>
-  <blockTable style="Standard_Outline" colWidths="18,{$text_width}">
-  <xsl:apply-templates match="text:list-item" />
-</blockTable>
-</xsl:template>
-
-<xsl:template match="text:list-item">
-  <tr>
-    <td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
-    <td>
-      <xsl:apply-templates />
-    </td>
-  </tr>
-</xsl:template>
-
--->
-
-
-<xsl:template match="office:body">
-  <story>
-    <xsl:apply-templates />
-       <xsl:for-each select="//draw:text-box">
-               <currentFrame>
-                       <xsl:attribute name="name">
-                               <xsl:value-of select="./@draw:name" />
-                       </xsl:attribute>
-               </currentFrame>
-               <xsl:apply-templates>
-                       <xsl:with-param name="skip_draw" select="0" />
-               </xsl:apply-templates>
-               <frameEnd />
-       </xsl:for-each>
-       <xsl:for-each select="//text:ordered-list">
-               <para><seqReset id="{./@text:style-name}"/></para>
-       </xsl:for-each>
-  </story>
-</xsl:template>
-
-<xsl:template match="table:table">
-  <blockTable>
-    <xsl:attribute name="colWidths">
-      <xsl:call-template name="make_columns" />
-    </xsl:attribute>
-    <xsl:call-template name="make_tableheaders" />
-    <xsl:attribute name="style">
-      <xsl:value-of select="@table:name" />
-    </xsl:attribute>
-    <xsl:apply-templates />
-  </blockTable>
-</xsl:template>
-
-<xsl:template name="make_tableheaders">
-  <xsl:if test="boolean(count(table:table-header-rows))">
-    <xsl:attribute name="repeatRows">1</xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_tablebackground">
-  <xsl:for-each select=".//table:table-row">
-    <!--Be careful when there are table:table-header-rows as
-         parent node of table:table-row -->
-    <xsl:variable name="row" select="position() - 1" />
-    <xsl:for-each select="./table:table-cell">
-      <xsl:variable name="col" select="position() - 1" />
-      <xsl:variable name="background">
-        <xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
-      </xsl:variable>
-      <xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
-        <!--only RGB hexcolors are accepted -->
-               <blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},-1" />
-      </xsl:if>
-     </xsl:for-each>
-   </xsl:for-each>
-</xsl:template>
-
-<xsl:template name="make_columns">
-  <xsl:variable name="columns" >
-    <xsl:for-each select="table:table-column">
-      <xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
-      <xsl:text>,</xsl:text>
-    </xsl:for-each>
-  </xsl:variable>
-  <xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
-  <!--strip the last comma-->
-</xsl:template>
-
-<xsl:template match="table:table-row">
-  <tr>
-    <xsl:apply-templates />
-  </tr>
-</xsl:template>
-
-<xsl:template match="table:table-cell">
-  <td>
-    <xsl:apply-templates />
-  </td>
-</xsl:template>
-
-<xsl:template match="text:section">
-  <section>
-    <xsl:apply-templates />
-  </section>
-</xsl:template>
-
-
-<xsl:template match="text:span">
-  <font>
-    <xsl:call-template name="make_fontnames_span" />
-    <xsl:call-template name="make_fontsize_span" />
-    <xsl:apply-templates />
-  </font>
-</xsl:template>
-
-<xsl:template name="make_fontsize_span">
-  <xsl:variable name ="fontsize">
-    <xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
-  </xsl:variable>
-  <xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
-    <xsl:attribute name="size">
-      <xsl:value-of select="$fontsize" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontnames_span">
-  <xsl:attribute name="face">
-    <xsl:call-template name="make_fontnames">
-      <xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name"  />
-      <xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight"  />
-      <xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
-    </xsl:call-template>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="make_image">
-  <illustration height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}">
-    <image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'#Pictures/')}" height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}" />
-  </illustration>
-</xsl:template>
-
-<xsl:template name="empty_paragraph">
-  <xsl:if test="not(boolean(count(descendant::node())))">
-    <xsl:call-template name="distance_point">
-      <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
-    </xsl:call-template>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="distance_point">
-  <xsl:param name="background" />
-  <xsl:param name="tab_stop"></xsl:param>
-  <xsl:variable name="local_back">
-    <xsl:choose>
-      <xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
-        <!-- Do not accept OO colors like "transparent", only hex-colors -->
-        <xsl:text>white</xsl:text>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="$background" />
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <font color="{$local_back}">
-    <xsl:text> </xsl:text>
-    <xsl:if test="boolean($tab_stop)">
-      <!-- simulate a tabstop with white/background-color points -->
-      <xsl:text>.........</xsl:text>
-    </xsl:if>
-  </font>
-</xsl:template>
-
-<xsl:template match="text:ordered-list">
-  <xsl:apply-templates />
-
-  <!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
-       so it needs a dummy paragraph to enclose it -->
-</xsl:template>
-
-<xsl:template name="make_listitem">
-  <xsl:if test="(name(..)='text:list-item')">
-    <xsl:attribute name="leftIndent">15</xsl:attribute>
-    <xsl:attribute name="bulletIndent">0</xsl:attribute>
-    <xsl:choose>
-      <xsl:when test="(name(../..)='text:unordered-list')">
-        <xsl:variable name="fontsize">
-          <xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
-        </xsl:variable>
-        <xsl:choose>
-          <xsl:when test="$fontsize='NaN'">
-            <!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
-            <!--use a default bullet font size-->
-            <xsl:attribute name="bulletFontSize">6</xsl:attribute>
-          </xsl:when>
-          <xsl:otherwise>
-            <xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
-          </xsl:otherwise>
-        </xsl:choose>
-        <xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
-        <xsl:attribute name="bulletText">l</xsl:attribute>
-      </xsl:when>
-      <xsl:otherwise>
-        <!-- Generate the numbers for an ordered list -->
-        <xsl:variable name="size">
-          <xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
-        </xsl:variable>
-        <!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
-        <bullet>
-          <xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
-            <xsl:attribute name="size">
-              <!-- adapt the fontsize to the fontsize of the current paragraph -->
-              <xsl:value-of select="$size" />
-            </xsl:attribute>
-          </xsl:if>
-          <seq id="{../../@text:style-name}"/>.</bullet>
-
-      </xsl:otherwise>
-    </xsl:choose>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template match="text:drop-down">
-    <xsl:value-of select="text:label[2]/@text:value" />
-</xsl:template>
-
-
-<xsl:template match="text:p|text:h">
-       <xsl:param name="skip_draw" select="1" />
-  <xsl:if test="boolean(key('page_break_before',@text:style-name))" >
-    <pageBreak />
-  </xsl:if>
-  <xsl:choose>
-    <xsl:when test="boolean(.//draw:image)">
-      <xsl:call-template name="make_image" />
-    </xsl:when>
-       <xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
-       </xsl:when>
-    <xsl:otherwise>
-      <para>
-        <xsl:attribute name="style">
-          <xsl:value-of select="@text:style-name" />
-        </xsl:attribute>
-        <xsl:call-template name="make_listitem" />
-        <xsl:apply-templates />
-        <xsl:call-template name="empty_paragraph" />
-      </para>
-    </xsl:otherwise>
-  </xsl:choose>
-  <xsl:if test="boolean(key('page_break_after',@text:style-name))" >
-    <pageBreak />
-  </xsl:if>
-</xsl:template>
-
-<xsl:template match="text:p/text:tab-stop">
-  <!-- simulate a tabstop -->
-  <xsl:call-template name="distance_point">
-    <xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
-    <xsl:with-param name="tab_stop">yes</xsl:with-param>
-  </xsl:call-template>
-</xsl:template>
-
-<!-- experimental - switched off
-<xsl:template match="text:h">
-  <para>
-    <xsl:attribute name="style">
-      <xsl:value-of select="@text:style-name" />
-    </xsl:attribute>
-    <xsl:call-template name="make_number" />
-    <xsl:apply-templates />
-    <xsl:call-template name="empty_paragraph" />
-  </para>
-</xsl:template>
-
-<xsl:template name="make_number">
-  <xsl:choose>
-    <xsl:when test="@text:level='1'">
-      <xsl:number format="1. " />
-    </xsl:when>
-    <xsl:when test="@text:level='2'">
-      <xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
-    </xsl:when>
-  </xsl:choose>
-</xsl:template>
-
--->
-
-<xsl:template match="style:style[@style:family='paragraph']">
-  <paraStyle>
-    <xsl:attribute name="name">
-      <xsl:value-of select="@style:name" />
-    </xsl:attribute>
-    <xsl:call-template name="make_indent_paragraph" />
-    <xsl:call-template name="make_fontnames_paragraph" />
-    <xsl:call-template name="make_fontsize" />
-    <!--<xsl:call-template name="make_parent" /> not necessary -
-         parent styles processed by PyOpenOffice -->
-    <xsl:call-template name="make_alignment" />
-    <xsl:call-template name="make_background" />
-    <xsl:call-template name="make_space_beforeafter" />
-    <xsl:call-template name="make_fontcolor" />
-  </paraStyle>
-</xsl:template>
-
-<xsl:template name="make_indent_paragraph">
-  <xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
-  <xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
-  <xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
-    <xsl:attribute name="rightIndent">
-      <xsl:value-of select="$right_indent" />
-    </xsl:attribute>
-  </xsl:if>
-  <xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
-    <xsl:attribute name="leftIndent">
-      <xsl:value-of select="$left_indent" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_background">
-  <xsl:variable name="background">
-    <xsl:value-of select="style:properties/@fo:background-color" />
-  </xsl:variable>
-  <xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
-    <xsl:attribute name="backColor">
-      <xsl:value-of select="$background" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_space_beforeafter">
-  <xsl:variable name="before">
-    <xsl:value-of select="style:properties/@fo:margin-top" />
-  </xsl:variable>
-  <xsl:variable name="after">
-    <xsl:value-of select="style:properties/@fo:margin-bottom" />
-  </xsl:variable>
-  <xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
-    <xsl:attribute name="spaceBefore">
-      <xsl:value-of select="$before" />
-    </xsl:attribute>
-  </xsl:if>
-  <xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
-    <xsl:attribute name="spaceAfter">
-      <xsl:value-of select="$after" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontsize">
-  <xsl:variable name="fontSize">
-    <xsl:value-of select="style:properties/@fo:font-size" />
-  </xsl:variable>
-  <xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
-    <xsl:attribute name="fontSize">
-      <xsl:value-of select="$fontSize" />
-    </xsl:attribute>
-    <xsl:attribute name="leading">
-      <xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
-      <!--use a standard leading related to the font size -->
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<!--this template is not needed anymore for "normalized" sxw files -->
-<xsl:template name="make_parent">
-  <xsl:variable name="parent">
-    <xsl:value-of select="@style:parent-style-name" />
-  </xsl:variable>
-  <xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
-    <xsl:attribute name="parent">
-      <xsl:value-of select="$parent" />
-    </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_alignment">
-  <xsl:variable name="alignment">
-    <xsl:value-of select="style:properties/@fo:text-align" />
-  </xsl:variable>
-  <xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
-    <xsl:choose>
-      <xsl:when test="$alignment='start'">
-        <xsl:attribute name="alignment">LEFT</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='center'">
-        <xsl:attribute name="alignment">CENTER</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='end'">
-        <xsl:attribute name="alignment">RIGHT</xsl:attribute>
-      </xsl:when>
-      <xsl:when test="$alignment='justify'">
-        <xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
-      </xsl:when>
-    </xsl:choose>
-  </xsl:if>
-</xsl:template>
-
-<xsl:template name="make_fontnames_paragraph">
-  <xsl:attribute name="fontName">
-    <xsl:call-template name="make_fontnames">
-      <xsl:with-param name="fontName" select="style:properties/@style:font-name" />
-      <xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
-      <xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
-    </xsl:call-template>
-  </xsl:attribute>
-</xsl:template>
-
-<xsl:template name="make_fontnames">
-  <!--much too verbose, needs improvement-->
-<xsl:param name="fontName" />
-<xsl:param name="fontWeight" />
-<xsl:param name="fontStyle" />
-<xsl:choose>
-<xsl:when test="not($fontName='') and boolean($fontName)">
-  <xsl:choose>
-    <xsl:when test="contains($fontName,'Courier')">
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Courier-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Courier-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Courier-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Courier</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:when>
-    <xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Helvetica-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Helvetica</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:when>
-    <xsl:otherwise>
-      <xsl:choose>
-        <xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-BoldOblique</xsl:text>
-        </xsl:when>
-        <xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
-          <xsl:text>Helvetica-Bold</xsl:text>
-        </xsl:when>
-        <xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
-          <xsl:text>Helvetica-Oblique</xsl:text>
-        </xsl:when>
-        <xsl:otherwise>
-          <xsl:text>Helvetica</xsl:text>
-        </xsl:otherwise>
-      </xsl:choose>
-    </xsl:otherwise>
-  </xsl:choose>
-</xsl:when>
-<xsl:otherwise>
-  <!--Use this as default -->
-  <xsl:text>Helvetica</xsl:text>
-</xsl:otherwise>
-</xsl:choose>
-</xsl:template>
-<xsl:template name="make_fontcolor">
-  <xsl:variable name="textColor">
-    <xsl:value-of select="style:properties/@fo:color"/>
-  </xsl:variable>
-  <xsl:if test="not($textColor='') and boolean(style:properties/@fo:color)">
-  <xsl:attribute name="textColor">
-      <xsl:value-of select="$textColor" />
-   </xsl:attribute>
-  </xsl:if>
-</xsl:template>
-
-<!--
-This stylesheet is part of:
-PyOpenOffice Version 0.4
-Copyright (C) 2005: Martin Simon
-Homepage: www.bezirksreiter.de
-
-GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
--->
-
-</xsl:stylesheet>
-
-
diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/office.dtd b/addons/base_report_designer/wizard/tiny_sxw2rml/office.dtd
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py b/addons/base_report_designer/wizard/tiny_sxw2rml/tiny_sxw2rml.py
deleted file mode 100644 (file)
index 1a29324..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# Copyright (c):
-#
-#     2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
-#     2005 Fabien Pinckaers, TINY SPRL. (http://tiny.be)
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-#!/usr/bin/python
-"""
-Tiny SXW2RML - The OpenERP's report engine
-
-Tiny SXW2RMLis part of the Tiny report project.
-Tiny Report is a module that allows you to render high quality PDF document
-from an OpenOffice template (.sxw) and any relationnal database.
-
-The whole source code is distributed under the terms of the
-GNU Public Licence.
-
-(c) 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
-(c) 2005-TODAY, Fabien Pinckaers - Tiny sprl
-"""
-__version__ = '0.9'
-
-
-import re
-import string
-import os
-import zipfile
-import xml.dom.minidom
-from reportlab.lib.units import toLength
-import base64
-import copy
-
-class DomApiGeneral:
-    """General DOM API utilities."""
-    def __init__(self,content_string="",file=""):
-        self.content_string = content_string
-        self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)")
-
-    def _unitTuple(self,string):
-        """Split values and units to a tuple."""
-        temp = self.re_digits.findall(string)
-        if not temp:
-            return (string,"")
-        else:
-            return (temp[0])
-
-    def stringPercentToFloat(self,string):
-        temp = string.replace("""%""","")
-        return float(temp)/100
-
-    def findChildrenByName(self,parent,name,attr_dict={}):
-        """Helper functions. Does not work recursively.
-        Optional: also test for certain attribute/value pairs."""
-        children = []
-        for c in parent.childNodes:
-            if c.nodeType == c.ELEMENT_NODE and c.nodeName == name:
-                children.append(c)
-        if attr_dict == {}:
-            return children
-        else:
-            return self._selectForAttributes(nodelist=children,attr_dict=attr_dict)
-
-    def _selectForAttributes(self,nodelist,attr_dict):
-        "Helper function."""
-        selected_nodes = []
-        for n in nodelist:
-            check = 1
-            for a in attr_dict.keys():
-                if n.getAttribute(a) != attr_dict[a]:
-                    # at least one incorrect attribute value?
-                    check = 0
-            if check:
-                selected_nodes.append(n)
-        return selected_nodes
-
-    def _stringToTuple(self,s):
-        """Helper function."""
-        try:
-            temp = string.split(s,",")
-            return int(temp[0]),int(temp[1])
-        except:
-            return None
-
-    def _tupleToString(self,t):
-        try:
-            return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1]))
-        except:
-            return None
-
-    def _lengthToFloat(self,value):
-        v = value
-        if not self.re_digits.search(v):
-            return v
-        try:
-            if v[-4:] == "inch":
-                # OO files use "inch" instead of "in" in Reportlab units
-                v = v[:-2]
-        except:
-            pass
-        try:
-            c = round(toLength(v))
-            return c
-        except:
-            return v
-
-    def openOfficeStringUtf8(self,string):
-        if type(string) == unicode:
-            return string.encode("utf-8")
-        tempstring = unicode(string,"cp1252").encode("utf-8")
-        return tempstring
-
-class DomApi(DomApiGeneral):
-    """This class provides a DOM-API for XML-Files from an SXW-Archive."""
-    def __init__(self,xml_content,xml_styles):
-        DomApiGeneral.__init__(self)
-        self.content_dom = xml.dom.minidom.parseString(xml_content)
-        self.styles_dom = xml.dom.minidom.parseString(xml_styles)
-        body = self.content_dom.getElementsByTagName("office:body")
-        self.body = body and body[0]
-
-        # TODO:
-        self.style_dict = {}
-        self.style_properties_dict = {}
-
-        # ******** always use the following order:
-        self.buildStyleDict()
-        self.buildStylePropertiesDict()
-        if self.styles_dom.getElementsByTagName("style:page-master").__len__()<>0:
-            self.page_master = self.styles_dom.getElementsByTagName("style:page-master")[0]
-        if  self.styles_dom.getElementsByTagName("style:page-layout").__len__()<>0 :
-                       self.page_master = self.styles_dom.getElementsByTagName("style:page-layout")[0]        
-        self.document = self.content_dom.getElementsByTagName("office:document-content")[0]
-
-    def buildStylePropertiesDict(self):
-        for s in self.style_dict.keys():
-            self.style_properties_dict[s] = self.getStylePropertiesDict(s)
-
-    def updateWithPercents(self,dict,updatedict):
-        """Sometimes you find values like "115%" in the style hierarchy."""
-        if not updatedict:
-            # no style hierarchies for this style? =>
-            return
-        new_updatedict = copy.copy(updatedict)
-        for u in new_updatedict.keys():
-            try:
-                if new_updatedict[u].find("""%""") != -1 and dict.has_key(u):
-                    number = float(self.re_digits.search(dict[u]).group(1))
-                    unit = self.re_digits.search(dict[u]).group(2)
-                    new_number = self.stringPercentToFloat(new_updatedict[u]) * number
-                    if unit == "pt":
-                        new_number = int(new_number)
-                        # no floats allowed for "pt"
-                        # OOo just takes the int, does not round (try it out!)
-                    new_updatedict[u] = "%s%s" % (new_number,unit)
-                else:
-                    dict[u] = new_updatedict[u]
-            except:
-                dict[u] = new_updatedict[u]
-        dict.update(new_updatedict)
-
-    def normalizeStyleProperties(self):
-        """Transfer all style:style-properties attributes from the
-        self.style_properties_hierarchical dict to the automatic-styles
-        from content.xml. Use this function to preprocess content.xml for
-        XSLT transformations etc.Do not try to implement this function
-        with XSlT - believe me, it's a terrible task..."""
-        styles_styles = self.styles_dom.getElementsByTagName("style:style")
-        automatic_styles = self.content_dom.getElementsByTagName("office:automatic-styles")[0]
-        for s in styles_styles:
-            automatic_styles.appendChild(s.cloneNode(deep=1))
-        content_styles = self.content_dom.getElementsByTagName("style:style")
-        # these are the content_styles with styles_styles added!!!
-        for s in content_styles:
-            c = self.findChildrenByName(s,"style:properties")
-            if c == []:
-                # some derived automatic styles do not have "style:properties":
-                temp = self.content_dom.createElement("style:properties")
-                s.appendChild(temp)
-                c = self.findChildrenByName(s,"style:properties")
-            c = c[0]
-            dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("utf-8")] or {}
-            for attribute in dict.keys():
-                c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
-
-    def transferStylesXml(self):
-        """Transfer certain sub-trees from styles.xml to the normalized content.xml
-        (see above). It is not necessary to do this - for example - with paragraph styles.
-        the "normalized" style properties contain all information needed for
-        further processing."""
-        # TODO: What about table styles etc.?
-        outline_styles = self.styles_dom.getElementsByTagName("text:outline-style")
-        t = self.content_dom.createElement("transferredfromstylesxml")
-        self.document.insertBefore(t,self.body)
-        t_new = self.body.previousSibling
-        try:
-            page_master = self.page_master
-            t_new.appendChild(page_master.cloneNode(deep=1))
-            t_new.appendChild(outline_styles[0].cloneNode(deep=1))
-        except:
-            pass
-
-    def normalizeLength(self):
-        """Normalize all lengthes to floats (i.e: 1 inch = 72).
-        Always use this after "normalizeContent" and "transferStyles"!"""
-        # TODO: The complex attributes of table cell styles are not transferred yet.
-        #all_styles = self.content_dom.getElementsByTagName("style:properties")
-        #all_styles += self.content_dom.getElementsByTagName("draw:image")
-        all_styles = self.content_dom.getElementsByTagName("*")
-        for s in all_styles:
-            for x in s._attrs.keys():
-                v = s.getAttribute(x)
-                s.setAttribute(x,"%s" % self._lengthToFloat(v))
-                # convert float to string first!
-
-    def normalizeTableColumns(self):
-        """Handle this strange table:number-columns-repeated attribute."""
-        columns = self.content_dom.getElementsByTagName("table:table-column")
-        for c in columns:
-            if c.hasAttribute("table:number-columns-repeated"):
-                number = int(c.getAttribute("table:number-columns-repeated"))
-                c.removeAttribute("table:number-columns-repeated")
-                for i in range(number-1):
-                    (c.parentNode).insertBefore(c.cloneNode(deep=1),c)
-
-    def buildStyleDict(self):
-        """Store all style:style-nodes from content.xml and styles.xml in self.style_dict.
-        Caution: in this dict the nodes from two dom apis are merged!"""
-        for st in (self.styles_dom,self.content_dom):
-            for s in st.getElementsByTagName("style:style"):
-                name = s.getAttribute("style:name").encode("utf-8")
-                self.style_dict[name] = s
-        return True
-
-    def toxml(self):
-        return self.content_dom.toxml(encoding="utf-8")
-
-    def getStylePropertiesDict(self,style_name):
-        res = {}
-
-        if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
-            parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("utf-8")
-            res = self.getStylePropertiesDict(parent)
-
-        childs = self.style_dict[style_name].childNodes
-        for c in childs:
-            if c.nodeType == c.ELEMENT_NODE and c.nodeName.find("properties")>0 :
-                for attr in c._attrs.keys():
-                    res[attr] = c.getAttribute(attr).encode("utf-8")
-        return res
-
-class PyOpenOffice(object):
-    """This is the main class which provides all functionality."""
-    def __init__(self, path='.', save_pict=False):
-        self.path = path
-        self.save_pict = save_pict
-        self.images = {}
-
-    def oo_read(self,fname):
-        z = zipfile.ZipFile(fname,"r")
-        content = z.read('content.xml')
-        style = z.read('styles.xml')
-        all = z.namelist()
-        for a in all:
-            if a[:9]=='Pictures/' and len(a)>10:
-                pic_content = z.read(a)
-                self.images[a[9:]] = pic_content
-                if self.save_pict:
-                    f=open(os.path.join(self.path, os.path.basename(a)),"wb")
-                    f.write(pic_content)
-                    f.close()
-        z.close()
-        return content,style
-
-    def oo_replace(self,content):
-        regex = [
-            (r"<para[^>]*/>", ""),
-            (r"<para(.*)>(.*?)<text:line-break[^>]*/>", "<para$1>$2</para><para$1>"),
-        ]
-        for key,val in regex:
-            content = re.sub(key, val, content)
-        return content
-
-    def unpackNormalize(self,sourcefile):
-        c,s = self.oo_read(sourcefile)
-        c = self.oo_replace(c)
-        dom = DomApi(c,s)
-        dom.normalizeStyleProperties()
-        dom.transferStylesXml()
-        dom.normalizeLength()
-        dom.normalizeTableColumns()
-        new_c = dom.toxml()
-        return new_c
-
-def sxw2rml(sxw_file, xsl, output='.', save_pict=False):
-    from lxml import etree
-    from StringIO import StringIO
-
-    tool = PyOpenOffice(output, save_pict = save_pict)
-    res = tool.unpackNormalize(sxw_file)
-    
-    f = StringIO(xsl)
-    styledoc = etree.parse(f)
-    style = etree.XSLT(styledoc)
-    
-    f = StringIO(res)
-    doc = etree.parse(f)
-    result = style(doc)
-    root = etree.XPathEvaluator(result)("/document/stylesheet")
-    
-    if root:
-        root=root[0]
-        images = etree.Element("images")
-        for img in tool.images:
-            node = etree.Element('image', name=img)
-            node.text = base64.encodestring(tool.images[img])
-            images.append(node)
-        root.append(images)
-
-    try:
-        xml = str(result)
-        return xml
-    except:
-        return result
-
-if __name__ == "__main__":
-    import optparse
-    parser = optparse.OptionParser(
-        version="Tiny Report v%s" % __version__,
-        usage = 'tiny_sxw2rml.py [options] file.sxw')
-    parser.add_option("-v", "--verbose", default=False, dest="verbose", help="enable basic debugging")
-    parser.add_option("-o", "--output", dest="output", default='.', help="directory of image output")
-    (opt, args) = parser.parse_args()
-    if len(args) != 1:
-        parser.error("incorrect number of arguments")
-
-    import sys
-    import StringIO
-
-    fname = sys.argv[1]
-    f = fname
-    xsl_file = 'normalized_oo2rml.xsl'
-    z = zipfile.ZipFile(fname,"r")
-    mimetype = z.read('mimetype')
-    if mimetype.split('/')[-1] == 'vnd.oasis.opendocument.text' :
-               xsl_file = 'normalized_odt2rml.xsl'
-    xsl = file(os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), xsl_file)).read()
-    result = sxw2rml(f, xsl, output=opt.output, save_pict=False)
-
-    print result
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-
diff --git a/addons/base_synchro/__init__.py b/addons/base_synchro/__init__.py
new file mode 100644 (file)
index 0000000..c23ec3f
--- /dev/null
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import wizard
+import base_synchro_obj
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_synchro/__openerp__.py b/addons/base_synchro/__openerp__.py
new file mode 100644 (file)
index 0000000..69fcb83
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{
+        "name":"Base Synchro",
+        "version":"0.1",
+        "author":"Tiny",
+        "category":"Generic Modules/Base",
+        "depends":["base"],
+        "demo_xml":[],
+        "update_xml":["base_synchro_wizard.xml","base_synchro_view.xml"],
+        "active":False,
+        "installable":True,
+}
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_synchro/base_synchro_obj.py b/addons/base_synchro/base_synchro_obj.py
new file mode 100755 (executable)
index 0000000..5093c8f
--- /dev/null
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-\r
+##############################################################################\r
+#\r
+#    OpenERP, Open Source Management Solution\r
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).\r
+#\r
+#    This program is free software: you can redistribute it and/or modify\r
+#    it under the terms of the GNU Affero General Public License as\r
+#    published by the Free Software Foundation, either version 3 of the\r
+#    License, or (at your option) any later version.\r
+#\r
+#    This program is distributed in the hope that it will be useful,\r
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+#    GNU Affero General Public License for more details.\r
+#\r
+#    You should have received a copy of the GNU Affero General Public License\r
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+#\r
+##############################################################################\r
+from osv import fields,osv\r
+import tools\r
+import re\r
+import time\r
+\r
+class base_synchro_server(osv.osv):\r
+    '''Class to store the information regarding server'''\r
+    _name = "base.synchro.server"\r
+    _description = "Synchronized server"\r
+    _columns = {\r
+        'name': fields.char('Server name', size=64,required=True),\r
+        'server_url': fields.char('Server URL', size=64,required=True),\r
+        'server_port': fields.integer('Server Port', size=64,required=True),\r
+        'server_db': fields.char('Server Database', size=64,required=True),\r
+        'login': fields.char('User Name',size=50,required=True),\r
+        'password': fields.char('Password',size=64,invisible=True,required=True),\r
+        'obj_ids' : fields.one2many('base.synchro.obj','server_id','Models',ondelete='cascade')\r
+    }\r
+    _defaults = {\r
+        'server_port': lambda *args: 8069\r
+    }\r
+base_synchro_server()\r
+\r
+class base_synchro_obj(osv.osv):\r
+    '''Class to store the operations done by wizart'''\r
+    _name = "base.synchro.obj"\r
+    _description = "Register Class"\r
+    _columns = {\r
+        'name':fields.char('Name', size=64, select=1, required=1),\r
+        'domain':fields.char('Domain', size=64, select=1, required=1),\r
+        'server_id':fields.many2one('base.synchro.server','Server', ondelete='cascade', select=1, required=1),\r
+        'model_id': fields.many2one('ir.model', 'Object to synchronize',required=True),\r
+        'action':fields.selection([('d','Download'),('u','Upload'),('b','Both')],'Synchronisation direction', required=True),\r
+        'sequence': fields.integer('Sequence'),\r
+        'active': fields.boolean('Active'),\r
+        'synchronize_date':fields.datetime('Latest Synchronization', readonly=True),\r
+        'line_id':fields.one2many('base.synchro.obj.line','obj_id','Ids Affected',ondelete='cascade'),\r
+        'avoid_ids':fields.one2many('base.synchro.obj.avoid','obj_id','Fields Not Sync.'),\r
+    }\r
+    _defaults = {\r
+        'active': lambda *args: True,\r
+        'action': lambda *args: 'd',\r
+        'domain': lambda *args: '[]'\r
+    }\r
+    _order = 'sequence'\r
+    #\r
+    # Return a list of changes: [ (date, id) ]\r
+    #\r
+    def _get_ids(self, cr, uid, object, dt, domain=[], context={}):\r
+        result = []\r
+        if dt:\r
+            domain2 = domain+[('write_date','>=',dt)]\r
+            domain3 = domain+[('create_date','>=',dt)]\r
+        else:\r
+            domain2 = domain3 = domain\r
+        ids = self.pool.get(object).search(cr, uid, domain2, context=context)\r
+        ids += self.pool.get(object).search(cr, uid, domain3, context=context)\r
+        for r in self.pool.get(object).perm_read(cr, uid, ids, context, details=False):\r
+            result.append( (r['write_date'] or r['create_date'], r['id'], context.get('action', 'd')))\r
+        return result\r
+base_synchro_obj()\r
+\r
+class base_synchro_obj_avoid(osv.osv):\r
+    _name = "base.synchro.obj.avoid"\r
+    _description = "Fields to not synchronize"\r
+    _columns = {\r
+        'name':fields.char('Field Name', size=64, select=1, required=1),\r
+        'obj_id':fields.many2one('base.synchro.obj', 'Object', required=1,ondelete='cascade'),\r
+    }\r
+base_synchro_obj_avoid()\r
+\r
+\r
+class base_synchro_obj_line(osv.osv):\r
+    '''Class to store the operations done by wizard'''\r
+    _name = "base.synchro.obj.line"\r
+    _description = "Synchronized instances"\r
+    _columns = {\r
+        'name': fields.datetime('Date', required=True),\r
+        'obj_id': fields.many2one('base.synchro.obj', 'Object', ondelete='cascade', select=True),\r
+        'local_id': fields.integer('Local Id',readonly=True),\r
+        'remote_id':fields.integer('Remote Id',readonly=True),\r
+    }\r
+    _defaults = {\r
+        'name': lambda *args: time.strftime('%Y-%m-%d %H:%M:%S')\r
+    }\r
+base_synchro_obj_line()\r
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:\r
diff --git a/addons/base_synchro/base_synchro_view.xml b/addons/base_synchro/base_synchro_view.xml
new file mode 100755 (executable)
index 0000000..9799510
--- /dev/null
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="view_transfer_line_tree" model="ir.ui.view">
+            <field name="name">base.synchro.obj.line.tree</field>
+            <field name="model">base.synchro.obj.line</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree string="Transfered Ids Details">
+                    <field name="name" select="1"/>
+                    <field name="obj_id" select="1"/>
+                    <field name="local_id" select="2"/>
+                    <field name="remote_id" select="2"/>
+                </tree>
+            </field>
+        </record>
+
+        <record id="view_transfer_line_form" model="ir.ui.view">
+            <field name="name">base.synchro.obj.line.form</field>
+            <field name="model">base.synchro.obj.line</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Transfered Ids Details">
+                    <field name="name" select="1"/>
+                    <field name="obj_id" select="1"/>
+                    <field name="local_id" readonly="1" select="2"/>
+                    <field name="remote_id" readonly="1" select="2"/>
+                </form>
+            </field>
+        </record>
+
+
+        <record id="action_base_synchro_obj_line_tree" model="ir.actions.act_window">
+            <field name="name">Synchronized instances</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">base.synchro.obj.line</field>
+            <field name="view_type">form</field>
+        </record>
+        <menuitem id="next_id_63" name="History"  groups="base.group_extended" parent="base_synchro.next_id_62"/><menuitem action="action_base_synchro_obj_line_tree" id="menu_action_base_synchro_obj_line_tree" parent="base_synchro.next_id_63"/>
+
+<!--view_base_synchro_obj starts-->
+
+        <record id="view_transfer_form" model="ir.ui.view">
+            <field name="name">base.synchro.obj.form</field>
+            <field name="model">base.synchro.obj</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Transfer Details">
+                    <field name="name" select="1"/>
+                    <field name="active" select="2"/>
+                    <field name="server_id" select="2"/>
+                    <field name="model_id" select="1"/>
+                    <field name="action"/>
+                    <field name="sequence"/>
+                    <field colspan="4" name="domain"/>
+                    <field name="synchronize_date"/>
+                    <newline/>
+                    <field name="avoid_ids" colspan="4">
+                        <tree string="Fields" editable="bottom">
+                            <field name="name"/>
+                        </tree>
+                    </field>
+                </form>
+            </field>
+        </record>
+
+        <record id="view_regclass_tree" model="ir.ui.view">
+            <field name="name">base.synchro.obj.tree</field>
+            <field name="model">base.synchro.obj</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree string="Synchronized objects">
+                    <field name="sequence"/>
+                    <field name="name"/>
+                    <field name="model_id"/>
+                    <field name="server_id"/>
+                    <field name="action"/>
+                    <field name="synchronize_date"/>
+                </tree>
+            </field>
+        </record>
+
+        <record id="action_transfer_tree" model="ir.actions.act_window">
+            <field name="name">Synchronized objects</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">base.synchro.obj</field>
+            <field name="view_type">form</field>
+        </record>
+
+        <menuitem action="action_transfer_tree" id="transfer_menu_id" parent="base_synchro.next_id_63"/>
+
+
+<!--view_base_synchro_obj starts-->
+
+<!--view_base_synchro_server starts -->
+
+        <record id="view_base_synchro_server_tree" model="ir.ui.view">
+            <field name="name">base.synchro.server.tree</field>
+            <field name="model">base.synchro.server</field>
+            <field name="type">tree</field>
+            <field name="arch" type="xml">
+                <tree string="Synchronized server">
+                    <field name="name"/>
+                    <field name="server_url"/>
+                    <field name="server_port"/>
+                    <field name="server_db"/>
+                </tree>
+            </field>
+        </record>
+
+        <record id="view_base_synchro_server_form" model="ir.ui.view">
+            <field name="name">base.synchro.server.form</field>
+            <field name="model">base.synchro.server</field>
+            <field name="type">form</field>
+            <field name="arch" type="xml">
+                <form string="Synchronized server">
+                    <field name="name" select="1"/>
+                    <newline/>
+                    <field name="server_url" select="2"/>
+                    <newline/>
+                    <field name="server_port"/>
+                    <field name="server_db"/>
+                    <newline/>
+                    <field name="login" select="1"/>
+                    <field name="password"/>
+                </form>
+            </field>
+        </record>
+
+        <record id="action_base_synchro_server_tree" model="ir.actions.act_window">
+            <field name="name">Synchronized Servers</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">base.synchro.server</field>
+            <field name="view_type">form</field>
+        </record>
+
+        <menuitem action="action_base_synchro_server_tree" id="synchro_server_tree_menu_id" parent="base_synchro.next_id_63"/>
+
+
+
+<!--view_base_synchro_server end -->
+
+
+    </data>
+</openerp>
diff --git a/addons/base_synchro/base_synchro_wizard.xml b/addons/base_synchro/base_synchro_wizard.xml
new file mode 100644 (file)
index 0000000..b26b3bb
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+       <data>
+               <wizard id="wizard_cost_account_synchro" model="account.analytic.account" name="account.analytic.account.transfer" string="Synchronize objects"/>
+               <menuitem id="next_id_62" name="Synchronization" parent="base.menu_administration"/><menuitem action="wizard_cost_account_synchro" id="menu_wizard_cost_account_synchro" parent="base_synchro.next_id_62" type="wizard"/>
+
+       </data>
+</openerp>
diff --git a/addons/base_synchro/wizard/__init__.py b/addons/base_synchro/wizard/__init__.py
new file mode 100644 (file)
index 0000000..7ff450a
--- /dev/null
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import base_synchro
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/base_synchro/wizard/base_synchro.py b/addons/base_synchro/wizard/base_synchro.py
new file mode 100644 (file)
index 0000000..3a394d4
--- /dev/null
@@ -0,0 +1,279 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import wizard
+import osv
+from datetime import date
+import time
+import pooler
+import xmlrpclib
+import re
+import tools
+import threading
+
+acc_synchro_form = '''<?xml version="1.0"?>
+<form string="Transfer Data To Server">
+    <field name="server_url" colspan="4"/>
+    <newline/>
+    <separator string="Control" colspan="4"/>
+    <field name="user_id"/>
+    <newline/>
+</form>'''
+
+acc_synchro_fields = {
+    'server_url': {'string':'Server URL', 'type':'many2one', 'relation':'base.synchro.server','required':True},
+    'user_id': {'string':'Send Result To', 'type':'many2one', 'relation':'res.users', 'default': lambda uid,data,state: uid},
+}
+
+finish_form ='''<?xml version="1.0"?>
+<form string="Synchronization Complited!">
+    <label string="The synchronisation has been started.\nYou will receive a request when it's done." colspan="4"/>
+</form>
+'''
+
+class RPCProxyOne(object):
+    def __init__(self, server, ressource):
+        self.server = server
+        local_url = 'http://%s:%d/xmlrpc/common'%(server.server_url,server.server_port)
+        rpc = xmlrpclib.ServerProxy(local_url)
+        self.uid = rpc.login(server.server_db, server.login, server.password)
+        local_url = 'http://%s:%d/xmlrpc/object'%(server.server_url,server.server_port)
+        self.rpc = xmlrpclib.ServerProxy(local_url)
+        self.ressource = ressource
+    def __getattr__(self, name):
+        return lambda cr, uid, *args, **kwargs: self.rpc.execute(self.server.server_db, self.uid, self.server.password, self.ressource, name, *args, **kwargs)
+
+class RPCProxy(object):
+    def __init__(self, server):
+        self.server = server
+    def get(self, ressource):
+        return RPCProxyOne(self.server, ressource)
+
+class wizard_cost_account_synchro(wizard.interface):
+    start_date = time.strftime('%Y-%m-%d, %Hh %Mm %Ss')
+    report = []
+    report_total = 0
+    report_create = 0
+    report_write = 0
+    def _synchronize(self, cr, uid, server, object, context):
+        pool = pooler.get_pool(cr.dbname)
+        self.meta = {}
+        ids = []
+        pool1 = RPCProxy(server)
+        pool2 = pool
+        #try:
+        if object.action in ('d','b'):
+            ids = pool1.get('base.synchro.obj')._get_ids(cr, uid,
+                object.model_id.model,
+                object.synchronize_date,
+                eval(object.domain),
+                {'action':'d'}
+            )
+        if object.action in ('u','b'):
+            ids += pool2.get('base.synchro.obj')._get_ids(cr, uid,
+                object.model_id.model,
+                object.synchronize_date,
+                eval(object.domain),
+                {'action':'u'}
+            )
+        ids.sort()
+        iii = 0
+        for dt, id, action in ids:
+            print 'Process', dt, id, action
+            iii +=1
+            if action=='u':
+                pool_src = pool2
+                pool_dest = pool1
+            else:
+                pool_src = pool1
+                pool_dest = pool2
+            print 'Read', object.model_id.model, id
+            fields = False
+            if object.model_id.model=='crm.case.history':
+                fields = ['email','description','log_id']
+            value = pool_src.get(object.model_id.model).read(cr, uid, [id], fields)[0]
+            value = self._data_transform(cr, uid, pool_src, pool_dest, object.model_id.model, value, action)
+            id2 = self.get_id(cr, uid, object.id, id, action, context)
+            #
+            # Transform value
+            #
+            #tid=pool_dest.get(object.model_id.model).name_search(cr, uid, value['name'],[],'=',)
+            if not (iii%50):
+                print 'Record', iii
+
+            # Filter fields to not sync
+            for field in object.avoid_ids:
+                if field.name in value:
+                    del value[field.name]
+
+            if id2:
+                #try:
+                pool_dest.get(object.model_id.model).write(cr, uid, [id2], value)
+                #except Exception, e:
+                #self.report.append('ERROR: Unable to update record ['+str(id2)+']:'+str(value.get('name', '?')))
+                self.report_total+=1
+                self.report_write+=1
+            else:
+                print value
+                idnew = pool_dest.get(object.model_id.model).create(cr, uid, value)
+                synid = pool.get('base.synchro.obj.line').create(cr, uid, {
+                    'obj_id': object.id,
+                    'local_id': (action=='u') and id or idnew,
+                    'remote_id': (action=='d') and id or idnew
+                })
+                self.report_total+=1
+                self.report_create+=1
+        self.meta = {}
+        return 'finish'
+
+    #
+    # IN: object and ID
+    # OUT: ID of the remote object computed:
+    #        If object is synchronised, read the sync database
+    #        Otherwise, use the name_search method
+    #
+    def get_id(self, cr, uid, object_id, id, action, context={}):
+        pool = pooler.get_pool(cr.dbname)
+        field_src = (action=='u') and 'local_id' or 'remote_id'
+        field_dest = (action=='d') and 'local_id' or 'remote_id'
+        rid = pool.get('base.synchro.obj.line').search(cr, uid, [('obj_id','=',object_id), (field_src,'=',id)], context=context)
+        result = False
+        if rid:
+            result  = pool.get('base.synchro.obj.line').read(cr, uid, rid, [field_dest], context=context)[0][field_dest]
+        return result
+
+    def _relation_transform(self, cr, uid, pool_src, pool_dest, object, id, action, context={}):
+        if not id:
+            return False
+        pool = pooler.get_pool(cr.dbname)
+        cr.execute('''select o.id from base_synchro_obj o left join ir_model m on (o.model_id =m.id) where
+                m.model=%s and
+                o.active''', (object,))
+        obj = cr.fetchone()
+        result = False
+        if obj:
+            #
+            # If the object is synchronised and found, set it
+            #
+            result = self.get_id(cr, uid, obj[0], id, action, context)
+        else:
+            #
+            # If not synchronized, try to find it with name_get/name_search
+            #
+            names = pool_src.get(object).name_get(cr, uid, [id], context)[0][1]
+            res = pool_dest.get(object).name_search(cr, uid, names, [], 'like')
+            if res:
+                result = res[0][0]
+            else:
+                # LOG this in the report, better message.
+                print self.report.append('WARNING: Record "%s" on relation %s not found, set to null.' % (names,object))
+        return result
+
+    def _data_transform(self, cr, uid, pool_src, pool_dest, object, data, action='u', context={}):
+        self.meta.setdefault(pool_src, {})
+        if not object in self.meta[pool_src]:
+            self.meta[pool_src][object] = pool_src.get(object).fields_get(cr, uid, context)
+        fields = self.meta[pool_src][object]
+
+        for f in fields:
+            if f not in data:
+                continue
+            ftype = fields[f]['type']
+
+            if ftype in ('function', 'one2many', 'one2one'):
+                del data[f]
+            elif ftype == 'many2one':
+                if data[f]:
+                    df = self._relation_transform(cr, uid, pool_src, pool_dest, fields[f]['relation'], data[f][0], action, context)
+                    data[f] = df
+                    if not data[f]:
+                        del data[f]
+            elif ftype == 'many2many':
+                res = map(lambda x: self._relation_transform(cr, uid, pool_src, pool_dest, fields[f]['relation'], x, action, context), data[f])
+                data[f] = [(6, 0, res)]
+        del data['id']
+        return data
+
+    #
+    # Find all objects that are created or modified after the synchronize_date
+    # Synchronize these obejcts
+    #
+    def _upload_download(self, db_name, uid, data, context):
+        cr = pooler.get_db(db_name).cursor()
+        start_date = time.strftime('%Y-%m-%d, %Hh %Mm %Ss')
+        pool = pooler.get_pool(cr.dbname)
+        server = pool.get('base.synchro.server').browse(cr, uid, data['form']['server_url'], context)
+        for object in server.obj_ids:
+            dt = time.strftime('%Y-%m-%d %H:%M:%S')
+            self._synchronize(cr, uid, server, object, context)
+            if object.action=='b':
+                time.sleep(1)
+                dt = time.strftime('%Y-%m-%d %H:%M:%S')
+            pool.get('base.synchro.obj').write(cr, uid, [object.id], {'synchronize_date': dt})
+            cr.commit()
+        end_date = time.strftime('%Y-%m-%d, %Hh %Mm %Ss')
+        if 'user_id' in data['form'] and data['form']['user_id']:
+            request = pooler.get_pool(cr.dbname).get('res.request')
+            if not self.report:
+                self.report.append('No exception.')
+            summary = '''Here is the synchronization report:
+
+Synchronization started: %s
+Synchronization finnished: %s
+
+Synchronized records: %d
+Records updated: %d
+Records created: %d
+
+Exceptions:
+            '''% (start_date,end_date,self.report_total, self.report_write,self.report_create)
+            summary += '\n'.join(self.report)
+            request.create(cr, uid, {
+                'name' : "Synchronization report",
+                'act_from' : uid,
+                'act_to' : data['form']['user_id'],
+                'body': summary,
+            })
+        cr.commit()
+        cr.close()
+        return 'finish'
+
+    def _upload_download_multi_thread(self, cr, uid, data, context):
+        threaded_synchronization = threading.Thread(target=self._upload_download, args=(cr.dbname, uid, data, context))
+        threaded_synchronization.start()
+        return 'finish'
+
+    states = {
+        'init': {
+            'actions': [],
+            'result': {'type':'form', 'arch':acc_synchro_form, 'fields':acc_synchro_fields, 'state':[('end','Cancel'),('upload_download','Synchronize')]}
+        },
+        'upload_download': {
+            'actions': [],
+            'result':{'type':'choice', 'next_state': _upload_download_multi_thread}
+        },
+        'finish': {
+            'actions': [],
+            'result':{'type':'form', 'arch':finish_form,'fields':{},'state':[('end','Ok')]}
+        },
+    }
+wizard_cost_account_synchro('account.analytic.account.transfer')
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+