Merge lp:~omar7r/openobject-addons/extra_trunk_pxgo_openoffice_reports into lp:openobject-addons/extra-trunk
- extra_trunk_pxgo_openoffice_reports
- Merge into trunk-extra-addons
Proposed by
Omar (Pexego)
Status: | Merged |
---|---|
Merged at revision: | 5064 |
Proposed branch: | lp:~omar7r/openobject-addons/extra_trunk_pxgo_openoffice_reports |
Merge into: | lp:openobject-addons/extra-trunk |
Diff against target: |
2779 lines (+2677/-0) 16 files modified
pxgo_openoffice_reports/__init__.py (+31/-0) pxgo_openoffice_reports/__openerp__.py (+115/-0) pxgo_openoffice_reports/demo/__init__.py (+1/-0) pxgo_openoffice_reports/demo/partner_demo_bar_chart.yaml (+32/-0) pxgo_openoffice_reports/demo/partner_demo_pie_chart.yaml (+23/-0) pxgo_openoffice_reports/demo/partner_demo_report.xml (+50/-0) pxgo_openoffice_reports/demo/report_parser.py (+42/-0) pxgo_openoffice_reports/i18n/ca.po (+200/-0) pxgo_openoffice_reports/i18n/es.po (+368/-0) pxgo_openoffice_reports/i18n/it.po (+113/-0) pxgo_openoffice_reports/i18n/pxgo_openoffice_reports.pot (+280/-0) pxgo_openoffice_reports/oo_template.py (+599/-0) pxgo_openoffice_reports/openoffice_report.py (+528/-0) pxgo_openoffice_reports/report_xml.py (+189/-0) pxgo_openoffice_reports/report_xml_view.xml (+103/-0) pxgo_openoffice_reports/security/ir.model.access.csv (+3/-0) |
To merge this branch: | bzr merge lp:~omar7r/openobject-addons/extra_trunk_pxgo_openoffice_reports |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Borja López Soilán (NeoPolus) | Approve | ||
OpenERP Core Team | Pending | ||
Review via email: mp+39647@code.launchpad.net |
Commit message
Description of the change
Add pxgo_openoffice
To post a comment you must log in.
Revision history for this message
Borja López Soilán (NeoPolus) (borjals) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'pxgo_openoffice_reports' |
2 | === added file 'pxgo_openoffice_reports/__init__.py' |
3 | --- pxgo_openoffice_reports/__init__.py 1970-01-01 00:00:00 +0000 |
4 | +++ pxgo_openoffice_reports/__init__.py 2010-11-02 09:27:47 +0000 |
5 | @@ -0,0 +1,31 @@ |
6 | +# -*- coding: utf-8 -*- |
7 | +# -*- encoding: utf-8 -*- |
8 | +############################################################################## |
9 | +# |
10 | +# OpenOffice Reports |
11 | +# Copyright (C) 2009 Pexego Sistemas Informáticos. All Rights Reserved |
12 | +# $Id$ |
13 | +# |
14 | +# This program is free software: you can redistribute it and/or modify |
15 | +# it under the terms of the GNU General Public License as published by |
16 | +# the Free Software Foundation, either version 3 of the License, or |
17 | +# (at your option) any later version. |
18 | +# |
19 | +# This program is distributed in the hope that it will be useful, |
20 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 | +# GNU General Public License for more details. |
23 | +# |
24 | +# You should have received a copy of the GNU General Public License |
25 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
26 | +# |
27 | +############################################################################## |
28 | + |
29 | +""" |
30 | +OpenOffice Reports - Reporting Engine based on Relatorio and OpenOffice. |
31 | +""" |
32 | +__author__ = "Borja López Soilán (Pexego)" |
33 | + |
34 | +import openoffice_report |
35 | +import report_xml |
36 | +#import demo |
37 | \ No newline at end of file |
38 | |
39 | === added file 'pxgo_openoffice_reports/__openerp__.py' |
40 | --- pxgo_openoffice_reports/__openerp__.py 1970-01-01 00:00:00 +0000 |
41 | +++ pxgo_openoffice_reports/__openerp__.py 2010-11-02 09:27:47 +0000 |
42 | @@ -0,0 +1,115 @@ |
43 | +# -*- coding: utf-8 -*- |
44 | +# -*- encoding: utf-8 -*- |
45 | +############################################################################## |
46 | +# |
47 | +# OpenOffice Reports |
48 | +# Copyright (C) 2009 Pexego Sistemas Informáticos. All Rights Reserved |
49 | +# $Id$ |
50 | +# |
51 | +# This program is free software: you can redistribute it and/or modify |
52 | +# it under the terms of the GNU General Public License as published by |
53 | +# the Free Software Foundation, either version 3 of the License, or |
54 | +# (at your option) any later version. |
55 | +# |
56 | +# This program is distributed in the hope that it will be useful, |
57 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
58 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
59 | +# GNU General Public License for more details. |
60 | +# |
61 | +# You should have received a copy of the GNU General Public License |
62 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
63 | +# |
64 | +############################################################################## |
65 | +# |
66 | +# OpenOffice Reports - Reporting Engine based on Relatorio and OpenOffice. |
67 | +# |
68 | +# Autor: Borja López Soilán (Pexego) |
69 | +# |
70 | +{ |
71 | + "name" : "Pexego OpenOffice Reports", |
72 | + "version" : "0.2", |
73 | + "author" : "Pexego", |
74 | + "website" : "http://www.pexego.es", |
75 | + "category" : "Enterprise Specific Modules", |
76 | + "description": """Pexego OpenOffice Reports - Reporting Engine based on Relatorio and OpenOffice. |
77 | + |
78 | +Reporting engine that uses OpenOffice and Relatorio to create reports from several kind of templates (like an OpenDocument Text, a Microsoft Excel spreadsheet, or even a PowerPoint!) |
79 | +and export them on several formats (i.e.: it may create a Microsoft Excel spreadsheet from a OpenDocument spreadshet template). |
80 | + |
81 | +Based on Relatorio (see http://relatorio.openhex.org/), PyODConverter (http://www.artofsolving.com/opensource/pyodconverter) and the Jasper Reports addon from Koo (https://code.launchpad.net/openobject-client-kde). |
82 | + |
83 | + |
84 | +*** FEATURES *** |
85 | + |
86 | +- The next template formats and output formats are supported: |
87 | + * Text (any text format supported by OpenOffice like odt, doc, rtf, txt): |
88 | + pdf, html, odt, doc (MS Word 97), rtf, txt |
89 | + * Web (hmtl): |
90 | + pdf, odt |
91 | + * Spreadsheet (ods, xls): |
92 | + pdf, html, ods, xls (MS Excel 97), csv |
93 | + * Presentation (odp, ppt): |
94 | + pdf, html, odp, ppt |
95 | + * Drawing (odg): |
96 | + pdf, swf |
97 | + |
98 | +- Subreports (inserting another file anywhere on the document) are supported for text formats, |
99 | + they are recursive (will be processed by the template system and may have their own subreports) |
100 | + and they can be loaded from a binary field. |
101 | + |
102 | +- Dynamic insertion of images is supported too, and they can be loaded from a file or a binary field. |
103 | + |
104 | +- Conditional statements (if) and repetitive structures (for) are supported. And they can be used in tables. |
105 | + |
106 | + |
107 | +*** TEMPLATE LANGUAGE *** |
108 | + |
109 | +Templates are based on Relatorio and Genshi, you might find useful this introduction to Relatorio: http://relatorio.openhex.org/wiki/IndepthIntroduction |
110 | + |
111 | +Some additional features, mainly related to OpenERP, where added: |
112 | + |
113 | + - Support for subreports (text documents only). |
114 | + * From OpenObject binary fields: |
115 | + ${ subreport(object.file_field, object.filename_field) } |
116 | + * From files on disk: |
117 | + ${ subreport(filepath='/tmp/something.odt') } |
118 | + * From buffers (open files, strings): |
119 | + ${ subreport(source=buffer, source_format='odt') } |
120 | + |
121 | + - Translations using the OpenERP translation engine: |
122 | + ${ _("Object Name") } |
123 | + |
124 | + - Access to attachments of an OpenObject: |
125 | + * Get the attachment names: |
126 | + ${ ', '.join([a.name for a in get_attachments(object)]) } |
127 | + * Use the first attachment as a subreport (only text documents): |
128 | + ${ subreport(get_attachments(object)[0].datas, get_attachments(object)[0].datas_fname) } |
129 | + |
130 | + - Using images from fields: |
131 | + * On a frame name (see Relatorio documentation about including images), |
132 | + instead of "image: (file, mimetype)'", |
133 | + use "image: ${ field_to_image(object.field) }" |
134 | + |
135 | + |
136 | +*** REQUIREMENTS *** |
137 | + |
138 | +- Relatorio (0.5.0 or better) for basic templating (odt->odt and ods->ods only), |
139 | +- OpenOffice (2.4 or better) and PyUno for file conversions and subreports. |
140 | +- Python Imaging Library (PIL) if you want to use images from binary fields. |
141 | +- PyCha (3.0 or better) if you want to use charts. |
142 | +- Genshi (0.5.1 or better) for using ${} instead of relatorio:// |
143 | + |
144 | + """, |
145 | + "depends" : [ |
146 | + 'base', |
147 | + ], |
148 | + "init_xml" : [], |
149 | + "demo_xml" : [ |
150 | + 'demo/partner_demo_report.xml', |
151 | + ], |
152 | + "update_xml" : [ |
153 | + 'security/ir.model.access.csv', |
154 | + 'report_xml_view.xml', |
155 | + ], |
156 | + "installable": True |
157 | +} |
158 | |
159 | === added directory 'pxgo_openoffice_reports/custom_reports' |
160 | === added directory 'pxgo_openoffice_reports/demo' |
161 | === added file 'pxgo_openoffice_reports/demo/__init__.py' |
162 | --- pxgo_openoffice_reports/demo/__init__.py 1970-01-01 00:00:00 +0000 |
163 | +++ pxgo_openoffice_reports/demo/__init__.py 2010-11-02 09:27:47 +0000 |
164 | @@ -0,0 +1,1 @@ |
165 | +import report_parser |
166 | \ No newline at end of file |
167 | |
168 | === added file 'pxgo_openoffice_reports/demo/partner_demo.ods' |
169 | Binary files pxgo_openoffice_reports/demo/partner_demo.ods 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo.ods 2010-11-02 09:27:47 +0000 differ |
170 | === added file 'pxgo_openoffice_reports/demo/partner_demo.odt' |
171 | Binary files pxgo_openoffice_reports/demo/partner_demo.odt 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo.odt 2010-11-02 09:27:47 +0000 differ |
172 | === added file 'pxgo_openoffice_reports/demo/partner_demo_bar_chart.yaml' |
173 | --- pxgo_openoffice_reports/demo/partner_demo_bar_chart.yaml 1970-01-01 00:00:00 +0000 |
174 | +++ pxgo_openoffice_reports/demo/partner_demo_bar_chart.yaml 2010-11-02 09:27:47 +0000 |
175 | @@ -0,0 +1,32 @@ |
176 | +options: |
177 | + width: 800 |
178 | + height: 800 |
179 | + background: |
180 | + hide: true |
181 | + legend: |
182 | + hide: true |
183 | + padding: |
184 | + bottom: 50 |
185 | + left: 120 |
186 | + right: 30 |
187 | + top: 10 |
188 | + axis: |
189 | + x: |
190 | + label: 'Credit limit' |
191 | + rotate: 25 |
192 | + ticks: |
193 | + {% for idx, partner in enumerate(objects) %} |
194 | + - v: $idx |
195 | + label: $partner.name |
196 | + {% end %} |
197 | + y: |
198 | + rotate: 25 |
199 | +chart: |
200 | + type: hbar |
201 | + output_type: png |
202 | + dataset: |
203 | + - - ${_('Credit limit')} |
204 | + - |
205 | + {% for idx, partner in enumerate(objects) %} |
206 | + - [$idx, $partner.credit_limit] |
207 | + {% end %} |
208 | \ No newline at end of file |
209 | |
210 | === added file 'pxgo_openoffice_reports/demo/partner_demo_not_auto.odt' |
211 | Binary files pxgo_openoffice_reports/demo/partner_demo_not_auto.odt 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo_not_auto.odt 2010-11-02 09:27:47 +0000 differ |
212 | === added file 'pxgo_openoffice_reports/demo/partner_demo_ods_output.xls' |
213 | Binary files pxgo_openoffice_reports/demo/partner_demo_ods_output.xls 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo_ods_output.xls 2010-11-02 09:27:47 +0000 differ |
214 | === added file 'pxgo_openoffice_reports/demo/partner_demo_odt_output.pdf' |
215 | Binary files pxgo_openoffice_reports/demo/partner_demo_odt_output.pdf 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo_odt_output.pdf 2010-11-02 09:27:47 +0000 differ |
216 | === added file 'pxgo_openoffice_reports/demo/partner_demo_pie_chart.yaml' |
217 | --- pxgo_openoffice_reports/demo/partner_demo_pie_chart.yaml 1970-01-01 00:00:00 +0000 |
218 | +++ pxgo_openoffice_reports/demo/partner_demo_pie_chart.yaml 2010-11-02 09:27:47 +0000 |
219 | @@ -0,0 +1,23 @@ |
220 | +options: |
221 | + width: 400 |
222 | + height: 400 |
223 | + background: |
224 | + hide: true |
225 | + legend: |
226 | + hide: true |
227 | + padding: |
228 | + bottom: 10 |
229 | + left: 70 |
230 | + right: 10 |
231 | + top: 10 |
232 | + axis: |
233 | + labelFontSize: 16 |
234 | +chart: |
235 | + type: pie |
236 | + output_type: png |
237 | + dataset: |
238 | + {% for partner in objects %} |
239 | + - - ${partner.id} |
240 | + - - [0, $partner.credit_limit] |
241 | + {% end %} |
242 | + |
243 | |
244 | === added file 'pxgo_openoffice_reports/demo/partner_demo_report.xml' |
245 | --- pxgo_openoffice_reports/demo/partner_demo_report.xml 1970-01-01 00:00:00 +0000 |
246 | +++ pxgo_openoffice_reports/demo/partner_demo_report.xml 2010-11-02 09:27:47 +0000 |
247 | @@ -0,0 +1,50 @@ |
248 | +<?xml version="1.0" encoding="utf-8"?> |
249 | +<!-- |
250 | + OpenOffice Reports - Sample partner report |
251 | + Autor: Borja López Soilán (Pexego) |
252 | +--> |
253 | +<openerp> |
254 | + <data> |
255 | + |
256 | + <!-- Sample odt partner report --> |
257 | + <report id="report_pxgo_openoffice_reports_partner_demo" |
258 | + string="OpenOffice Reports Demo (ODT->PDF)" |
259 | + model="res.partner" |
260 | + name="pxgo_openoffice_reports.partner_demo" |
261 | + rml="pxgo_openoffice_reports/demo/partner_demo.odt" |
262 | + auto="True" |
263 | + header="False" /> |
264 | + <record model="ir.actions.report.xml" id="report_pxgo_openoffice_reports_partner_demo"> |
265 | + <field name="report_type">oo-pdf</field> |
266 | + </record> |
267 | + |
268 | + <!-- Sample ods partner report --> |
269 | + <report id="report_pxgo_openoffice_reports_partner_demo_ods" |
270 | + string="OpenOffice Reports Demo (ODS->XLS)" |
271 | + model="res.partner" |
272 | + name="pxgo_openoffice_reports.partner_demo_ods" |
273 | + rml="pxgo_openoffice_reports/demo/partner_demo.ods" |
274 | + auto="True" |
275 | + header="False" /> |
276 | + <record model="ir.actions.report.xml" id="report_pxgo_openoffice_reports_partner_demo_ods"> |
277 | + <field name="report_type">oo-xls</field> |
278 | + </record> |
279 | + |
280 | + <!-- Sample odt partner with parser when you can add more attributes to context--> |
281 | + <!-- It is commented because in demo data you cannot have python files, this report need report_parser.py file, if |
282 | + you want to test it discommented and write import demo in __init__.py--> |
283 | + |
284 | + <!--<report id="report_pxgo_openoffice_reports_partner_demo_ods_not_auto" |
285 | + string="OpenOffice Reports Demo (ODT->PDF) not auto" |
286 | + model="res.partner" |
287 | + name="pxgo_openoffice_reports.partner_demo_ods_not_auto" |
288 | + rml="pxgo_openoffice_reports/demo/partner_demo_not_auto.odt" |
289 | + auto="False" |
290 | + header="False" /> |
291 | + <record model="ir.actions.report.xml" id="report_pxgo_openoffice_reports_partner_demo_ods_not_auto"> |
292 | + <field name="report_type">oo-pdf</field> |
293 | + </record>--> |
294 | + |
295 | + </data> |
296 | +</openerp> |
297 | + |
298 | \ No newline at end of file |
299 | |
300 | === added file 'pxgo_openoffice_reports/demo/partner_demo_subreport.odt' |
301 | Binary files pxgo_openoffice_reports/demo/partner_demo_subreport.odt 1970-01-01 00:00:00 +0000 and pxgo_openoffice_reports/demo/partner_demo_subreport.odt 2010-11-02 09:27:47 +0000 differ |
302 | === added file 'pxgo_openoffice_reports/demo/report_parser.py' |
303 | --- pxgo_openoffice_reports/demo/report_parser.py 1970-01-01 00:00:00 +0000 |
304 | +++ pxgo_openoffice_reports/demo/report_parser.py 2010-11-02 09:27:47 +0000 |
305 | @@ -0,0 +1,42 @@ |
306 | +# -*- coding: utf-8 -*- |
307 | +############################################################################## |
308 | +# |
309 | +# OpenERP, Open Source Management Solution |
310 | +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved |
311 | +# $Id$ |
312 | +# |
313 | +# This program is free software: you can redistribute it and/or modify |
314 | +# it under the terms of the GNU General Public License as published by |
315 | +# the Free Software Foundation, either version 3 of the License, or |
316 | +# (at your option) any later version. |
317 | +# |
318 | +# This program is distributed in the hope that it will be useful, |
319 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
320 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
321 | +# GNU General Public License for more details. |
322 | +# |
323 | +# You should have received a copy of the GNU General Public License |
324 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
325 | +# |
326 | +############################################################################## |
327 | + |
328 | +"""Add dummy function to context, it prints Hi! when you call it""" |
329 | + |
330 | +from addons.pxgo_openoffice_reports.openoffice_report import openoffice_report, OOReport |
331 | + |
332 | +class report_parser(OOReport): |
333 | + """Add dummy function to context, it prints Hi! when you call it""" |
334 | + def get_report_context(self): |
335 | + """Add dummy function to context, it prints Hi! when you call it""" |
336 | + res = super(report_parser, self).get_report_context() |
337 | + res.update({ |
338 | + 'print_hi': self.print_hi, |
339 | + }) |
340 | + return res |
341 | + |
342 | + def print_hi(self): |
343 | + """Print Hi!""" |
344 | + res = "Hi !" |
345 | + return res |
346 | + |
347 | +openoffice_report('report.pxgo_openoffice_reports.partner_demo_ods_not_auto', 'res.partner', parser=report_parser) |
348 | \ No newline at end of file |
349 | |
350 | === added directory 'pxgo_openoffice_reports/i18n' |
351 | === added file 'pxgo_openoffice_reports/i18n/ca.po' |
352 | --- pxgo_openoffice_reports/i18n/ca.po 1970-01-01 00:00:00 +0000 |
353 | +++ pxgo_openoffice_reports/i18n/ca.po 2010-11-02 09:27:47 +0000 |
354 | @@ -0,0 +1,200 @@ |
355 | +# Catalan translation for openobject-addons |
356 | +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 |
357 | +# This file is distributed under the same license as the openobject-addons package. |
358 | +# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. |
359 | +# |
360 | +msgid "" |
361 | +msgstr "" |
362 | +"Project-Id-Version: openobject-addons\n" |
363 | +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" |
364 | +"POT-Creation-Date: 2009-11-27 17:29+0000\n" |
365 | +"PO-Revision-Date: 2010-09-03 08:06+0000\n" |
366 | +"Last-Translator: OpenERP Administrators <Unknown>\n" |
367 | +"Language-Team: Catalan <ca@li.org>\n" |
368 | +"MIME-Version: 1.0\n" |
369 | +"Content-Type: text/plain; charset=UTF-8\n" |
370 | +"Content-Transfer-Encoding: 8bit\n" |
371 | +"X-Launchpad-Export-Date: 2010-09-29 05:32+0000\n" |
372 | +"X-Generator: Launchpad (build Unknown)\n" |
373 | + |
374 | +#. module: pxgo_openoffice_reports |
375 | +#: model:ir.module.module,description:pxgo_openoffice_reports.module_meta_information |
376 | +msgid "" |
377 | +"Pexego OpenOffice Reports - Reporting Engine based on Relatorio and " |
378 | +"OpenOffice.\n" |
379 | +"\n" |
380 | +"Reporting engine that uses OpenOffice and Relatorio to create reports from " |
381 | +"several kind of templates (like an OpenDocument Text, a Microsoft Excel " |
382 | +"spreadsheet, or even a PowerPoint!) \n" |
383 | +"and export them on several formats (i.e.: it may create a Microsoft Excel " |
384 | +"spreadsheet from a OpenDocument spreadshet template).\n" |
385 | +"\n" |
386 | +"Based on Relatorio (see http://relatorio.openhex.org/), PyODConverter " |
387 | +"(http://www.artofsolving.com/opensource/pyodconverter) and the Jasper " |
388 | +"Reports addon from Koo (https://code.launchpad.net/openobject-client-kde).\n" |
389 | +"\n" |
390 | +"\n" |
391 | +"*** FEATURES ***\n" |
392 | +"\n" |
393 | +"- The next template formats and output formats are supported:\n" |
394 | +" * Text (any text format supported by OpenOffice like odt, doc, rtf, txt): " |
395 | +"\n" |
396 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
397 | +" * Web (hmtl): \n" |
398 | +" pdf, odt\n" |
399 | +" * Spreadsheet (ods, xls): \n" |
400 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
401 | +" * Presentation (odp, ppt): \n" |
402 | +" pdf, html, odp, ppt\n" |
403 | +" * Drawing (odg): \n" |
404 | +" pdf, swf\n" |
405 | +"\n" |
406 | +"- Subreports (inserting another file anywhere on the document) are supported " |
407 | +"for text formats,\n" |
408 | +" they are recursive (will be processed by the template system and may have " |
409 | +"their own subreports)\n" |
410 | +" and they can be loaded from a binary field.\n" |
411 | +" \n" |
412 | +"- Dynamic insertion of images is supported too, and they can be loaded from " |
413 | +"a file or a binary field.\n" |
414 | +"\n" |
415 | +"- Conditional statements (if) and repetitive structures (for) are supported. " |
416 | +"And they can be used in tables.\n" |
417 | +"\n" |
418 | +"\n" |
419 | +"*** TEMPLATE LANGUAGE ***\n" |
420 | +"\n" |
421 | +"Templates are based on Relatorio and Genshi, you might find useful this " |
422 | +"introduction to Relatorio: " |
423 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
424 | +"\n" |
425 | +"Some additional features, mainly related to OpenERP, where added:\n" |
426 | +"\n" |
427 | +" - Support for subreports (text documents only).\n" |
428 | +" * From OpenObject binary fields:\n" |
429 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
430 | +" * From files on disk:\n" |
431 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
432 | +" * From buffers (open files, strings):\n" |
433 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
434 | +"\n" |
435 | +" - Translations using the OpenERP translation engine:\n" |
436 | +" ${ _(\"Object Name\") }\n" |
437 | +"\n" |
438 | +" - Access to attachments of an OpenObject:\n" |
439 | +" * Get the attachment names:\n" |
440 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
441 | +" * Use the first attachment as a subreport (only text documents):\n" |
442 | +" ${ subreport(get_attachments(object)[0].datas, " |
443 | +"get_attachments(object)[0].datas_fname) }\n" |
444 | +"\n" |
445 | +" - Using images from fields:\n" |
446 | +" * On a frame name (see Relatorio documentation about including " |
447 | +"images),\n" |
448 | +" instead of \"image: (file, mimetype)'\",\n" |
449 | +" use \"image: field_to_image(object.field)\"\n" |
450 | +"\n" |
451 | +"\n" |
452 | +"*** REQUIREMENTS ***\n" |
453 | +"\n" |
454 | +"- Relatorio (0.5.0 or better) for basic templating (odt->odt and ods->ods " |
455 | +"only),\n" |
456 | +"- OpenOffice (3.0 or better) and PyUno for file conversions and subreports.\n" |
457 | +"- Python Imaging Library (PIL) if you want to use images from binary " |
458 | +"fields.\n" |
459 | +"- PyCha (3.0 or better) if you want to use charts.\n" |
460 | +"\n" |
461 | +" " |
462 | +msgstr "" |
463 | +"Informes OpenOffice Pexego - Motor d'informes basat en Relatorio i " |
464 | +"OpenOffice.\n" |
465 | +"\n" |
466 | +"Motor d'informes que utilitza OpenOffice i Relatorio per a crear informes a " |
467 | +"partir de varis tipus de plantilles (com un Text OpenDocument, un full de " |
468 | +"càlcul de Microsoft Excel, o fins i tot un PowerPoint!) \n" |
469 | +"i els exporta a varis formats (p.ex.: podeu crear un full de càlcul " |
470 | +"Microsoft Excel a partir d'una plantilla de full de càlcul OpenDocument).\n" |
471 | +"\n" |
472 | +"Basat en Relatorio (veure http://relatorio.openhex.org/), PyODConverter " |
473 | +"(http://www.artofsolving.com/opensource/pyodconverter) i el mòdul Jasper " |
474 | +"Reports de Koo (https://code.launchpad.net/openobject-client-kde).\n" |
475 | +"\n" |
476 | +"\n" |
477 | +"*** FUNCIONALITATS ***\n" |
478 | +"\n" |
479 | +"- Es suporten els següents formats de plantilla i de sortida:\n" |
480 | +" * Text (qualsevol suportat per OpenOffice com odt, doc, rtf, txt): \n" |
481 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
482 | +" * Web (hmtl): \n" |
483 | +" pdf, odt\n" |
484 | +" * Full de càlcul (ods, xls): \n" |
485 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
486 | +" * Presentació (odp, ppt): \n" |
487 | +" pdf, html, odp, ppt\n" |
488 | +" * Dibuix (odg): \n" |
489 | +" pdf, swf\n" |
490 | +"\n" |
491 | +"- Suporta subinformes (inserir un altre fitxer en qualsevol lloc del " |
492 | +"document) per als formats de text,\n" |
493 | +" són recursius (seran processats pel sistema de plantilles i poden tenir " |
494 | +"els seus propis subinformes)\n" |
495 | +" i poden ser carregats des d'un camp binari.\n" |
496 | +" \n" |
497 | +"- També suporta inserció dinàmica d'imatges, que poden ser carregades des " |
498 | +"d'un fitxer o un camp binari.\n" |
499 | +"\n" |
500 | +"- Suporta sentències condicionals (if) i estructures repetitives (for). I " |
501 | +"poden ser utilitzats en taules.\n" |
502 | +"\n" |
503 | +"\n" |
504 | +"*** IDIOMA DE LES PLANTILLES ***\n" |
505 | +"\n" |
506 | +"Les plantilles estan basades en Relatorio i Genshi, aquesta introducció a " |
507 | +"Relatorio podria resultar-vos d'utilitat: " |
508 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
509 | +"\n" |
510 | +"Es van afegir algunes funcionalitats addicionals, principalment relacionades " |
511 | +"amb OpenERP:\n" |
512 | +"\n" |
513 | +" - Suport per a subinformes (només documents de text).\n" |
514 | +" * Per a camps binaris d'OpenObject:\n" |
515 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
516 | +" * Per a fitxers en disc:\n" |
517 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
518 | +" * Per a bufers (fitxers oberts, cadenes):\n" |
519 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
520 | +"\n" |
521 | +" - Traduccions utilitzen el motor de traduccions d'OpenERP:\n" |
522 | +" ${ _(\"Object Name\") }\n" |
523 | +"\n" |
524 | +" - Accés als fitxers adjunts d'un OpenObject:\n" |
525 | +" * Obtenir els noms dels adjunts:\n" |
526 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
527 | +" * Utilitzar el primer adjunt com un subinforme (només documents de " |
528 | +"text):\n" |
529 | +" ${ subreport(get_attachments(object)[0].datas, " |
530 | +"get_attachments(object)[0].datas_fname) }\n" |
531 | +"\n" |
532 | +" - Utilitzant imatges des de camps:\n" |
533 | +" * En el nom d'un marc (vegeu la documentació de Relatorio sobre " |
534 | +"incloure imatges),\n" |
535 | +" en lloc de \"image: (file, mimetype)'\",\n" |
536 | +" utilitzeu \"image: field_to_image(object.field)\"\n" |
537 | +"\n" |
538 | +"\n" |
539 | +"*** REQUISITS ***\n" |
540 | +"\n" |
541 | +"- Relatorio (0.5.0 o mejor) per a plantilles bàsiques (només odt->odt y ods-" |
542 | +">ods),\n" |
543 | +"- OpenOffice (3.0 o mejor) i PyUno per a conversió de fitxers i " |
544 | +"subinformes.\n" |
545 | +"- Python Imaging Library (PIL) si voleu utilitzar imatges des de camps " |
546 | +"binaris.\n" |
547 | +"- PyCha (3.0. or millor) if voleu utilitzar diagrames.\n" |
548 | +"\n" |
549 | +" " |
550 | + |
551 | +#. module: pxgo_openoffice_reports |
552 | +#: model:ir.module.module,shortdesc:pxgo_openoffice_reports.module_meta_information |
553 | +msgid "Pexego OpenOffice Reports" |
554 | +msgstr "Informes OpenOffice Pexego" |
555 | |
556 | === added file 'pxgo_openoffice_reports/i18n/es.po' |
557 | --- pxgo_openoffice_reports/i18n/es.po 1970-01-01 00:00:00 +0000 |
558 | +++ pxgo_openoffice_reports/i18n/es.po 2010-11-02 09:27:47 +0000 |
559 | @@ -0,0 +1,368 @@ |
560 | +# Translation of OpenERP Server. |
561 | +# This file contains the translation of the following modules: |
562 | +# * pxgo_openoffice_reports |
563 | +# |
564 | +msgid "" |
565 | +msgstr "" |
566 | +"Project-Id-Version: OpenERP Server 6.0.0-rc1\n" |
567 | +"Report-Msgid-Bugs-To: support@openerp.com\n" |
568 | +"POT-Creation-Date: 2010-10-29 08:32:31+0000\n" |
569 | +"PO-Revision-Date: 2010-10-29 10:40+0100\n" |
570 | +"Last-Translator: omar <omar@pexego.es>\n" |
571 | +"Language-Team: \n" |
572 | +"MIME-Version: 1.0\n" |
573 | +"Content-Type: text/plain; charset=UTF-8\n" |
574 | +"Content-Transfer-Encoding: 8bit\n" |
575 | +"Plural-Forms: \n" |
576 | + |
577 | +#. module: pxgo_openoffice_reports |
578 | +#: field:ir.actions.report.xml,openoffice_report:0 |
579 | +msgid "Is OpenOffice Report?" |
580 | +msgstr "Informe de OpenOffice" |
581 | + |
582 | +#: model:ir.module.module,description:pxgo_openoffice_reports.module_meta_information |
583 | +msgid "" |
584 | +"Pexego OpenOffice Reports - Reporting Engine based on Relatorio and " |
585 | +"OpenOffice.\n" |
586 | +"\n" |
587 | +"Reporting engine that uses OpenOffice and Relatorio to create reports from " |
588 | +"several kind of templates (like an OpenDocument Text, a Microsoft Excel " |
589 | +"spreadsheet, or even a PowerPoint!) \n" |
590 | +"and export them on several formats (i.e.: it may create a Microsoft Excel " |
591 | +"spreadsheet from a OpenDocument spreadshet template).\n" |
592 | +"\n" |
593 | +"Based on Relatorio (see http://relatorio.openhex.org/), PyODConverter " |
594 | +"(http://www.artofsolving.com/opensource/pyodconverter) and the Jasper " |
595 | +"Reports addon from Koo (https://code.launchpad.net/openobject-client-kde).\n" |
596 | +"\n" |
597 | +"\n" |
598 | +"*** FEATURES ***\n" |
599 | +"\n" |
600 | +"- The next template formats and output formats are supported:\n" |
601 | +" * Text (any text format supported by OpenOffice like odt, doc, rtf, txt): " |
602 | +"\n" |
603 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
604 | +" * Web (hmtl): \n" |
605 | +" pdf, odt\n" |
606 | +" * Spreadsheet (ods, xls): \n" |
607 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
608 | +" * Presentation (odp, ppt): \n" |
609 | +" pdf, html, odp, ppt\n" |
610 | +" * Drawing (odg): \n" |
611 | +" pdf, swf\n" |
612 | +"\n" |
613 | +"- Subreports (inserting another file anywhere on the document) are supported " |
614 | +"for text formats,\n" |
615 | +" they are recursive (will be processed by the template system and may have " |
616 | +"their own subreports)\n" |
617 | +" and they can be loaded from a binary field.\n" |
618 | +" \n" |
619 | +"- Dynamic insertion of images is supported too, and they can be loaded from " |
620 | +"a file or a binary field.\n" |
621 | +"\n" |
622 | +"- Conditional statements (if) and repetitive structures (for) are supported. " |
623 | +"And they can be used in tables.\n" |
624 | +"\n" |
625 | +"\n" |
626 | +"*** TEMPLATE LANGUAGE ***\n" |
627 | +"\n" |
628 | +"Templates are based on Relatorio and Genshi, you might find useful this " |
629 | +"introduction to Relatorio: " |
630 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
631 | +"\n" |
632 | +"Some additional features, mainly related to OpenERP, where added:\n" |
633 | +"\n" |
634 | +" - Support for subreports (text documents only).\n" |
635 | +" * From OpenObject binary fields:\n" |
636 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
637 | +" * From files on disk:\n" |
638 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
639 | +" * From buffers (open files, strings):\n" |
640 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
641 | +"\n" |
642 | +" - Translations using the OpenERP translation engine:\n" |
643 | +" ${ _(\"Object Name\") }\n" |
644 | +"\n" |
645 | +" - Access to attachments of an OpenObject:\n" |
646 | +" * Get the attachment names:\n" |
647 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
648 | +" * Use the first attachment as a subreport (only text documents):\n" |
649 | +" ${ subreport(get_attachments(object)[0].datas, " |
650 | +"get_attachments(object)[0].datas_fname) }\n" |
651 | +"\n" |
652 | +" - Using images from fields:\n" |
653 | +" * On a frame name (see Relatorio documentation about including " |
654 | +"images),\n" |
655 | +" instead of \"image: (file, mimetype)'\",\n" |
656 | +" use \"image: field_to_image(object.field)\"\n" |
657 | +"\n" |
658 | +"\n" |
659 | +"*** REQUIREMENTS ***\n" |
660 | +"\n" |
661 | +"- Relatorio (0.5.0 or better) for basic templating (odt->odt and ods->ods " |
662 | +"only),\n" |
663 | +"- OpenOffice (2.4 or better) and PyUno for file conversions and subreports.\n" |
664 | +"- Python Imaging Library (PIL) if you want to use images from binary " |
665 | +"fields.\n" |
666 | +"- PyCha (3.0 or better) if you want to use charts.\n" |
667 | +"- Genshi (0.5.1 or better) for using ${} instead of relatorio://\n" |
668 | +"\n" |
669 | +" " |
670 | +msgstr "" |
671 | +"Reportes OpenOffice Pexego - Motor de reportes basado en Relatorio y " |
672 | +"OpenOffice.\n" |
673 | +"\n" |
674 | +"Motor de reportes que usa OpenOffice y Relatorio para crear reportes a " |
675 | +"partir de varios tipos de plantillas (como un Texto OpenDocument, una hoja " |
676 | +"de cálculo de Microsoft Excel, ¡o incluso un PowerPoint!) \n" |
677 | +"y los exporta a varios formatos (p.ej.: puede crear una hoja de cálculo " |
678 | +"Microsoft Excel a partir de una plantilla de hoja de cálculo OpenDocument).\n" |
679 | +"\n" |
680 | +"Basado en Relatorio (ver http://relatorio.openhex.org/), PyODConverter " |
681 | +"(http://www.artofsolving.com/opensource/pyodconverter) y el módulo Jasper " |
682 | +"Reports de Koo (https://code.launchpad.net/openobject-client-kde).\n" |
683 | +"\n" |
684 | +"\n" |
685 | +"*** FUNCIONALIDADES ***\n" |
686 | +"\n" |
687 | +"- Se soportan los siguientes formatos de plantilla y de salida:\n" |
688 | +" * Texto (cualquiera soportado por OpenOffice como odt, doc, rtf, txt): \n" |
689 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
690 | +" * Web (hmtl): \n" |
691 | +" pdf, odt\n" |
692 | +" * Hoja de cálculo (ods, xls): \n" |
693 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
694 | +" * Presentación (odp, ppt): \n" |
695 | +" pdf, html, odp, ppt\n" |
696 | +" * Dibujo (odg): \n" |
697 | +" pdf, swf\n" |
698 | +"\n" |
699 | +"- Soporta subreportes (insertar otro archivo en cualquier lugar del " |
700 | +"documento) para los formatos de texto,\n" |
701 | +" son recursivos (serán procesados por el sistema de plantillas y pueden " |
702 | +"tener sus propios subreportes)\n" |
703 | +" y pueden ser cargados desde un campo binario.\n" |
704 | +" \n" |
705 | +"- También soporta inserción dinámica de imágenes, que pueden ser cargadas " |
706 | +"desde un archivo o un campo binario.\n" |
707 | +"\n" |
708 | +"- Soporta sentencias condicionales (if) y estructuras repetitivas (for). Y " |
709 | +"pueden ser usados en tablas.\n" |
710 | +"\n" |
711 | +"\n" |
712 | +"*** IDIOMA DE LAS PLANTILLAS ***\n" |
713 | +"\n" |
714 | +"Las plantillas están basadas en Relatorio y Genshi, esta introducción a " |
715 | +"Relatorio podría resultarle de utilidad: " |
716 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
717 | +"\n" |
718 | +"Se añadieron algunas funcionalidades adicionales, principalmente " |
719 | +"relacionadas con OpenERP:\n" |
720 | +"\n" |
721 | +" - Soporte para subreportes (sólo documentos de texto).\n" |
722 | +" * Para campos binarios de OpenObject:\n" |
723 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
724 | +" * Para archivos en disco:\n" |
725 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
726 | +" * Para buferes (archivos abiertos, cadenas):\n" |
727 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
728 | +"\n" |
729 | +" - Traducciones usando el motor de traducciones de OpenERP:\n" |
730 | +" ${ _(\"Object Name\") }\n" |
731 | +"\n" |
732 | +" - Acceso a los archivos adjuntos de un OpenObject:\n" |
733 | +" * Obtener los nombres de los adjuntos:\n" |
734 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
735 | +" * Usar el primer adjunto como un subreporte (sólo documentos de " |
736 | +"texto):\n" |
737 | +" ${ subreport(get_attachments(object)[0].datas, " |
738 | +"get_attachments(object)[0].datas_fname) }\n" |
739 | +"\n" |
740 | +" - Usando imágenes desde campos:\n" |
741 | +" * En el nombre de un marco (vea la documentación de Relatorio acerca " |
742 | +"de incluir imágenes),\n" |
743 | +" en vez de \"image: (file, mimetype)'\",\n" |
744 | +" use \"image: field_to_image(object.field)\"\n" |
745 | +"\n" |
746 | +"\n" |
747 | +"*** REQUISITOS ***\n" |
748 | +"\n" |
749 | +"- Relatorio (0.5.0 o mejor) para plantillas básicas (sólo odt->odt y ods-" |
750 | +">ods),\n" |
751 | +"- OpenOffice (2.4 o mejor) y PyUno para conversión de archivos y " |
752 | +"subreportes.\n" |
753 | +"- Python Imaging Library (PIL) si quieres usar imágenes desde campos " |
754 | +"binarios.\n" |
755 | +"- PyCha (3.0. o mejor) if quieres usar diagramas.\n" |
756 | +"- Genshi (0.5.1 o mejor) para usar expresiones ${} en lugar de relatorio://\n" |
757 | +"\n" |
758 | +" " |
759 | + |
760 | +#. module: pxgo_openoffice_reports |
761 | +#: code:addons/pxgo_openoffice_reports/openoffice_report.py:0 |
762 | +#, python-format |
763 | +msgid "Error loading the OpenOffice template: %s" |
764 | +msgstr "Error cargando la plantilla de OpenOffice: %s" |
765 | + |
766 | +#. module: pxgo_openoffice_reports |
767 | +#: model:ir.ui.menu,name:pxgo_openoffice_reports.openoffice_reports_menu |
768 | +msgid "OpenOffice Reports" |
769 | +msgstr "Informes OpenOffice" |
770 | + |
771 | +#. module: pxgo_openoffice_reports |
772 | +#: constraint:ir.model:0 |
773 | +msgid "The Object name must start with x_ and not contain any special character !" |
774 | +msgstr "¡El nombre del objeto debe empezar con x_ y no contener ningún carácter especial!" |
775 | + |
776 | +#. module: pxgo_openoffice_reports |
777 | +#: constraint:ir.actions.act_window:0 |
778 | +msgid "Invalid model name in the action definition." |
779 | +msgstr "Nombre de modelo no válido en la definición de acción." |
780 | + |
781 | +#. module: pxgo_openoffice_reports |
782 | +#: code:addons/pxgo_openoffice_reports/openoffice_report.py:0 |
783 | +#, python-format |
784 | +msgid "Error processing the OpenOffice template: %s" |
785 | +msgstr "Error procesando la plantilla de OpenOffice: %s" |
786 | + |
787 | +#. module: pxgo_openoffice_reports |
788 | +#: constraint:ir.ui.view:0 |
789 | +msgid "Invalid XML for View Architecture!" |
790 | +msgstr "¡XML inválido para la definición de la vista!" |
791 | + |
792 | +#. module: pxgo_openoffice_reports |
793 | +#: view:ir.actions.report.xml:0 |
794 | +msgid "openoffice Reports" |
795 | +msgstr "Informes OpenOffice" |
796 | + |
797 | +#. module: pxgo_openoffice_reports |
798 | +#: constraint:ir.ui.menu:0 |
799 | +msgid "Error ! You can not create recursive Menu." |
800 | +msgstr "¡ Error ! No puede crear menús recursivos." |
801 | + |
802 | +#. module: pxgo_openoffice_reports |
803 | +#: model:ir.actions.report.xml,name:pxgo_openoffice_reports.report_pxgo_openoffice_reports_partner_demo_ods |
804 | +msgid "OpenOffice Reports Demo (ODS->XLS)" |
805 | +msgstr "Informe OpenOffice demo (ODS->XLS)" |
806 | + |
807 | +#. module: pxgo_openoffice_reports |
808 | +#: view:ir.actions.report.xml:0 |
809 | +#: field:ir.actions.report.xml,openoffice_file_ids:0 |
810 | +msgid "Files" |
811 | +msgstr "Ficheros" |
812 | + |
813 | +#. module: pxgo_openoffice_reports |
814 | +#: view:ir.actions.report.xml.file:0 |
815 | +msgid "Openoffice Reports File" |
816 | +msgstr "Fichero informe Openoffice" |
817 | + |
818 | +#. module: pxgo_openoffice_reports |
819 | +#: model:ir.actions.act_window,name:pxgo_openoffice_reports.ir_action_report_openoffice |
820 | +#: view:ir.actions.report.xml:0 |
821 | +#: model:ir.ui.menu,name:pxgo_openoffice_reports.menu_ir_action_report_openoffice |
822 | +msgid "Openoffice Reports" |
823 | +msgstr "Informes Openoffice" |
824 | + |
825 | +#. module: pxgo_openoffice_reports |
826 | +#: view:ir.actions.report.xml:0 |
827 | +msgid "Update from attachments" |
828 | +msgstr "Actualizar desde adjuntos" |
829 | + |
830 | +#. module: pxgo_openoffice_reports |
831 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
832 | +#, python-format |
833 | +msgid "Error inserting file %s on the OpenOffice document: %s" |
834 | +msgstr "Error insertando el fichero %s en el documento de OpenOffice: %s" |
835 | + |
836 | +#. module: pxgo_openoffice_reports |
837 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
838 | +#, python-format |
839 | +msgid "There is more than one report marked as default" |
840 | +msgstr "Hay más de un informe marcado como por defecto." |
841 | + |
842 | +#. module: pxgo_openoffice_reports |
843 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
844 | +#, python-format |
845 | +msgid "Error saving file %s with OpenOffice: %s" |
846 | +msgstr "Error guardando el fichero %s con OpenOffice: %s" |
847 | + |
848 | +#. module: pxgo_openoffice_reports |
849 | +#: view:ir.actions.report.xml:0 |
850 | +msgid "Groups" |
851 | +msgstr "Grupos" |
852 | + |
853 | +#. module: pxgo_openoffice_reports |
854 | +#: field:ir.actions.report.xml.file,report_id:0 |
855 | +msgid "Report" |
856 | +msgstr "Informe" |
857 | + |
858 | +#. module: pxgo_openoffice_reports |
859 | +#: code:addons/pxgo_openoffice_reports/__openerp__.py:0 |
860 | +#, python-format |
861 | +msgid "Object Name" |
862 | +msgstr "Nombre objeto" |
863 | + |
864 | +#. module: pxgo_openoffice_reports |
865 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
866 | +#, python-format |
867 | +msgid "Error loading file %s with OpenOffice: %s" |
868 | +msgstr "Error cargando el fichero %s con OpenOffice: %s" |
869 | + |
870 | +#. module: pxgo_openoffice_reports |
871 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
872 | +#, python-format |
873 | +msgid "Couldn't connect to OpenOffice. Make sure you have an OpenOffice instance running and listening on the %s port. Details: %s" |
874 | +msgstr "No se pudo conectar con OpenOffice. Asegúrese de tener una instancia de OpenOffice corriendo y escuchando el el puerto %s. Detalles: %s" |
875 | + |
876 | +#. module: pxgo_openoffice_reports |
877 | +#: model:ir.model,name:pxgo_openoffice_reports.model_ir_actions_report_xml_file |
878 | +msgid "ir.actions.report.xml.file" |
879 | +msgstr "ir.actions.report.xml.file" |
880 | + |
881 | +#. module: pxgo_openoffice_reports |
882 | +#: field:ir.actions.report.xml.file,default:0 |
883 | +msgid "Default" |
884 | +msgstr "Por defecto" |
885 | + |
886 | +#. module: pxgo_openoffice_reports |
887 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
888 | +#, python-format |
889 | +msgid "No report has been marked as default." |
890 | +msgstr "Ningún informe ha sido marcado por defecto." |
891 | + |
892 | +#. module: pxgo_openoffice_reports |
893 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
894 | +#, python-format |
895 | +msgid "Error" |
896 | +msgstr "Error" |
897 | + |
898 | +#. module: pxgo_openoffice_reports |
899 | +#: field:ir.actions.report.xml,openoffice_model_id:0 |
900 | +msgid "Model" |
901 | +msgstr "Modelo" |
902 | + |
903 | +#. module: pxgo_openoffice_reports |
904 | +#: model:ir.actions.report.xml,name:pxgo_openoffice_reports.report_pxgo_openoffice_reports_partner_demo |
905 | +msgid "OpenOffice Reports Demo (ODT->PDF)" |
906 | +msgstr "Informe OpenOffice demo (ODT->PDF)" |
907 | + |
908 | +#. module: pxgo_openoffice_reports |
909 | +#: field:ir.actions.report.xml.file,filename:0 |
910 | +msgid "File Name" |
911 | +msgstr "Nombre fichero" |
912 | + |
913 | +#. module: pxgo_openoffice_reports |
914 | +#: model:ir.model,name:pxgo_openoffice_reports.model_ir_actions_report_xml |
915 | +msgid "ir.actions.report.xml" |
916 | +msgstr "ir.acciones.informe.xml" |
917 | + |
918 | +#. module: pxgo_openoffice_reports |
919 | +#: field:ir.actions.report.xml.file,file:0 |
920 | +msgid "File" |
921 | +msgstr "Fichero" |
922 | + |
923 | +#. module: pxgo_openoffice_reports |
924 | +#: sql_constraint:ir.model.fields:0 |
925 | +msgid "Size of the field can never be less than 1 !" |
926 | +msgstr "¡ El tamaño del campo no puede nunca ser menor que 1 !" |
927 | + |
928 | |
929 | === added file 'pxgo_openoffice_reports/i18n/it.po' |
930 | --- pxgo_openoffice_reports/i18n/it.po 1970-01-01 00:00:00 +0000 |
931 | +++ pxgo_openoffice_reports/i18n/it.po 2010-11-02 09:27:47 +0000 |
932 | @@ -0,0 +1,113 @@ |
933 | +# Italian translation for openobject-addons |
934 | +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 |
935 | +# This file is distributed under the same license as the openobject-addons package. |
936 | +# FIRST AUTHOR <EMAIL@ADDRESS>, 2010. |
937 | +# |
938 | +msgid "" |
939 | +msgstr "" |
940 | +"Project-Id-Version: openobject-addons\n" |
941 | +"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n" |
942 | +"POT-Creation-Date: 2009-11-27 17:29+0000\n" |
943 | +"PO-Revision-Date: 2010-08-18 12:15+0000\n" |
944 | +"Last-Translator: OpenERP Administrators <Unknown>\n" |
945 | +"Language-Team: Italian <it@li.org>\n" |
946 | +"MIME-Version: 1.0\n" |
947 | +"Content-Type: text/plain; charset=UTF-8\n" |
948 | +"Content-Transfer-Encoding: 8bit\n" |
949 | +"X-Launchpad-Export-Date: 2010-09-29 05:32+0000\n" |
950 | +"X-Generator: Launchpad (build Unknown)\n" |
951 | + |
952 | +#. module: pxgo_openoffice_reports |
953 | +#: model:ir.module.module,description:pxgo_openoffice_reports.module_meta_information |
954 | +msgid "" |
955 | +"Pexego OpenOffice Reports - Reporting Engine based on Relatorio and " |
956 | +"OpenOffice.\n" |
957 | +"\n" |
958 | +"Reporting engine that uses OpenOffice and Relatorio to create reports from " |
959 | +"several kind of templates (like an OpenDocument Text, a Microsoft Excel " |
960 | +"spreadsheet, or even a PowerPoint!) \n" |
961 | +"and export them on several formats (i.e.: it may create a Microsoft Excel " |
962 | +"spreadsheet from a OpenDocument spreadshet template).\n" |
963 | +"\n" |
964 | +"Based on Relatorio (see http://relatorio.openhex.org/), PyODConverter " |
965 | +"(http://www.artofsolving.com/opensource/pyodconverter) and the Jasper " |
966 | +"Reports addon from Koo (https://code.launchpad.net/openobject-client-kde).\n" |
967 | +"\n" |
968 | +"\n" |
969 | +"*** FEATURES ***\n" |
970 | +"\n" |
971 | +"- The next template formats and output formats are supported:\n" |
972 | +" * Text (any text format supported by OpenOffice like odt, doc, rtf, txt): " |
973 | +"\n" |
974 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
975 | +" * Web (hmtl): \n" |
976 | +" pdf, odt\n" |
977 | +" * Spreadsheet (ods, xls): \n" |
978 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
979 | +" * Presentation (odp, ppt): \n" |
980 | +" pdf, html, odp, ppt\n" |
981 | +" * Drawing (odg): \n" |
982 | +" pdf, swf\n" |
983 | +"\n" |
984 | +"- Subreports (inserting another file anywhere on the document) are supported " |
985 | +"for text formats,\n" |
986 | +" they are recursive (will be processed by the template system and may have " |
987 | +"their own subreports)\n" |
988 | +" and they can be loaded from a binary field.\n" |
989 | +" \n" |
990 | +"- Dynamic insertion of images is supported too, and they can be loaded from " |
991 | +"a file or a binary field.\n" |
992 | +"\n" |
993 | +"- Conditional statements (if) and repetitive structures (for) are supported. " |
994 | +"And they can be used in tables.\n" |
995 | +"\n" |
996 | +"\n" |
997 | +"*** TEMPLATE LANGUAGE ***\n" |
998 | +"\n" |
999 | +"Templates are based on Relatorio and Genshi, you might find useful this " |
1000 | +"introduction to Relatorio: " |
1001 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
1002 | +"\n" |
1003 | +"Some additional features, mainly related to OpenERP, where added:\n" |
1004 | +"\n" |
1005 | +" - Support for subreports (text documents only).\n" |
1006 | +" * From OpenObject binary fields:\n" |
1007 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
1008 | +" * From files on disk:\n" |
1009 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
1010 | +" * From buffers (open files, strings):\n" |
1011 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
1012 | +"\n" |
1013 | +" - Translations using the OpenERP translation engine:\n" |
1014 | +" ${ _(\"Object Name\") }\n" |
1015 | +"\n" |
1016 | +" - Access to attachments of an OpenObject:\n" |
1017 | +" * Get the attachment names:\n" |
1018 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
1019 | +" * Use the first attachment as a subreport (only text documents):\n" |
1020 | +" ${ subreport(get_attachments(object)[0].datas, " |
1021 | +"get_attachments(object)[0].datas_fname) }\n" |
1022 | +"\n" |
1023 | +" - Using images from fields:\n" |
1024 | +" * On a frame name (see Relatorio documentation about including " |
1025 | +"images),\n" |
1026 | +" instead of \"image: (file, mimetype)'\",\n" |
1027 | +" use \"image: field_to_image(object.field)\"\n" |
1028 | +"\n" |
1029 | +"\n" |
1030 | +"*** REQUIREMENTS ***\n" |
1031 | +"\n" |
1032 | +"- Relatorio (0.5.0 or better) for basic templating (odt->odt and ods->ods " |
1033 | +"only),\n" |
1034 | +"- OpenOffice (3.0 or better) and PyUno for file conversions and subreports.\n" |
1035 | +"- Python Imaging Library (PIL) if you want to use images from binary " |
1036 | +"fields.\n" |
1037 | +"- PyCha (3.0 or better) if you want to use charts.\n" |
1038 | +"\n" |
1039 | +" " |
1040 | +msgstr "" |
1041 | + |
1042 | +#. module: pxgo_openoffice_reports |
1043 | +#: model:ir.module.module,shortdesc:pxgo_openoffice_reports.module_meta_information |
1044 | +msgid "Pexego OpenOffice Reports" |
1045 | +msgstr "Reports OpenOffice Pexego" |
1046 | |
1047 | === added file 'pxgo_openoffice_reports/i18n/pxgo_openoffice_reports.pot' |
1048 | --- pxgo_openoffice_reports/i18n/pxgo_openoffice_reports.pot 1970-01-01 00:00:00 +0000 |
1049 | +++ pxgo_openoffice_reports/i18n/pxgo_openoffice_reports.pot 2010-11-02 09:27:47 +0000 |
1050 | @@ -0,0 +1,280 @@ |
1051 | +# Translation of OpenERP Server. |
1052 | +# This file contains the translation of the following modules: |
1053 | +# * pxgo_openoffice_reports |
1054 | +# |
1055 | +msgid "" |
1056 | +msgstr "" |
1057 | +"Project-Id-Version: OpenERP Server 6.0.0-rc1\n" |
1058 | +"Report-Msgid-Bugs-To: support@openerp.com\n" |
1059 | +"POT-Creation-Date: 2010-10-29 08:32:31+0000\n" |
1060 | +"PO-Revision-Date: 2010-10-29 10:40+0100\n" |
1061 | +"Last-Translator: omar <omar@pexego.es>\n" |
1062 | +"Language-Team: \n" |
1063 | +"MIME-Version: 1.0\n" |
1064 | +"Content-Type: text/plain; charset=UTF-8\n" |
1065 | +"Content-Transfer-Encoding: 8bit\n" |
1066 | +"Plural-Forms: \n" |
1067 | + |
1068 | +#. module: pxgo_openoffice_reports |
1069 | +#: field:ir.actions.report.xml,openoffice_report:0 |
1070 | +msgid "Is OpenOffice Report?" |
1071 | +msgstr "" |
1072 | + |
1073 | +#: model:ir.module.module,description:pxgo_openoffice_reports.module_meta_information |
1074 | +msgid "" |
1075 | +"Pexego OpenOffice Reports - Reporting Engine based on Relatorio and " |
1076 | +"OpenOffice.\n" |
1077 | +"\n" |
1078 | +"Reporting engine that uses OpenOffice and Relatorio to create reports from " |
1079 | +"several kind of templates (like an OpenDocument Text, a Microsoft Excel " |
1080 | +"spreadsheet, or even a PowerPoint!) \n" |
1081 | +"and export them on several formats (i.e.: it may create a Microsoft Excel " |
1082 | +"spreadsheet from a OpenDocument spreadshet template).\n" |
1083 | +"\n" |
1084 | +"Based on Relatorio (see http://relatorio.openhex.org/), PyODConverter " |
1085 | +"(http://www.artofsolving.com/opensource/pyodconverter) and the Jasper " |
1086 | +"Reports addon from Koo (https://code.launchpad.net/openobject-client-kde).\n" |
1087 | +"\n" |
1088 | +"\n" |
1089 | +"*** FEATURES ***\n" |
1090 | +"\n" |
1091 | +"- The next template formats and output formats are supported:\n" |
1092 | +" * Text (any text format supported by OpenOffice like odt, doc, rtf, txt): " |
1093 | +"\n" |
1094 | +" pdf, html, odt, doc (MS Word 97), rtf, txt\n" |
1095 | +" * Web (hmtl): \n" |
1096 | +" pdf, odt\n" |
1097 | +" * Spreadsheet (ods, xls): \n" |
1098 | +" pdf, html, ods, xls (MS Excel 97), csv\n" |
1099 | +" * Presentation (odp, ppt): \n" |
1100 | +" pdf, html, odp, ppt\n" |
1101 | +" * Drawing (odg): \n" |
1102 | +" pdf, swf\n" |
1103 | +"\n" |
1104 | +"- Subreports (inserting another file anywhere on the document) are supported " |
1105 | +"for text formats,\n" |
1106 | +" they are recursive (will be processed by the template system and may have " |
1107 | +"their own subreports)\n" |
1108 | +" and they can be loaded from a binary field.\n" |
1109 | +" \n" |
1110 | +"- Dynamic insertion of images is supported too, and they can be loaded from " |
1111 | +"a file or a binary field.\n" |
1112 | +"\n" |
1113 | +"- Conditional statements (if) and repetitive structures (for) are supported. " |
1114 | +"And they can be used in tables.\n" |
1115 | +"\n" |
1116 | +"\n" |
1117 | +"*** TEMPLATE LANGUAGE ***\n" |
1118 | +"\n" |
1119 | +"Templates are based on Relatorio and Genshi, you might find useful this " |
1120 | +"introduction to Relatorio: " |
1121 | +"http://relatorio.openhex.org/wiki/IndepthIntroduction\n" |
1122 | +"\n" |
1123 | +"Some additional features, mainly related to OpenERP, where added:\n" |
1124 | +"\n" |
1125 | +" - Support for subreports (text documents only).\n" |
1126 | +" * From OpenObject binary fields:\n" |
1127 | +" ${ subreport(object.file_field, object.filename_field) }\n" |
1128 | +" * From files on disk:\n" |
1129 | +" ${ subreport(filepath='/tmp/something.odt') }\n" |
1130 | +" * From buffers (open files, strings):\n" |
1131 | +" ${ subreport(source=buffer, source_format='odt') }\n" |
1132 | +"\n" |
1133 | +" - Translations using the OpenERP translation engine:\n" |
1134 | +" ${ _(\"Object Name\") }\n" |
1135 | +"\n" |
1136 | +" - Access to attachments of an OpenObject:\n" |
1137 | +" * Get the attachment names:\n" |
1138 | +" ${ ', '.join([a.name for a in get_attachments(object)]) }\n" |
1139 | +" * Use the first attachment as a subreport (only text documents):\n" |
1140 | +" ${ subreport(get_attachments(object)[0].datas, " |
1141 | +"get_attachments(object)[0].datas_fname) }\n" |
1142 | +"\n" |
1143 | +" - Using images from fields:\n" |
1144 | +" * On a frame name (see Relatorio documentation about including " |
1145 | +"images),\n" |
1146 | +" instead of \"image: (file, mimetype)'\",\n" |
1147 | +" use \"image: field_to_image(object.field)\"\n" |
1148 | +"\n" |
1149 | +"\n" |
1150 | +"*** REQUIREMENTS ***\n" |
1151 | +"\n" |
1152 | +"- Relatorio (0.5.0 or better) for basic templating (odt->odt and ods->ods " |
1153 | +"only),\n" |
1154 | +"- OpenOffice (2.4 or better) and PyUno for file conversions and subreports.\n" |
1155 | +"- Python Imaging Library (PIL) if you want to use images from binary " |
1156 | +"fields.\n" |
1157 | +"- PyCha (3.0 or better) if you want to use charts.\n" |
1158 | +"- Genshi (0.5.1 or better) for using ${} instead of relatorio://\n" |
1159 | +"\n" |
1160 | +" " |
1161 | +msgstr "" |
1162 | + |
1163 | +#. module: pxgo_openoffice_reports |
1164 | +#: code:addons/pxgo_openoffice_reports/openoffice_report.py:0 |
1165 | +#, python-format |
1166 | +msgid "Error loading the OpenOffice template: %s" |
1167 | +msgstr "" |
1168 | + |
1169 | +#. module: pxgo_openoffice_reports |
1170 | +#: model:ir.ui.menu,name:pxgo_openoffice_reports.openoffice_reports_menu |
1171 | +msgid "OpenOffice Reports" |
1172 | +msgstr "" |
1173 | + |
1174 | +#. module: pxgo_openoffice_reports |
1175 | +#: constraint:ir.model:0 |
1176 | +msgid "The Object name must start with x_ and not contain any special character !" |
1177 | +msgstr "" |
1178 | + |
1179 | +#. module: pxgo_openoffice_reports |
1180 | +#: constraint:ir.actions.act_window:0 |
1181 | +msgid "Invalid model name in the action definition." |
1182 | +msgstr "" |
1183 | + |
1184 | +#. module: pxgo_openoffice_reports |
1185 | +#: code:addons/pxgo_openoffice_reports/openoffice_report.py:0 |
1186 | +#, python-format |
1187 | +msgid "Error processing the OpenOffice template: %s" |
1188 | +msgstr "" |
1189 | + |
1190 | +#. module: pxgo_openoffice_reports |
1191 | +#: constraint:ir.ui.view:0 |
1192 | +msgid "Invalid XML for View Architecture!" |
1193 | +msgstr "" |
1194 | + |
1195 | +#. module: pxgo_openoffice_reports |
1196 | +#: view:ir.actions.report.xml:0 |
1197 | +msgid "openoffice Reports" |
1198 | +msgstr "" |
1199 | + |
1200 | +#. module: pxgo_openoffice_reports |
1201 | +#: constraint:ir.ui.menu:0 |
1202 | +msgid "Error ! You can not create recursive Menu." |
1203 | +msgstr "" |
1204 | + |
1205 | +#. module: pxgo_openoffice_reports |
1206 | +#: model:ir.actions.report.xml,name:pxgo_openoffice_reports.report_pxgo_openoffice_reports_partner_demo_ods |
1207 | +msgid "OpenOffice Reports Demo (ODS->XLS)" |
1208 | +msgstr "" |
1209 | + |
1210 | +#. module: pxgo_openoffice_reports |
1211 | +#: view:ir.actions.report.xml:0 |
1212 | +#: field:ir.actions.report.xml,openoffice_file_ids:0 |
1213 | +msgid "Files" |
1214 | +msgstr "" |
1215 | + |
1216 | +#. module: pxgo_openoffice_reports |
1217 | +#: view:ir.actions.report.xml.file:0 |
1218 | +msgid "Openoffice Reports File" |
1219 | +msgstr "" |
1220 | + |
1221 | +#. module: pxgo_openoffice_reports |
1222 | +#: model:ir.actions.act_window,name:pxgo_openoffice_reports.ir_action_report_openoffice |
1223 | +#: view:ir.actions.report.xml:0 |
1224 | +#: model:ir.ui.menu,name:pxgo_openoffice_reports.menu_ir_action_report_openoffice |
1225 | +msgid "Openoffice Reports" |
1226 | +msgstr "" |
1227 | + |
1228 | +#. module: pxgo_openoffice_reports |
1229 | +#: view:ir.actions.report.xml:0 |
1230 | +msgid "Update from attachments" |
1231 | +msgstr "" |
1232 | + |
1233 | +#. module: pxgo_openoffice_reports |
1234 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
1235 | +#, python-format |
1236 | +msgid "Error inserting file %s on the OpenOffice document: %s" |
1237 | +msgstr "" |
1238 | + |
1239 | +#. module: pxgo_openoffice_reports |
1240 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
1241 | +#, python-format |
1242 | +msgid "There is more than one report marked as default" |
1243 | +msgstr "" |
1244 | + |
1245 | +#. module: pxgo_openoffice_reports |
1246 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
1247 | +#, python-format |
1248 | +msgid "Error saving file %s with OpenOffice: %s" |
1249 | +msgstr "" |
1250 | + |
1251 | +#. module: pxgo_openoffice_reports |
1252 | +#: view:ir.actions.report.xml:0 |
1253 | +msgid "Groups" |
1254 | +msgstr "" |
1255 | + |
1256 | +#. module: pxgo_openoffice_reports |
1257 | +#: field:ir.actions.report.xml.file,report_id:0 |
1258 | +msgid "Report" |
1259 | +msgstr "" |
1260 | + |
1261 | +#. module: pxgo_openoffice_reports |
1262 | +#: code:addons/pxgo_openoffice_reports/__openerp__.py:0 |
1263 | +#, python-format |
1264 | +msgid "Object Name" |
1265 | +msgstr "" |
1266 | + |
1267 | +#. module: pxgo_openoffice_reports |
1268 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
1269 | +#, python-format |
1270 | +msgid "Error loading file %s with OpenOffice: %s" |
1271 | +msgstr "" |
1272 | + |
1273 | +#. module: pxgo_openoffice_reports |
1274 | +#: code:addons/pxgo_openoffice_reports/oo_template.py:0 |
1275 | +#, python-format |
1276 | +msgid "Couldn't connect to OpenOffice. Make sure you have an OpenOffice instance running and listening on the %s port. Details: %s" |
1277 | +msgstr "" |
1278 | + |
1279 | +#. module: pxgo_openoffice_reports |
1280 | +#: model:ir.model,name:pxgo_openoffice_reports.model_ir_actions_report_xml_file |
1281 | +msgid "ir.actions.report.xml.file" |
1282 | +msgstr "" |
1283 | + |
1284 | +#. module: pxgo_openoffice_reports |
1285 | +#: field:ir.actions.report.xml.file,default:0 |
1286 | +msgid "Default" |
1287 | +msgstr "" |
1288 | + |
1289 | +#. module: pxgo_openoffice_reports |
1290 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
1291 | +#, python-format |
1292 | +msgid "No report has been marked as default." |
1293 | +msgstr "" |
1294 | + |
1295 | +#. module: pxgo_openoffice_reports |
1296 | +#: code:addons/pxgo_openoffice_reports/report_xml.py:0 |
1297 | +#, python-format |
1298 | +msgid "Error" |
1299 | +msgstr "" |
1300 | + |
1301 | +#. module: pxgo_openoffice_reports |
1302 | +#: field:ir.actions.report.xml,openoffice_model_id:0 |
1303 | +msgid "Model" |
1304 | +msgstr "" |
1305 | + |
1306 | +#. module: pxgo_openoffice_reports |
1307 | +#: model:ir.actions.report.xml,name:pxgo_openoffice_reports.report_pxgo_openoffice_reports_partner_demo |
1308 | +msgid "OpenOffice Reports Demo (ODT->PDF)" |
1309 | +msgstr "" |
1310 | + |
1311 | +#. module: pxgo_openoffice_reports |
1312 | +#: field:ir.actions.report.xml.file,filename:0 |
1313 | +msgid "File Name" |
1314 | +msgstr "" |
1315 | + |
1316 | +#. module: pxgo_openoffice_reports |
1317 | +#: model:ir.model,name:pxgo_openoffice_reports.model_ir_actions_report_xml |
1318 | +msgid "ir.actions.report.xml" |
1319 | +msgstr "" |
1320 | + |
1321 | +#. module: pxgo_openoffice_reports |
1322 | +#: field:ir.actions.report.xml.file,file:0 |
1323 | +msgid "File" |
1324 | +msgstr "" |
1325 | + |
1326 | +#. module: pxgo_openoffice_reports |
1327 | +#: sql_constraint:ir.model.fields:0 |
1328 | +msgid "Size of the field can never be less than 1 !" |
1329 | +msgstr "" |
1330 | + |
1331 | |
1332 | === added file 'pxgo_openoffice_reports/oo_template.py' |
1333 | --- pxgo_openoffice_reports/oo_template.py 1970-01-01 00:00:00 +0000 |
1334 | +++ pxgo_openoffice_reports/oo_template.py 2010-11-02 09:27:47 +0000 |
1335 | @@ -0,0 +1,599 @@ |
1336 | +# -*- coding: utf-8 -*- |
1337 | +# -*- encoding: utf-8 -*- |
1338 | +############################################################################## |
1339 | +# |
1340 | +# OpenOffice Reports |
1341 | +# Copyright (C) 2009 Pexego Sistemas Informáticos. All Rights Reserved |
1342 | +# Based on Relatorio (see http://relatorio.openhex.org/) |
1343 | +# and PyODConverter (http://www.artofsolving.com/opensource/pyodconverter) |
1344 | +# $Id$ |
1345 | +# |
1346 | +# This program is free software: you can redistribute it and/or modify |
1347 | +# it under the terms of the GNU General Public License as published by |
1348 | +# the Free Software Foundation, either version 3 of the License, or |
1349 | +# (at your option) any later version. |
1350 | +# |
1351 | +# This program is distributed in the hope that it will be useful, |
1352 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1353 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1354 | +# GNU General Public License for more details. |
1355 | +# |
1356 | +# You should have received a copy of the GNU General Public License |
1357 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1358 | +# |
1359 | +############################################################################## |
1360 | + |
1361 | +""" |
1362 | +OpenOffice/Relatorio template engine. |
1363 | +""" |
1364 | +__author__ = "Borja López Soilán (Pexego)" |
1365 | + |
1366 | +from tools.translate import _ |
1367 | +import os |
1368 | +import tempfile |
1369 | +import inspect |
1370 | +import base64 |
1371 | +import subprocess |
1372 | +import time |
1373 | +import genshi |
1374 | +from os.path import abspath, splitext |
1375 | +from relatorio.templates.opendocument import Template |
1376 | + |
1377 | + |
1378 | +class OOTemplateException(Exception): |
1379 | + """ |
1380 | + OpenOffice template exception |
1381 | + """ |
1382 | + def __init__(self, message): |
1383 | + # pylint: disable-msg=W0231 |
1384 | + self.message = message |
1385 | + def __str__(self): |
1386 | + return self.message |
1387 | + |
1388 | + |
1389 | +class OOTemplate(Template): |
1390 | + """ |
1391 | + OpenOffice/Relatorio template. |
1392 | + Extends the standard relatorio template to let the user include subreports |
1393 | + with the "${ subreport(file, context) }" statement, |
1394 | + and allow file conversions (pdf output and such). |
1395 | + |
1396 | + Note: It needs an OpenOffice instance running and listening for the |
1397 | + advanced features. |
1398 | + """ |
1399 | + |
1400 | + def log(self, message): |
1401 | + """ |
1402 | + Helper method used print debug messages |
1403 | + """ |
1404 | + if self.logger: |
1405 | + self.logger(message) |
1406 | + else: |
1407 | + print "OOTemplate: %s" % message |
1408 | + |
1409 | + |
1410 | + def __init__(self, source=None, filepath=None, filename=None, loader=None, |
1411 | + encoding=None, lookup='strict', allow_exec=True, |
1412 | + source_format=None, output_format=None, |
1413 | + openoffice_port=8100, autostart_openoffice=True, |
1414 | + logger=None): |
1415 | + """ |
1416 | + Init the oo_subreports list, OpenOffice options and formats, |
1417 | + and then delegate on the parent constructor. |
1418 | + """ |
1419 | + self.logger = logger |
1420 | + |
1421 | + self.temp_file_names = [] # List of files to delete on the destructor (__del__) |
1422 | + assert filepath or filename or source_format |
1423 | + |
1424 | + if source: |
1425 | + # |
1426 | + # Relatorio reports don't support using source instead of filepath/filename. |
1427 | + # Passing the file contents using source seems useful, but |
1428 | + # we will have to write it somewhere for Relatorio to work. |
1429 | + # So we will create a temp file (that will be removed when |
1430 | + # oo_render ends, and dump source to that file. |
1431 | + # |
1432 | + assert isinstance(source, (file, str, unicode)) |
1433 | + self.log("Template is a file-like object or string, writing it to a temp file.") |
1434 | + dummy_fd, temp_file_name = tempfile.mkstemp(suffix=".%s" % source_format, prefix='openerp_oot_t_') |
1435 | + temp_file = open(temp_file_name, 'wb') |
1436 | + try: |
1437 | + if isinstance(source, file): |
1438 | + temp_file.write(source.read()) |
1439 | + elif isinstance(source, (str, unicode)): |
1440 | + temp_file.write(source) |
1441 | + finally: |
1442 | + temp_file.close() |
1443 | + self.temp_file_names.append(temp_file_name) |
1444 | + filepath = temp_file_name |
1445 | + |
1446 | + filepath = filepath or filename |
1447 | + filename = None |
1448 | + assert filepath |
1449 | + |
1450 | + if not os.path.exists(filepath): |
1451 | + search_paths = ['./bin/addons/%s' % filepath, './addons/%s' % filepath] |
1452 | + for path in search_paths: |
1453 | + if os.path.exists(path): |
1454 | + filepath = path |
1455 | + break |
1456 | + |
1457 | + if not source_format: |
1458 | + # Get the source_format from the file name: |
1459 | + source_format = splitext(filepath or filename)[1][1:] |
1460 | + |
1461 | + assert source_format and output_format |
1462 | + source_format = source_format.lower() |
1463 | + output_format = output_format.lower() |
1464 | + |
1465 | + if source_format in ('doc', 'rtf', 'txt', 'xls'): |
1466 | + # It's not an OpenDocument file, |
1467 | + # (it may be a Microsoft Word document [doc] for example), |
1468 | + # convert it using OpenOffice. |
1469 | + format_mapping = { 'doc': 'odt', 'rtf': 'odt', 'txt': 'odt', 'xls': 'ods'} |
1470 | + self.log("Template file is not an OpenDocument, converting from %s to %s." % (source_format, format_mapping[source_format])) |
1471 | + dummy_fd, temp_file_name = tempfile.mkstemp(suffix=".%s" % format_mapping[source_format], prefix='openerp_oot_t_') |
1472 | + oohelper = OOHelper(openoffice_port, autostart_openoffice, logger=self.logger) |
1473 | + document = oohelper.open_document(filepath) |
1474 | + oohelper.save_document(document, temp_file_name, close_document=True) |
1475 | + self.temp_file_names.append(temp_file_name) |
1476 | + source_format = format_mapping[source_format] |
1477 | + filepath = temp_file_name |
1478 | + |
1479 | + self.source_format = source_format |
1480 | + self.output_format = output_format |
1481 | + self.openoffice_port = openoffice_port |
1482 | + self.autostart_openoffice = autostart_openoffice |
1483 | + self.oo_subreports = [] |
1484 | + |
1485 | + super(OOTemplate, self).__init__(source, filepath, filename, loader, |
1486 | + encoding, lookup, allow_exec) |
1487 | + |
1488 | + |
1489 | + def __del__(self): |
1490 | + """ |
1491 | + Destructor of the template: Will delete any temp file created on the |
1492 | + constructor. |
1493 | + """ |
1494 | + if self.temp_file_names: |
1495 | + for file_name in self.temp_file_names: |
1496 | + os.unlink(file_name) |
1497 | + |
1498 | + |
1499 | + def generate(self, *args, **kwargs): |
1500 | + """ |
1501 | + Apply the template to the given context data. |
1502 | + Overwrites the generate method to add support for subreports. |
1503 | + Delegates on the standard generate method for everything else. |
1504 | + """ |
1505 | + def _subreport(field=None, filename=None, source=None, filepath=None, source_format=None, encoding=None, context=None): |
1506 | + """ |
1507 | + Method that can be referenced from the template to include subreports. |
1508 | + When called it will process the file as a template, |
1509 | + write the generated data to a temp file, |
1510 | + and return a reference (filename) to this output file for later usage. |
1511 | + The OOTemplate will will use this data, after the main template |
1512 | + is generated, to do an insertion pass using UNO. |
1513 | + """ |
1514 | + # Field is a binary field with a base64 encoded file that we will |
1515 | + # use as source if it is specified |
1516 | + source = field and base64.decodestring(field) or source |
1517 | + |
1518 | + # |
1519 | + # Get the current report context so the subreport can see |
1520 | + # the variables defined on the report. |
1521 | + # |
1522 | + if not context: |
1523 | + context = {} |
1524 | + try: |
1525 | + frame = inspect.stack()[1][0] |
1526 | + locals_context = frame.f_locals.copy() |
1527 | + data_context = locals_context.get('__data__') or context |
1528 | + if data_context and isinstance(data_context, genshi.template.base.Context): |
1529 | + for c in data_context.frames: |
1530 | + context.update(c) |
1531 | + else: |
1532 | + context = data_context |
1533 | + except: |
1534 | + self.log("Warning: Failed to get the context for the subreport from the stack frame!") |
1535 | + |
1536 | + |
1537 | + # Get the source_format from the file name: |
1538 | + if not source_format and (filepath or filename): |
1539 | + source_format = splitext(filepath or filename)[1][1:] |
1540 | + source_format = source_format or self.source_format |
1541 | + assert source_format |
1542 | + |
1543 | + # |
1544 | + # Process the subreport file like a normal template |
1545 | + # (we are recursive!) |
1546 | + # |
1547 | + self.log("Generating subreport (%s)..." % source_format) |
1548 | + subreport_template = OOTemplate(source=source, |
1549 | + filepath=filepath, |
1550 | + filename=filename, |
1551 | + encoding=encoding, |
1552 | + source_format=source_format, |
1553 | + output_format=self.source_format, |
1554 | + openoffice_port=self.openoffice_port, |
1555 | + autostart_openoffice=self.autostart_openoffice, |
1556 | + logger=self.log) |
1557 | + data = subreport_template.oo_render(context) |
1558 | + |
1559 | + # |
1560 | + # Save the subreport data to a temp file |
1561 | + # |
1562 | + dummy_fd, temp_file_name = tempfile.mkstemp(suffix=".%s" % source_format, prefix='openerp_oot_s_') |
1563 | + temp_file = open(temp_file_name, 'wb') |
1564 | + try: |
1565 | + temp_file.write(data) |
1566 | + finally: |
1567 | + temp_file.close() |
1568 | + |
1569 | + # |
1570 | + # Save a reference to this file for later usage |
1571 | + # |
1572 | + self.oo_subreports.append(temp_file_name) |
1573 | + self.log("...subreport generated as %s." % temp_file_name) |
1574 | + |
1575 | + # Return a placeholder that will be replaced later, |
1576 | + # on the insertion step, with the file contents: |
1577 | + return "${insert_doc('%s')}" % temp_file_name |
1578 | + |
1579 | + # Add the include function to the report context |
1580 | + kwargs['subreport'] = _subreport |
1581 | + |
1582 | + # Generate the template |
1583 | + res = super(OOTemplate, self).generate(*args, **kwargs) |
1584 | + |
1585 | + return res |
1586 | + |
1587 | + |
1588 | + |
1589 | + def oo_render(self, context=None): |
1590 | + """ |
1591 | + Wrapper, around the render method of the original template, |
1592 | + that adds support for subreports and format conversion. |
1593 | + The wrapper is required as these operations need to be performed, |
1594 | + using OpenOffice, after the document generation by the template. |
1595 | + """ |
1596 | + if context is None: context = {} |
1597 | + self.log("Generating report: step 1...") |
1598 | + |
1599 | + # Generate the stream from the template (Relatorio) |
1600 | + data = self.generate(**context).render().getvalue() |
1601 | + |
1602 | + self.log("...step 1 done.") |
1603 | + |
1604 | + # |
1605 | + # Next steps need OpenOffice to perform some tasks |
1606 | + # like file insertion or format conversions. |
1607 | + # Using OpenOffice brings some overhead, so we will try to avoid |
1608 | + # connecting to it unless it is necesary. |
1609 | + # |
1610 | + if len(self.oo_subreports)>0 or (self.output_format != self.source_format): |
1611 | + self.log("Step 2....") |
1612 | + |
1613 | + # Connect to OpenOffice |
1614 | + oohelper = OOHelper(self.openoffice_port, self.autostart_openoffice, logger=self.log) |
1615 | + |
1616 | + # |
1617 | + # Create a temporary (input for OpenOffice) file |
1618 | + # |
1619 | + dummy_fd, temp_file_name = tempfile.mkstemp(suffix=".%s" % self.source_format, prefix='openerp_oot_i_') |
1620 | + temp_file = open(temp_file_name, 'wb') |
1621 | + try: |
1622 | + # |
1623 | + # Write the data to the file |
1624 | + # |
1625 | + try: |
1626 | + temp_file.write(data) |
1627 | + finally: |
1628 | + temp_file.close() |
1629 | + |
1630 | + # Reopen the file with OpenOffice |
1631 | + document = oohelper.open_document(temp_file_name) |
1632 | + |
1633 | + # |
1634 | + # Insert subreport files if needed |
1635 | + # |
1636 | + if len(self.oo_subreports)>0: |
1637 | + self.log("Inserting subreport files") |
1638 | + for subreport in self.oo_subreports: |
1639 | + placeholder_text = "${insert_doc('%s')}" % subreport |
1640 | + oohelper.replace_text_with_file_contents(document, placeholder_text, subreport) |
1641 | + # Remove the subreport temp file |
1642 | + os.unlink(subreport) |
1643 | + |
1644 | + # |
1645 | + # Save the file (does the format conversion) on a temp file |
1646 | + # |
1647 | + dummy_fd, output_file_name = tempfile.mkstemp(suffix=".%s" % self.output_format, prefix='openerp_oot_o_') |
1648 | + try: |
1649 | + # Save the document |
1650 | + oohelper.save_document(document, output_file_name, close_document=True) |
1651 | + |
1652 | + # |
1653 | + # Read back the data |
1654 | + # |
1655 | + output_file = open(output_file_name, 'rb') |
1656 | + try: |
1657 | + data = output_file.read() |
1658 | + finally: |
1659 | + output_file.close() |
1660 | + finally: |
1661 | + # Remove the temp file |
1662 | + os.unlink(output_file_name) |
1663 | + finally: |
1664 | + # Remove the temp file |
1665 | + os.unlink(temp_file_name) |
1666 | + |
1667 | + self.log("...step 2 done.") |
1668 | + |
1669 | + |
1670 | + # TODO: As a long term feature it would be nice to be able to tell OpenOffice to refresh/recalculate the Table Of Contents (if there is any) |
1671 | + |
1672 | + |
1673 | + # Return the data (byte string) |
1674 | + return data |
1675 | + |
1676 | + |
1677 | + |
1678 | + |
1679 | +class OOHelperException(Exception): |
1680 | + """ |
1681 | + OpenOffice template exception |
1682 | + """ |
1683 | + def __init__(self, message): |
1684 | + # pylint: disable-msg=W0231 |
1685 | + self.message = message |
1686 | + def __str__(self): |
1687 | + return self.message |
1688 | + |
1689 | + |
1690 | + |
1691 | +class OOHelper(): |
1692 | + """ |
1693 | + OpenOffice helper methods. |
1694 | + |
1695 | + Loads and saves OpenOffice documents, doing the needed format conversions. |
1696 | + Also lets you to replace text (placeholders) on documents with the contents |
1697 | + of another document. |
1698 | + |
1699 | + Uses PyUNO, requires OpenOffice to be installed on the computer, |
1700 | + and a OpenOffice instance listening on the given port |
1701 | + (or it may start a headless OpenOffice instance for you). |
1702 | + |
1703 | + Based on PyODConverter (http://www.artofsolving.com/opensource/pyodconverter) |
1704 | + """ |
1705 | + |
1706 | + # OpenOffice main executable posible paths |
1707 | + OOPATHS = [ '/usr/bin/soffice', '/usr/lib64/ooo-2.0/program/soffice', '/opt/openoffice.org3/program/soffice', 'C:\\Program Files\\OpenOffice.org 3.1\\program\\soffice', ] |
1708 | + |
1709 | + |
1710 | + # |
1711 | + # Import/export formats and filter options |
1712 | + # |
1713 | + # see http://wiki.services.openoffice.org/wiki/Framework/Article/Filter |
1714 | + # |
1715 | + |
1716 | + # |
1717 | + # Import filter options (only formats that require options) |
1718 | + # |
1719 | + IMPORT_FILTER_MAP = { |
1720 | + 'txt': { 'FilterName': 'Text (encoded)', 'FilterOptions': 'utf8' }, |
1721 | + 'csv': { 'FilterName': 'Text - txt - csv (StarCalc)', 'FilterOptions': '44,34,0' } |
1722 | + } |
1723 | + |
1724 | + # |
1725 | + # Export filter mapping |
1726 | + # |
1727 | + EXPORT_FILTER_MAPS = { |
1728 | + 'text': { |
1729 | + 'pdf': { "FilterName": "writer_pdf_Export" }, |
1730 | + 'html': { "FilterName": "HTML (StarWriter)" }, |
1731 | + 'odt': { "FilterName": "writer8" }, |
1732 | + 'doc': { "FilterName": "MS Word 97" }, |
1733 | + 'rtf': { "FilterName": "Rich Text Format" }, |
1734 | + 'txt': { "FilterName": "Text", "FilterOptions": "utf8" } |
1735 | + }, |
1736 | + 'web': { |
1737 | + 'pdf': { "FilterName": "writer_web_pdf_Export" }, |
1738 | + 'odt': { "FilterName": "writerweb8_writer" }, |
1739 | + }, |
1740 | + 'spreadsheet': { |
1741 | + 'pdf': { "FilterName": "calc_pdf_Export" }, |
1742 | + 'html': { "FilterName": "HTML (StarCalc)" }, |
1743 | + 'ods': { "FilterName": "calc8" }, |
1744 | + 'xls': { "FilterName": "MS Excel 97" }, |
1745 | + 'csv': { "FilterName": "Text - txt - csv (StarCalc)", "FilterOptions": "44,34,0" } |
1746 | + }, |
1747 | + 'presentation': { |
1748 | + 'pdf': { "FilterName": "impress_pdf_Export" }, |
1749 | + 'html': { "FilterName": "impress_html_Export" }, |
1750 | + 'odp': { "FilterName": "impress8" }, |
1751 | + 'ppt': { "FilterName": "MS PowerPoint 97" }, |
1752 | + 'ppt': { "FilterName": "impress_flash_Export" }, |
1753 | + }, |
1754 | + 'drawing': { |
1755 | + 'pdf': { "FilterName": "draw_pdf_Export" }, |
1756 | + 'swf': { "FilterName": "draw_flash_Export" }, |
1757 | + } |
1758 | + } |
1759 | + |
1760 | + |
1761 | + # |
1762 | + # Code --------------------------------------------------------------------- |
1763 | + # |
1764 | + |
1765 | + def log(self, message): |
1766 | + """ |
1767 | + Helper method used print debug messages |
1768 | + """ |
1769 | + if self.logger: |
1770 | + self.logger(message) |
1771 | + else: |
1772 | + print "OOHelper: %s" % message |
1773 | + |
1774 | + |
1775 | + def __init__(self, openoffice_port=8100, autostart_openoffice=True, logger=None): |
1776 | + """ |
1777 | + Initialize the default values and try to connect to OpenOffice |
1778 | + (or even start it). |
1779 | + """ |
1780 | + import uno |
1781 | + |
1782 | + self.logger = logger |
1783 | + |
1784 | + self.port = openoffice_port |
1785 | + self.autostart = autostart_openoffice |
1786 | + |
1787 | + # |
1788 | + # Try to connect with retries (to start OpenOffice if autostart_openoffice is enabled) |
1789 | + # |
1790 | + retry = 2 |
1791 | + while retry: |
1792 | + retry = retry - 1 |
1793 | + try: |
1794 | + self.log("Connecting to OpenOffice...") |
1795 | + local_component_context = uno.getComponentContext() |
1796 | + resolver = local_component_context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local_component_context) |
1797 | + component_context = resolver.resolve("uno:socket,host=localhost,port=%s;urp;StarOffice.ComponentContext" % self.port) |
1798 | + self.desktop = component_context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", component_context) |
1799 | + self.log("...connected.") |
1800 | + except Exception, ex: |
1801 | + # |
1802 | + # Assume that the connection to OpenOffice has failed |
1803 | + # because OpenOffice is not running or listening |
1804 | + # and try to start it if autostart_openoffice. |
1805 | + # |
1806 | + self.log("...connection to OpenOffice failed!") |
1807 | + if autostart_openoffice and retry: |
1808 | + # |
1809 | + # Try to start a headless OpenOffice server |
1810 | + # |
1811 | + ooffice = None |
1812 | + for path in self.OOPATHS: |
1813 | + if os.path.exists(path): |
1814 | + ooffice = path |
1815 | + break |
1816 | + if ooffice: |
1817 | + self.log("Starting headless OpenOffice listener on port %s..." % self.port) |
1818 | + subprocess.call([ooffice, '-headless', '-nofirststartwizard', '-accept=socket,host=localhost,port=%s;urp;' % self.port]) |
1819 | + # Wait for OO to start |
1820 | + time.sleep(5) |
1821 | + self.log("...trying again...") |
1822 | + else: |
1823 | + raise OOHelperException(_("Couldn't connect to OpenOffice. Make sure you have an OpenOffice instance running and listening on the %s port. Details: %s") % (self.port, (hasattr(ex, 'value') and str(ex.value) or str(ex)))) |
1824 | + |
1825 | + |
1826 | + def open_document(self, file_name): |
1827 | + """ |
1828 | + Opens a document with OpenOffice |
1829 | + """ |
1830 | + import uno |
1831 | + file_url = uno.systemPathToFileUrl(abspath(file_name)) |
1832 | + |
1833 | + if os.environ.get('OSTYPE', False) == 'FreeBSD': |
1834 | + # Workaround a problemas con OpenOffice 3.1 en FreeBSD |
1835 | + file_url = file_url.encode('UTF-8') |
1836 | + |
1837 | + load_properties = { "Hidden": True } |
1838 | + file_ext = splitext(file_name)[1] |
1839 | + file_ext = file_ext and file_ext[1:].lower() or None |
1840 | + if self.IMPORT_FILTER_MAP.has_key(file_ext): |
1841 | + load_properties.update(self.IMPORT_FILTER_MAP[file_ext]) |
1842 | + |
1843 | + try: |
1844 | + document = self.desktop.loadComponentFromURL(file_url, "_blank", 0, self.make_properties(load_properties)) |
1845 | + except Exception, ex: |
1846 | + raise OOHelperException(_("Error loading file %s with OpenOffice: %s") % (file_name, ex)) |
1847 | + try: |
1848 | + document.refresh() |
1849 | + except AttributeError: |
1850 | + #print "Warning: Ignoring AttributeError on document refresh" |
1851 | + pass |
1852 | + |
1853 | + return document |
1854 | + |
1855 | + |
1856 | + def save_document(self, document, file_name, close_document=True): |
1857 | + """ |
1858 | + Saves a OpenOffice document to a file. |
1859 | + The file format will be detected (based on the file extension) |
1860 | + and the document will be converted to that format (see EXPORT_FILTER_MAPS). |
1861 | + """ |
1862 | + import uno |
1863 | + file_url = uno.systemPathToFileUrl(abspath(file_name)) |
1864 | + |
1865 | + if os.environ.get('OSTYPE', False) == 'FreeBSD': |
1866 | + # Workaround a problemas con OpenOffice 3.1 en FreeBSD |
1867 | + file_url = file_url.encode('UTF-8') |
1868 | + |
1869 | + save_properties = { } |
1870 | + |
1871 | + # |
1872 | + # Get the export filter options for the given file extension |
1873 | + # |
1874 | + file_ext = splitext(file_name)[1] |
1875 | + file_ext = file_ext and file_ext[1:].lower() or None |
1876 | + |
1877 | + export_filter_map = \ |
1878 | + (document.supportsService("com.sun.star.text.WebDocument") and self.EXPORT_FILTER_MAPS['web']) \ |
1879 | + or (document.supportsService("com.sun.star.text.GenericTextDocument") and self.EXPORT_FILTER_MAPS['text']) \ |
1880 | + or (document.supportsService("com.sun.star.sheet.SpreadsheetDocument") and self.EXPORT_FILTER_MAPS['spreadsheet']) \ |
1881 | + or (document.supportsService("com.sun.star.presentation.PresentationDocument") and self.EXPORT_FILTER_MAPS['presentation']) \ |
1882 | + or (document.supportsService("com.sun.star.drawing.DrawingDocument") and self.EXPORT_FILTER_MAPS['drawing']) |
1883 | + |
1884 | + if export_filter_map and export_filter_map.has_key(file_ext): |
1885 | + save_properties.update(export_filter_map[file_ext]) |
1886 | + |
1887 | + # |
1888 | + # Save the document |
1889 | + # |
1890 | + try: |
1891 | + document.storeToURL(file_url, self.make_properties(save_properties)) |
1892 | + except Exception, ex: |
1893 | + raise OOHelperException(_("Error saving file %s with OpenOffice: %s") % (file_name, ex)) |
1894 | + finally: |
1895 | + if close_document: |
1896 | + document.close(True) |
1897 | + |
1898 | + |
1899 | + |
1900 | + def replace_text_with_file_contents(self, document, placeholder_text, file_name): |
1901 | + """ |
1902 | + Inserts the given file into the current document. |
1903 | + The file contents will replace the placeholder text. |
1904 | + """ |
1905 | + import uno |
1906 | + file_url = uno.systemPathToFileUrl(abspath(file_name)) |
1907 | + |
1908 | + search = document.createSearchDescriptor() |
1909 | + search.SearchString = placeholder_text |
1910 | + |
1911 | + found = document.findFirst( search ) |
1912 | + while found: |
1913 | + try: |
1914 | + found.insertDocumentFromURL(file_url, ()) |
1915 | + except Exception, ex: |
1916 | + raise OOHelperException(_("Error inserting file %s on the OpenOffice document: %s") % (file_name, ex)) |
1917 | + found = document.findNext(found, search) |
1918 | + |
1919 | + |
1920 | + def make_properties(self, properties_dict): |
1921 | + """ |
1922 | + Helper to create a tuple of PropertyValue items from a dictionary. |
1923 | + """ |
1924 | + import uno |
1925 | + props = [] |
1926 | + for key in properties_dict: |
1927 | + prop = uno.createUnoStruct("com.sun.star.beans.PropertyValue") |
1928 | + prop.Name = key |
1929 | + prop.Value = properties_dict[key] |
1930 | + props.append(prop) |
1931 | + return tuple(props) |
1932 | + |
1933 | + |
1934 | + |
1935 | |
1936 | === added file 'pxgo_openoffice_reports/openoffice_report.py' |
1937 | --- pxgo_openoffice_reports/openoffice_report.py 1970-01-01 00:00:00 +0000 |
1938 | +++ pxgo_openoffice_reports/openoffice_report.py 2010-11-02 09:27:47 +0000 |
1939 | @@ -0,0 +1,528 @@ |
1940 | +# -*- coding: utf-8 -*- |
1941 | +# -*- encoding: utf-8 -*- |
1942 | +############################################################################## |
1943 | +# |
1944 | +# OpenOffice Reports |
1945 | +# Copyright (C) 2009 Pexego Sistemas Informáticos. All Rights Reserved |
1946 | +# $Id$ |
1947 | +# |
1948 | +# This program is free software: you can redistribute it and/or modify |
1949 | +# it under the terms of the GNU General Public License as published by |
1950 | +# the Free Software Foundation, either version 3 of the License, or |
1951 | +# (at your option) any later version. |
1952 | +# |
1953 | +# This program is distributed in the hope that it will be useful, |
1954 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1955 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1956 | +# GNU General Public License for more details. |
1957 | +# |
1958 | +# You should have received a copy of the GNU General Public License |
1959 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1960 | +# |
1961 | +############################################################################## |
1962 | + |
1963 | +""" |
1964 | +OpenOffice Reports - Reporting Engine based on Relatorio and OpenOffice. |
1965 | +""" |
1966 | +__author__ = "Borja López Soilán (Pexego)" |
1967 | + |
1968 | +import os |
1969 | +import report |
1970 | +import pooler |
1971 | +import netsvc |
1972 | +import base64 |
1973 | +import tempfile |
1974 | +import re |
1975 | +from tools.translate import _ |
1976 | +from oo_template import OOTemplate, OOTemplateException |
1977 | +import mx.DateTime |
1978 | +from datetime import datetime |
1979 | +import time |
1980 | + |
1981 | +DT_FORMAT = '%Y-%m-%d' |
1982 | +DHM_FORMAT = '%Y-%m-%d %H:%M:%S' |
1983 | +HM_FORMAT = '%H:%M:%S' |
1984 | + |
1985 | + |
1986 | +class OOReportException(Exception): |
1987 | + """ |
1988 | + OpenERP report exception |
1989 | + """ |
1990 | + def __init__(self, message): |
1991 | + # pylint: disable-msg=W0231 |
1992 | + self.message = message |
1993 | + def __str__(self): |
1994 | + return self.message |
1995 | + |
1996 | + |
1997 | +class OOReport(object): |
1998 | + """ |
1999 | + OpenOffice/Relatorio based report. |
2000 | + """ |
2001 | + |
2002 | + def log(self, message, level=netsvc.LOG_DEBUG): |
2003 | + """ |
2004 | + Helper method used print debug messages |
2005 | + """ |
2006 | + netsvc.Logger().notifyChannel('pxgo_openffice_reports', level, message) |
2007 | + |
2008 | + |
2009 | + def __init__(self, name, cr, uid, ids, data, context): |
2010 | + self.name = name |
2011 | + self.cr = cr |
2012 | + self.uid = uid |
2013 | + self.ids = ids |
2014 | + self.data = data |
2015 | + self.model = self.data['model'] |
2016 | + self.context = context or {} |
2017 | + self.dbname = cr.dbname |
2018 | + self.pool = pooler.get_pool( cr.dbname ) |
2019 | + self.openoffice_port = 8100 |
2020 | + self.autostart_openoffice = True |
2021 | + self.lang_dict_called = False |
2022 | + self.lang_dict = {} |
2023 | + self.default_lang = {} |
2024 | + self._transl_regex = re.compile('(\[\[.+?\]\])') |
2025 | + |
2026 | + |
2027 | + def get_report_context(self): |
2028 | + """ |
2029 | + Returns the context for the report |
2030 | + (Template method pattern) |
2031 | + """ |
2032 | + return {} |
2033 | + |
2034 | + |
2035 | + def _get_lang_dict(self): |
2036 | + """ |
2037 | + Helper function that returns a function that |
2038 | + sets the language for one object using the current database |
2039 | + connection (cr) and user (uid). |
2040 | + """ |
2041 | + pool_lang = self.pool.get('res.lang') |
2042 | + lang = self.context.get('lang', False) or 'en_US' |
2043 | + lang_ids = pool_lang.search(self.cr, self.uid, [('code','=',lang)])[0] |
2044 | + lang_obj = pool_lang.browse(self.cr, self.uid, lang_ids) |
2045 | + self.lang_dict.update({'lang_obj':lang_obj,'date_format':lang_obj.date_format,'time_format':lang_obj.time_format}) |
2046 | + self.default_lang[lang] = self.lang_dict.copy() |
2047 | + return True |
2048 | + |
2049 | + def get_digits(self, obj=None, f=None, dp=None): |
2050 | + """gets value for digits attribute""" |
2051 | + d = DEFAULT_DIGITS = 2 |
2052 | + if dp: |
2053 | + decimal_precision_obj = self.pool.get('decimal.precision') |
2054 | + ids = decimal_precision_obj.search(self.cr, self.uid, [('name', '=', dp)]) |
2055 | + if ids: |
2056 | + d = decimal_precision_obj.browse(self.cr, self.uid, ids)[0].digits |
2057 | + elif obj and f: |
2058 | + res_digits = getattr(obj._columns[f], 'digits', lambda x: ((16, DEFAULT_DIGITS))) |
2059 | + if isinstance(res_digits, tuple): |
2060 | + d = res_digits[1] |
2061 | + else: |
2062 | + d = res_digits(self.cr)[1] |
2063 | + elif (hasattr(obj, '_field') and\ |
2064 | + isinstance(obj._field, (float_class, function_class)) and\ |
2065 | + obj._field.digits): |
2066 | + d = obj._field.digits[1] or DEFAULT_DIGITS |
2067 | + return d |
2068 | + |
2069 | + def execute(self, output_format='pdf', report_file_name=None): |
2070 | + """ |
2071 | + Generate the report. |
2072 | + """ |
2073 | + |
2074 | + def _base64_to_string(field_value): |
2075 | + """ |
2076 | + Helper method to decode a binary field |
2077 | + """ |
2078 | + return base64.decodestring(field_value) |
2079 | + |
2080 | + def _get_attachments(): |
2081 | + """ |
2082 | + Helper function that returns a function that |
2083 | + gets the attachments for one object using the current database |
2084 | + connection (cr) and user (uid). |
2085 | + """ |
2086 | + def get_attachments_func(browse_object): |
2087 | + """ |
2088 | + Returns the attachments for one browse_object |
2089 | + """ |
2090 | + db, pool = pooler.get_db_and_pool(self.dbname) |
2091 | + cr = db.cursor() |
2092 | + att_facade = pool.get('ir.attachment') |
2093 | + # pylint: disable-msg=W0212 |
2094 | + attachment_ids = att_facade.search(cr, self.uid, [ |
2095 | + ('res_model', '=', browse_object._name), |
2096 | + ('res_id', '=', browse_object.id) |
2097 | + ]) |
2098 | + return att_facade.browse(cr, self.uid, attachment_ids) |
2099 | + return get_attachments_func |
2100 | + |
2101 | + def _field_to_image(field_value, rotate=None): |
2102 | + """ |
2103 | + Helper function that decodes and converts a binary field |
2104 | + into a png image and returns a tuple like the ones Relatorio |
2105 | + "image:" directive wants. |
2106 | + """ |
2107 | + from PIL import Image |
2108 | + data = base64.decodestring(field_value) |
2109 | + dummy_fd, temp_file_name = tempfile.mkstemp(prefix='openerp_oor_f2i_') |
2110 | + temp_file = open(temp_file_name, 'wb') |
2111 | + try: |
2112 | + temp_file.write(data) |
2113 | + finally: |
2114 | + temp_file.close() |
2115 | + image = Image.open(temp_file_name) |
2116 | + if rotate: |
2117 | + image = image.rotate(rotate) |
2118 | + image.save(temp_file_name, 'png') |
2119 | + return (open(temp_file_name, 'rb'), 'image/png') |
2120 | + |
2121 | + |
2122 | + def _chart_template_to_image(field=None, filename=None, source=None, filepath=None, source_format=None, encoding=None, context=None): |
2123 | + """ |
2124 | + Method that can be referenced from the template to include |
2125 | + charts as images. |
2126 | + When called it will process the file as a chart template, |
2127 | + generate a png image, and return the data plus the mime type. |
2128 | + """ |
2129 | + # Field is a binary field with a base64 encoded file that we will |
2130 | + # use as source if it is specified |
2131 | + source = field and base64.decodestring(field) or source |
2132 | + |
2133 | + filepath = filepath or filename |
2134 | + filename = None |
2135 | + assert filepath |
2136 | + |
2137 | + # |
2138 | + # Search for the file on the addons folder of OpenERP if the |
2139 | + # filepath does not exist. |
2140 | + # |
2141 | + if not os.path.exists(filepath): |
2142 | + search_paths = ['./bin/addons/%s' % filepath, './addons/%s' % filepath] |
2143 | + for path in search_paths: |
2144 | + if os.path.exists(path): |
2145 | + filepath = path |
2146 | + break |
2147 | + |
2148 | + # |
2149 | + # Genshi Base Template nor it's subclases |
2150 | + # (NewTextTemplate and chart.Template) |
2151 | + # seem to load the filepath/filename automatically; |
2152 | + # so we will read the file here if needed. |
2153 | + # |
2154 | + if not source: |
2155 | + file = open(filepath, 'rb') |
2156 | + try: |
2157 | + source = file.read() |
2158 | + finally: |
2159 | + file.close() |
2160 | + |
2161 | + # |
2162 | + # Process the chart subreport file |
2163 | + # |
2164 | + self.log("Generating chart subreport...") |
2165 | + from relatorio.templates.chart import Template |
2166 | + chart_subreport_template = Template(source=source, encoding=encoding) |
2167 | + data = chart_subreport_template #.generate(**context) |
2168 | + self.log("...done, chart generated.") |
2169 | + |
2170 | + return (data, 'image/png') |
2171 | + |
2172 | + |
2173 | + def _formatLang(): |
2174 | + """ |
2175 | + Helper function that returns a function that |
2176 | + formats received value to the language format. |
2177 | + """ |
2178 | + def _format_lang(value, digits=None, date=False, date_time=False, grouping=True, monetary=False, dp=False): |
2179 | + """ |
2180 | + Assuming 'Account' decimal.precision=3: |
2181 | + formatLang(value) -> digits=2 (default) |
2182 | + formatLang(value, digits=4) -> digits=4 |
2183 | + formatLang(value, dp='Account') -> digits=3 |
2184 | + formatLang(value, digits=5, dp='Account') -> digits=5 |
2185 | + """ |
2186 | + if digits is None: |
2187 | + if dp: |
2188 | + digits = self.get_digits(dp=dp) |
2189 | + else: |
2190 | + digits = self.get_digits(value) |
2191 | + |
2192 | + if isinstance(value, (str, unicode)) and not value: |
2193 | + return '' |
2194 | + |
2195 | + if not self.lang_dict_called: |
2196 | + self._get_lang_dict() |
2197 | + self.lang_dict_called = True |
2198 | + |
2199 | + if date or date_time: |
2200 | + if not str(value): |
2201 | + return '' |
2202 | + |
2203 | + date_format = self.lang_dict['date_format'] |
2204 | + parse_format = DT_FORMAT |
2205 | + if date_time: |
2206 | + value=value.split('.')[0] |
2207 | + date_format = date_format + " " + self.lang_dict['time_format'] |
2208 | + parse_format = DHM_FORMAT |
2209 | + if not isinstance(value, time.struct_time): |
2210 | + return time.strftime(date_format, time.strptime(value, parse_format)) |
2211 | + |
2212 | + if not isinstance(value, time.struct_time): |
2213 | + try: |
2214 | + date = mx.DateTime.strptime(str(value),parse_format) |
2215 | + except:# sometimes it takes converted values into value, so we dont need conversion. |
2216 | + return str(value) |
2217 | + else: |
2218 | + date = datetime(*value.timetuple()[:6]) |
2219 | + return date.strftime(date_format) |
2220 | + |
2221 | + return self.lang_dict['lang_obj'].format('%.' + str(digits) + 'f', value, grouping=grouping, monetary=monetary) |
2222 | + return _format_lang |
2223 | + |
2224 | + |
2225 | + def _format(text, oldtag=None): |
2226 | + """ |
2227 | + Removes white spaces |
2228 | + """ |
2229 | + return text.strip() |
2230 | + |
2231 | + |
2232 | + def translate(): |
2233 | + def _translate(text): |
2234 | + lang = self.context['lang'] |
2235 | + if lang and text and not text.isspace(): |
2236 | + transl_obj = self.pool.get('ir.translation') |
2237 | + piece_list = self._transl_regex.split(text) |
2238 | + for pn in range(len(piece_list)): |
2239 | + if not self._transl_regex.match(piece_list[pn]): |
2240 | + source_string = piece_list[pn].replace('\n', ' ').strip() |
2241 | + if len(source_string): |
2242 | + translated_string = transl_obj._get_source(self.cr, self.uid, self.name, ('report', 'rml'), lang, source_string) |
2243 | + if translated_string: |
2244 | + piece_list[pn] = piece_list[pn].replace(source_string, translated_string) |
2245 | + text = ''.join(piece_list) |
2246 | + return text |
2247 | + return _translate |
2248 | + |
2249 | + |
2250 | + def set_html_image(): |
2251 | + def _set_htmlImage(id, model=None, field=None, context=None): |
2252 | + if not id : |
2253 | + return '' |
2254 | + if not model: |
2255 | + model = 'ir.attachment' |
2256 | + try : |
2257 | + id = int(id) |
2258 | + res = self.pool.get(model).read(self.cr,self.uid,id) |
2259 | + if field : |
2260 | + return res[field] |
2261 | + elif model =='ir.attachment' : |
2262 | + return res['datas'] |
2263 | + else: |
2264 | + return '' |
2265 | + except Exception,e: |
2266 | + return '' |
2267 | + |
2268 | + return _set_htmlImage |
2269 | + |
2270 | + def setLang(): |
2271 | + """set lang to context""" |
2272 | + self.context['lang'] = lang |
2273 | + self.lang_dict_called = False |
2274 | + |
2275 | + |
2276 | + |
2277 | + assert output_format |
2278 | + |
2279 | + # |
2280 | + # Get the report path |
2281 | + # |
2282 | + if not report_file_name: |
2283 | + reports = self.pool.get( 'ir.actions.report.xml' ) |
2284 | + report_ids = reports.search(self.cr, self.uid, [('report_name', '=', self.name[7:])], context=self.context) |
2285 | + report_file_name = reports.read(self.cr, self.uid, report_ids[0], ['report_rml'])['report_rml'] |
2286 | + path = os.path.dirname(os.path.abspath(os.path.dirname(__file__))) |
2287 | + report_file_name = os.path.join(path, report_file_name) |
2288 | + |
2289 | + # |
2290 | + # Set the variables that the report must see |
2291 | + # |
2292 | + context = self.context |
2293 | + context['objects'] = self.pool.get(self.model).browse(self.cr, self.uid, self.ids, self.context) |
2294 | + context['ids'] = self.ids |
2295 | + context['model'] = self.model |
2296 | + context['data'] = self.data |
2297 | + |
2298 | + # |
2299 | + # Some aliases used on standard OpenERP reports |
2300 | + # |
2301 | + user = self.pool.get('res.users').browse(self.cr, self.uid, self.uid, self.context) |
2302 | + context['user'] = user |
2303 | + context['company'] = user.company_id |
2304 | + context['logo'] = user.company_id and user.company_id.logo |
2305 | + context['lang'] = context.get('lang') or (user.company_id and user.company_id.partner_id and user.company_id.partner_id.lang) |
2306 | + |
2307 | + # |
2308 | + # Add some helper function aliases |
2309 | + # |
2310 | + context['base64_to_string'] = context.get('base64_to_string') or _base64_to_string |
2311 | + context['b2s'] = context.get('b2s') or _base64_to_string |
2312 | + context['get_attachments'] = context.get('get_attachments') or _get_attachments() |
2313 | + context['field_to_image'] = context.get('field_to_image') or _field_to_image |
2314 | + context['f2i'] = context.get('f2i') or _field_to_image |
2315 | + context['chart_template_to_image'] = context.get('chart_template_to_image') or _chart_template_to_image |
2316 | + context['chart'] = context.get('chart') or _chart_template_to_image |
2317 | + context['translate'] = context.get('translate') or translate() |
2318 | + context['_'] = context.get('_') or translate() |
2319 | + context['formatLang'] = context.get('formatLang') or _formatLang() |
2320 | + context['format'] = context.get('format') or _format |
2321 | + context['setHtmlImage'] = context.get('setHtmlImage') or set_html_image() |
2322 | + context['time'] = context.get('time') or time |
2323 | + context['setLang'] = context.get('setLang') or setLang |
2324 | + |
2325 | + # Update the context with the custom report context |
2326 | + context.update(self.get_report_context()) |
2327 | + |
2328 | + # |
2329 | + # Process the template using the OpenOffice/Relatorio engine |
2330 | + # |
2331 | + data = self.process_template(report_file_name, output_format, context) |
2332 | + |
2333 | + return data |
2334 | + |
2335 | + def process_template(self, template_file, output_format, context=None): |
2336 | + """ |
2337 | + Will process a relatorio template and return the name |
2338 | + of the temp output file. |
2339 | + """ |
2340 | + if context is None: context = {} |
2341 | + # |
2342 | + # Get the template |
2343 | + # |
2344 | + self.log("Loading template %s from %s" % (self.name, template_file)) |
2345 | + try: |
2346 | + template = OOTemplate(source=None, |
2347 | + filepath=template_file, |
2348 | + output_format=output_format, |
2349 | + openoffice_port=self.openoffice_port, |
2350 | + autostart_openoffice=self.autostart_openoffice, |
2351 | + logger=self.log) |
2352 | + except OOTemplateException, ex: |
2353 | + raise OOReportException(_("Error loading the OpenOffice template: %s") % ex) |
2354 | + |
2355 | + # |
2356 | + # Process the template |
2357 | + # |
2358 | + self.log("Rendering template %s as %s" % (self.name, output_format)) |
2359 | + try: |
2360 | + data = template.oo_render(context=context) |
2361 | + except OOTemplateException, ex: |
2362 | + raise OOReportException(_("Error processing the OpenOffice template: %s") % ex) |
2363 | + |
2364 | + return data |
2365 | + |
2366 | + |
2367 | + |
2368 | +class openoffice_report(report.interface.report_int): |
2369 | + """ |
2370 | + Registers an OpenOffice/Relatorio report. |
2371 | + """ |
2372 | + |
2373 | + def __init__(self, name, model, parser=None, context=None): |
2374 | + if context is None: context = {} |
2375 | + # Remove report name from list of services if it already |
2376 | + # exists to avoid report_int's assert. We want to keep the |
2377 | + # automatic registration at login, but at the same time we |
2378 | + # need modules to be able to use a parser for certain reports. |
2379 | + if not name.startswith('report.'): |
2380 | + name = 'report.' + name |
2381 | + if name in netsvc.Service._services: |
2382 | + del netsvc.Service._services[name] |
2383 | + super(openoffice_report, self).__init__(name) |
2384 | + |
2385 | + self.model = model |
2386 | + self.parser = parser |
2387 | + self._context = context |
2388 | + |
2389 | + def create(self, cr, uid, ids, datas, context=None): |
2390 | + """ |
2391 | + Register the report with this handler. |
2392 | + """ |
2393 | + name = self.name |
2394 | + |
2395 | + reportClass = self.parser or OOReport |
2396 | + |
2397 | + |
2398 | + self._context.update(context) |
2399 | + |
2400 | + # |
2401 | + # Find the output format |
2402 | + # |
2403 | + reports = pooler.get_pool(cr.dbname).get( 'ir.actions.report.xml' ) |
2404 | + report_ids = reports.search(cr, uid, [('report_name', '=', name[7:])], context=context) |
2405 | + report_type = reports.read(cr, uid, report_ids[0], ['report_type'])['report_type'] |
2406 | + if report_type.startswith('oo-'): |
2407 | + output_format = report_type.split('-')[1] |
2408 | + else: |
2409 | + output_format = 'pdf' |
2410 | + |
2411 | + # |
2412 | + # Get the report |
2413 | + # |
2414 | + rpt = reportClass( name, cr, uid, ids, datas, self._context ) |
2415 | + return (rpt.execute(output_format=output_format), output_format ) |
2416 | + |
2417 | + |
2418 | +#Allow call to old create method |
2419 | +report.report_sxw.report_sxw.old_create = report.report_sxw.report_sxw.create |
2420 | + |
2421 | +def create(self, cr, uid, ids, data, context=None): |
2422 | + """ |
2423 | + Wrapper around the create method of report_sxw |
2424 | + that registers 'automagically' OpenOffice reports. |
2425 | + """ |
2426 | + if context is None: context = {} |
2427 | + |
2428 | + if self.internal_header: |
2429 | + context.update({'internal_header': self.internal_header}) |
2430 | + pool = pooler.get_pool(cr.dbname) |
2431 | + ir_obj = pool.get('ir.actions.report.xml') |
2432 | + report_xml_ids = ir_obj.search(cr, uid, |
2433 | + [('report_name', '=', self.name[7:])], context=context) |
2434 | + |
2435 | + fnct_ret = False |
2436 | + |
2437 | + if report_xml_ids: |
2438 | + report_xml = ir_obj.browse(cr, uid, report_xml_ids[0], context=context) |
2439 | + else: |
2440 | + title = '' |
2441 | + report_type= data.get('report_type', 'pdf') |
2442 | + |
2443 | + if not report_type.startswith('oo-'): |
2444 | + fnct_ret = self.old_create(cr, uid, ids, data, context=context) |
2445 | + else: |
2446 | + rml = tools.file_open(self.tmpl, subdir=None).read() |
2447 | + |
2448 | + class a(object): |
2449 | + def __init__(self, *args, **argv): |
2450 | + for key,arg in argv.items(): |
2451 | + setattr(self, key, arg) |
2452 | + |
2453 | + report_xml = a(title=title, report_type=report_type, report_rml_content=rml, name=title, attachment=False, header=self.header) |
2454 | + |
2455 | + report_xml.header = False |
2456 | + |
2457 | + if not fnct_ret: |
2458 | + oo_report = openoffice_report(self.name, data['model'], context=context) |
2459 | + fnct_ret = oo_report.create(cr, uid, ids, data, context) |
2460 | + if not fnct_ret: |
2461 | + return (False,False) |
2462 | + |
2463 | + return fnct_ret |
2464 | + |
2465 | +#override create method |
2466 | +report.report_sxw.report_sxw.create = create |
2467 | + |
2468 | |
2469 | === added file 'pxgo_openoffice_reports/report_xml.py' |
2470 | --- pxgo_openoffice_reports/report_xml.py 1970-01-01 00:00:00 +0000 |
2471 | +++ pxgo_openoffice_reports/report_xml.py 2010-11-02 09:27:47 +0000 |
2472 | @@ -0,0 +1,189 @@ |
2473 | +# -*- coding: utf-8 -*- |
2474 | +# -*- encoding: utf-8 -*- |
2475 | +############################################################################## |
2476 | +# |
2477 | +# OpenOffice Reports |
2478 | +# Copyright (C) 2009 Pexego Sistemas Informáticos. All Rights Reserved |
2479 | +# $Id$ |
2480 | +# |
2481 | +# This program is free software: you can redistribute it and/or modify |
2482 | +# it under the terms of the GNU General Public License as published by |
2483 | +# the Free Software Foundation, either version 3 of the License, or |
2484 | +# (at your option) any later version. |
2485 | +# |
2486 | +# This program is distributed in the hope that it will be useful, |
2487 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2488 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2489 | +# GNU General Public License for more details. |
2490 | +# |
2491 | +# You should have received a copy of the GNU General Public License |
2492 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
2493 | +# |
2494 | +############################################################################## |
2495 | + |
2496 | +""" |
2497 | +Extends report_xml to add new report types to the report_type selection. |
2498 | +""" |
2499 | +__author__ = "Borja López Soilán (Pexego)" |
2500 | + |
2501 | +import os |
2502 | +import base64 |
2503 | +from osv import osv, fields |
2504 | +import openoffice_report |
2505 | +from tools.translate import _ |
2506 | + |
2507 | +class report_xml_file(osv.osv): |
2508 | + _name = 'ir.actions.report.xml.file' |
2509 | + _columns = { |
2510 | + 'file': fields.binary('File', required=True, filters="*.odt,*.pdf,*.html,*.doc,*.rtf,*.txt,*.ods,*.xls,*.csv,*.odp,*.ppt,*.swf", help=''), |
2511 | + 'filename': fields.char('File Name', size=256, required=False, help=''), |
2512 | + 'report_id': fields.many2one('ir.actions.report.xml', 'Report', required=True, ondelete='cascade', help=''), |
2513 | + 'default': fields.boolean('Default', help=''), |
2514 | + } |
2515 | + def create(self, cr, uid, vals, context=None): |
2516 | + result = super(report_xml_file,self).create(cr, uid, vals, context) |
2517 | + self.pool.get('ir.actions.report.xml').update(cr, uid, [vals['report_id']], context) |
2518 | + return result |
2519 | + |
2520 | + def write(self, cr, uid, ids, vals, context=None): |
2521 | + result = super(report_xml_file,self).write(cr, uid, ids, vals, context) |
2522 | + for attachment in self.browse(cr, uid, ids, context): |
2523 | + self.pool.get('ir.actions.report.xml').update(cr, uid, [attachment.report_id.id], context) |
2524 | + return result |
2525 | + |
2526 | +report_xml_file() |
2527 | + |
2528 | +class report_xml(osv.osv): |
2529 | + """ |
2530 | + Extends report_xml to add new report types to the report_type selection. |
2531 | + |
2532 | + You may declare reports of the new types like this |
2533 | + <report id="report_REPORTNAME" |
2534 | + ... /> |
2535 | + <record model="ir.actions.report.xml" id="report_REPORTNAME"> |
2536 | + <field name="report_type">oo-odt</field> |
2537 | + </record> |
2538 | + """ |
2539 | + |
2540 | + _inherit = 'ir.actions.report.xml' |
2541 | + |
2542 | + _columns = { |
2543 | + 'report_type': fields.selection([ |
2544 | + ('pdf', 'pdf'), |
2545 | + ('html', 'html'), |
2546 | + ('raw', 'raw'), |
2547 | + ('sxw', 'sxw'), |
2548 | + ('odt', 'odt'), |
2549 | + ('html2html','Html from html'), |
2550 | + ('oo-pdf', 'OpenOffice - pdf output'), |
2551 | + ('oo-html', 'OpenOffice - html output'), |
2552 | + ('oo-odt', 'OpenOffice - odt output'), |
2553 | + ('oo-doc', 'OpenOffice - doc output'), |
2554 | + ('oo-rtf', 'OpenOffice - rtf output'), |
2555 | + ('oo-txt', 'OpenOffice - txt output'), |
2556 | + ('oo-ods', 'OpenOffice - ods output'), |
2557 | + ('oo-xls', 'OpenOffice - xls output'), |
2558 | + ('oo-csv', 'OpenOffice - csv output'), |
2559 | + ('oo-odp', 'OpenOffice - odp output'), |
2560 | + ('oo-ppt', 'OpenOffice - ppt output'), |
2561 | + ('oo-swf', 'OpenOffice - swf output'), |
2562 | + ], string='Type', required=True), |
2563 | + 'openoffice_file_ids': fields.one2many('ir.actions.report.xml.file', 'report_id', 'Files', help=''), |
2564 | + 'openoffice_model_id': fields.many2one('ir.model', 'Model', help=''), |
2565 | + 'openoffice_report': fields.boolean('Is OpenOffice Report?', help=''), |
2566 | + } |
2567 | + |
2568 | + def create(self, cr, uid, vals, context=None): |
2569 | + if context and context.get('openoffice_report'): |
2570 | + vals['model'] = self.pool.get('ir.model').browse(cr, uid, vals['openoffice_model_id'], context).model |
2571 | + vals['type'] = 'ir.actions.report.xml' |
2572 | +# vals['report_type'] = 'pdf' |
2573 | + vals['openoffice_report'] = True |
2574 | + vals['header'] = False |
2575 | + |
2576 | + return super(report_xml, self).create(cr, uid, vals, context) |
2577 | + |
2578 | + def write(self, cr, uid, ids, vals, context=None): |
2579 | + if context and context.get('openoffice_report'): |
2580 | + if 'openoffice_model_id' in vals: |
2581 | + vals['model'] = self.pool.get('ir.model').browse(cr, uid, vals['openoffice_model_id'], context).model |
2582 | + vals['type'] = 'ir.actions.report.xml' |
2583 | +# vals['report_type'] = 'pdf' |
2584 | + vals['openoffice_report'] = True |
2585 | + vals['header'] = False |
2586 | + |
2587 | + return super(report_xml, self).write(cr, uid, ids, vals, context) |
2588 | + |
2589 | + def unlink(self, cr, uid, ids, context=None): |
2590 | + """Deletes ir_values register when you delete any ir.actions.report.xml""" |
2591 | + if context is None: context = {} |
2592 | + for report in self.browse(cr, uid, ids): |
2593 | + values = self.pool.get('ir.values').search(cr, uid, [('value','=','ir.actions.report.xml,%s'% report.id)]) |
2594 | + if values: |
2595 | + self.pool.get('ir.values').unlink(cr, uid, values) |
2596 | + |
2597 | + return super(report_xml, self).unlink(cr, uid, ids, context=context) |
2598 | + |
2599 | + def update(self, cr, uid, ids, context={}): |
2600 | + """Browse attachments and store .odt into pxgo_openoffixe_reprots/custom_reports |
2601 | + directory. Also add or update ir.values data so they're shown on model views.""" |
2602 | + for report in self.browse(cr, uid, ids): |
2603 | + has_default = False |
2604 | + |
2605 | + for attachment in report.openoffice_file_ids: |
2606 | + content = attachment.file |
2607 | + fileName = attachment.filename |
2608 | + |
2609 | + if not fileName or not content: |
2610 | + continue |
2611 | + |
2612 | + path = self.save_file( fileName, content ) |
2613 | + for extension in ['.odt','.pdf','.html','.doc','.rtf','.txt','.ods','.xls','.csv','.odp','.ppt','.swf']: |
2614 | + if extension in fileName: |
2615 | + if attachment.default: |
2616 | + if has_default: |
2617 | + raise osv.except_osv(_('Error'), _('There is more than one report marked as default')) |
2618 | + |
2619 | + has_default = True |
2620 | + # Update path into report_rml field. |
2621 | + self.write(cr, uid, [report.id], { |
2622 | + 'report_rml': path |
2623 | + }) |
2624 | + |
2625 | + valuesId = self.pool.get('ir.values').search(cr, uid, [('value','=','ir.actions.report.xml,%s'% report.id)]) |
2626 | + data = { |
2627 | + 'name': report.name, |
2628 | + 'model': report.model, |
2629 | + 'key': 'action', |
2630 | + 'object': True, |
2631 | + 'key2': 'client_print_multi', |
2632 | + 'value': 'ir.actions.report.xml,%s'% report.id |
2633 | + } |
2634 | + |
2635 | + if not valuesId: |
2636 | + valuesId = self.pool.get('ir.values').create(cr, uid, data, context=context) |
2637 | + else: |
2638 | + self.pool.get('ir.values').write(cr, uid, valuesId, data, context=context) |
2639 | + valuesId = valuesId[0] |
2640 | + |
2641 | + if not has_default: |
2642 | + raise osv.except_osv(_('Error'), _('No report has been marked as default.')) |
2643 | + |
2644 | + # Ensure the report is registered so it can be used immediately |
2645 | + openoffice_report.openoffice_report( report.report_name, report.model ) |
2646 | + |
2647 | + return True |
2648 | + |
2649 | + def save_file(self, name, value): |
2650 | + """save the file to pxgo_openoffice_reports/custom_reports""" |
2651 | + path = os.path.abspath( os.path.dirname(__file__) ) |
2652 | + path += '/custom_reports/%s' % name |
2653 | + f = open( path, 'wb+' ) |
2654 | + try: |
2655 | + f.write( base64.decodestring( value ) ) |
2656 | + finally: |
2657 | + f.close() |
2658 | + path = 'pxgo_openoffice_reports/custom_reports/%s' % name |
2659 | + return path |
2660 | + |
2661 | +report_xml() |
2662 | |
2663 | === added file 'pxgo_openoffice_reports/report_xml_view.xml' |
2664 | --- pxgo_openoffice_reports/report_xml_view.xml 1970-01-01 00:00:00 +0000 |
2665 | +++ pxgo_openoffice_reports/report_xml_view.xml 2010-11-02 09:27:47 +0000 |
2666 | @@ -0,0 +1,103 @@ |
2667 | +<?xml version="1.0"?> |
2668 | +<openerp> |
2669 | +<data> |
2670 | + <record id="act_report_xml_view" model="ir.ui.view"> |
2671 | + <field name="name">ir.actions.report.xml.openoffice</field> |
2672 | + <field name="model">ir.actions.report.xml</field> |
2673 | + <field name="type">form</field> |
2674 | + <field name="inherit_id" ref="base.act_report_xml_view"/> |
2675 | + <field name="arch" type="xml"> |
2676 | + <field name="report_name" position="after"> |
2677 | + <button string="Update from attachments" name="update" type="object" colspan="2"/> |
2678 | + </field> |
2679 | + </field> |
2680 | + </record> |
2681 | + |
2682 | + <record id="act_report_openoffice_file_form" model="ir.ui.view"> |
2683 | + <field name="name">ir.actions.report.openoffice.file.form</field> |
2684 | + <field name="model">ir.actions.report.xml.file</field> |
2685 | + <field name="type">form</field> |
2686 | + <field name="arch" type="xml"> |
2687 | + <form string="Openoffice Reports File"> |
2688 | + <field name="file" filename="filename" colspan="4"/> |
2689 | + <field name="filename" colspan="4"/> |
2690 | + <field name="default" colspan="4"/> |
2691 | + </form> |
2692 | + </field> |
2693 | + </record> |
2694 | + <record id="act_report_openoffice_file_tree" model="ir.ui.view"> |
2695 | + <field name="name">ir.actions.report.openoffice.file.tree</field> |
2696 | + <field name="model">ir.actions.report.xml.file</field> |
2697 | + <field name="type">tree</field> |
2698 | + <field name="arch" type="xml"> |
2699 | + <tree string="Openoffice Reports File"> |
2700 | + <field name="filename"/> |
2701 | + <field name="default"/> |
2702 | + </tree> |
2703 | + </field> |
2704 | + </record> |
2705 | + |
2706 | + <record id="act_report_openoffice_form" model="ir.ui.view"> |
2707 | + <field name="name">ir.actions.report.openoffice.form</field> |
2708 | + <field name="model">ir.actions.report.xml</field> |
2709 | + <field name="type">form</field> |
2710 | + <field name="priority">20</field> |
2711 | + <field name="arch" type="xml"> |
2712 | + <form string="openoffice Reports"> |
2713 | + <field name="name" select="1"/> |
2714 | + <field name="openoffice_model_id" required="True" select="1"/> |
2715 | + <field name="report_name" select="1"/> |
2716 | + <field name="report_type" required="True" select="1"/> |
2717 | +<!-- <field name="attachment"/>--> |
2718 | +<!-- <field name="attachment_use"/>--> |
2719 | + <separator string="Files" colspan="4"/> |
2720 | + <field name="openoffice_file_ids" colspan="4" nolabel="1" /> |
2721 | + <separator string="Groups" colspan="4"/> |
2722 | + <field name="groups_id" colspan="4" nolabel="1" /> |
2723 | + </form> |
2724 | + </field> |
2725 | + </record> |
2726 | + |
2727 | + <record id="act_report_openoffice_tree" model="ir.ui.view"> |
2728 | + <field name="name">ir.actions.report.openoffice.tree</field> |
2729 | + <field name="model">ir.actions.report.xml</field> |
2730 | + <field name="type">tree</field> |
2731 | + <field name="priority">20</field> |
2732 | + <field name="arch" type="xml"> |
2733 | + <tree string="Openoffice Reports"> |
2734 | + <field name="name"/> |
2735 | + <field name="openoffice_model_id"/> |
2736 | + <field name="report_name"/> |
2737 | + <field name="report_type"/> |
2738 | + <field name="attachment"/> |
2739 | + </tree> |
2740 | + </field> |
2741 | + </record> |
2742 | + |
2743 | + |
2744 | + <record id="ir_action_report_openoffice" model="ir.actions.act_window"> |
2745 | + <field name="name">Openoffice Reports</field> |
2746 | + <field name="type">ir.actions.act_window</field> |
2747 | + <field name="res_model">ir.actions.report.xml</field> |
2748 | + <field name="view_type">form</field> |
2749 | + <field name="view_mode">tree,form</field> |
2750 | + <field name="context">{'openoffice_report': True}</field> |
2751 | + <field name="domain">[('openoffice_report','=',True)]</field> |
2752 | + </record> |
2753 | + <record id="ir_action_report_openoffice_view0" model="ir.actions.act_window.view"> |
2754 | + <field name="act_window_id" ref="ir_action_report_openoffice"/> |
2755 | + <field name="view_mode">tree</field> |
2756 | + <field name="view_id" ref="act_report_openoffice_tree"/> |
2757 | + <field name="sequence">0</field> |
2758 | + </record> |
2759 | + <record id="ir_action_report_openoffice_view1" model="ir.actions.act_window.view"> |
2760 | + <field name="act_window_id" ref="ir_action_report_openoffice"/> |
2761 | + <field name="view_mode">form</field> |
2762 | + <field name="view_id" ref="act_report_openoffice_form"/> |
2763 | + <field name="sequence">1</field> |
2764 | + </record> |
2765 | + |
2766 | + <menuitem parent="base.menu_custom" name="OpenOffice Reports" id="openoffice_reports_menu"/> |
2767 | + <menuitem action="ir_action_report_openoffice" id="menu_ir_action_report_openoffice" parent="openoffice_reports_menu"/> |
2768 | +</data> |
2769 | +</openerp> |
2770 | |
2771 | === added directory 'pxgo_openoffice_reports/security' |
2772 | === added file 'pxgo_openoffice_reports/security/ir.model.access.csv' |
2773 | --- pxgo_openoffice_reports/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 |
2774 | +++ pxgo_openoffice_reports/security/ir.model.access.csv 2010-11-02 09:27:47 +0000 |
2775 | @@ -0,0 +1,3 @@ |
2776 | +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
2777 | +"access_ir_actions_report_xml_file_all","ir_actions_report_xml_file","model_ir_actions_report_xml_file",,1,0,0,0 |
2778 | +"access_ir_actions_report_xml_file_group_system","ir_actions_report_xml_file_group_system","model_ir_actions_report_xml_file","base.group_system",1,1,1,1 |
2779 | \ No newline at end of file |