Developments for report designer
authorFabien Pinckaers <fp@tinyerp.com>
Thu, 7 Jun 2007 19:48:41 +0000 (19:48 +0000)
committerFabien Pinckaers <fp@tinyerp.com>
Thu, 7 Jun 2007 19:48:41 +0000 (19:48 +0000)
base_report_designer module allows you to create your own reports
reports and images are stored in the database

custom report may override base reports

RML modification
You can now select to put the image in the RML instead than in a
separate file

bzr revid: fp@tinyerp.com-0928aef6e14868d3cd6619d9d73031bfc5651ea2

bin/addons/base/ir/ir_actions.py
bin/osv/orm.py
bin/report/render/rml2pdf/trml2pdf.py
bin/report/report_sxw.py
bin/tools/convert.py

index 8dd7c94..d8f3cde 100644 (file)
@@ -90,7 +90,9 @@ class report_xml(osv.osv):
                'report_name': fields.char('Internal Name', size=64, required=True),
                'report_xsl': fields.char('XSL path', size=256),
                'report_xml': fields.char('XML path', size=256),
-               'report_rml': fields.char('RML path', size=256),
+               'report_rml': fields.char('RML path', size=256, help="The .rml path of the file or NULL if the content is in report_rml_content"),
+               'report_sxw_content': fields.binary('SXW content'),
+               'report_rml_content': fields.binary('RML content'),
                'auto': fields.boolean('Automatic XSL:RML', required=True),
                'usage': fields.char('Action Usage', size=32),
                'header': fields.boolean('Add RML header', help="Add or not the coporate RML header"),
@@ -99,6 +101,7 @@ class report_xml(osv.osv):
                'type': lambda *a: 'ir.actions.report.xml',
                'auto': lambda *a: True,
                'header': lambda *a: True,
+               'report_sxw_content': lambda *a: False,
        }
 report_xml()
 
index ee580cb..b55092b 100644 (file)
@@ -1319,22 +1319,26 @@ class orm(object):
                result['arch'] = xarch
                result['fields'] = xfields
                if toolbar:
+                       def clean(x):
+                               x = x[2]
+                               for key in ('report_sxw_content','report_rml_content','report_sxw','report_rml'):
+                                       if key in x:
+                                               del x[key]
+                               return x
                        resprint = self.pool.get('ir.values').get(cr, user, 'action', 'client_print_multi', [(self._name, False)], False, context)
                        resaction = self.pool.get('ir.values').get(cr, user, 'action', 'client_action_multi', [(self._name, False)], False, context)
                        resrelate = self.pool.get('ir.values').get(cr, user, 'action', 'client_action_relate', [(self._name, False)], False, context)
-                       resprint = map(lambda x:x[2], resprint)
-                       resaction = map(lambda x:x[2], resaction)
+                       resprint = map(clean, resprint)
+                       resaction = map(clean, resaction)
                        resaction = filter(lambda x: not x.get('multi',False), resaction)
                        resrelate = map(lambda x:x[2], resrelate)
                        for x in resprint+resaction+resrelate:
                                x['string'] = x['name']
-
                        result['toolbar'] = {
                                'print': resprint,
                                'action': resaction,
                                'relate': resrelate
                        }
-
                return result
 
        # TODO: ameliorer avec NULL
index 08e707d..7aad961 100755 (executable)
@@ -160,6 +160,20 @@ class _rml_doc(object):
                                addMapping(name, 1, 0, name)    #bold
                                addMapping(name, 1, 1, name)    #italic and bold
 
+       def _textual_image(self, node):
+               import base64
+               rc = ''
+               for n in node.childNodes:
+                       if n.nodeType in (node.CDATA_SECTION_NODE, node.TEXT_NODE):
+                               rc += n.data
+               return base64.decodestring(rc)
+
+       def _images(self, el):
+               result = {}
+               for node in el.getElementsByTagName('image'):
+                       result[node.getAttribute('name')] = self._textual_image(node)
+               return result
+
        def render(self, out):
                el = self.dom.documentElement.getElementsByTagName('docinit')
                if el:
@@ -168,6 +182,10 @@ class _rml_doc(object):
                el = self.dom.documentElement.getElementsByTagName('stylesheet')
                self.styles = _rml_styles(el)
 
+               el = self.dom.documentElement.getElementsByTagName('images')
+               if el:
+                       self.images.update( self._images(el[0]) )
+
                el = self.dom.documentElement.getElementsByTagName('template')
                if len(el):
                        pt_obj = _rml_template(out, el[0], self, images=self.images, path=self.path)
@@ -285,12 +303,15 @@ class _rml_canvas(object):
                if not node.hasAttribute('file'):
                        s = self.images[node.getAttribute('name')]
                else:
-                       try:
-                               u = urllib.urlopen(str(node.getAttribute('file')))
-                               s = StringIO.StringIO(u.read())
-                       except:
-                               u = file(os.path.join(self.path,str(node.getAttribute('file'))), 'rb')
-                               s = StringIO.StringIO(u.read())
+                       if node.getAttribute('file') in self.images:
+                               s = StringIO.StringIO(self.images[node.getAttribute('file')])
+                       else:
+                               try:
+                                       u = urllib.urlopen(str(node.getAttribute('file')))
+                                       s = StringIO.StringIO(u.read())
+                               except:
+                                       u = file(os.path.join(self.path,str(node.getAttribute('file'))), 'rb')
+                                       s = StringIO.StringIO(u.read())
                img = ImageReader(s)
                (sx,sy) = img.getSize()
 
index b1034bc..721e32b 100644 (file)
@@ -303,7 +303,12 @@ class report_sxw(report_rml):
                return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context)
 
        def create(self, cr, uid, ids, data, context={}):
-               rml = tools.file_open(self.tmpl, subdir=None).read()
+               cr.execute('select report_rml_content from ir_act_report_xml where report_name=%s', (self.name[7:],))
+               result = cr.fetchone()
+               if result and result[0]:
+                       rml = result[0]
+               else:
+                       rml = tools.file_open(self.tmpl, subdir=None).read()
 
                rml_parser = self.parser(cr, uid, self.name2, context)
                objs = self.getObjects(cr, uid, ids, context)
index b375a33..285b34b 100644 (file)
@@ -7,6 +7,7 @@ import osv,ir,pooler
 
 import csv
 import os.path
+import misc
 
 from config import config
 
@@ -142,6 +143,9 @@ class xml_import(object):
                                res[dest] = rec.getAttribute(field).encode('utf8')
                if rec.hasAttribute('auto'):
                        res['auto'] = eval(rec.getAttribute('auto'))
+               if rec.hasAttribute('sxw'):
+                       sxw_content = misc.file_open(rec.getAttribute('sxw')).read()
+                       res['report_sxw_content'] = sxw_content
                if rec.hasAttribute('header'):
                        res['header'] = eval(rec.getAttribute('header'))
                xml_id = rec.getAttribute('id').encode('utf8')