Commit a84dac8a authored by Arnaud Fontaine's avatar Arnaud Fontaine

WIP: ZODB Components: Migrate testOOoStyle{WithFlare} and split it into 2 tests (ODT, ODS).

parent ffc360ac
......@@ -27,19 +27,101 @@
#
##############################################################################
import unittest
"""This module provides utilities for testing ODF files.
Validator: a class defining a `validate` method that expects odf file content
as first argument and returns list of errors.
"""
import os
import sys
import tempfile
import zipfile
import popen2
from cStringIO import StringIO
try:
import lxml
except ImportError:
lxml = None
try:
import odfpy
except ImportError:
odfpy = None
if lxml:
class LXMLValidator:
"""Validate ODF document using RelaxNG and lxml"""
schema_url = \
'http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-schema-v1.1.rng'
def __init__(self, schema_url=schema_url):
self.schema_url = schema_url
self.schema_path = os.path.join(
os.path.dirname(__file__), os.path.basename(schema_url))
self.relaxng = lxml.etree.RelaxNG(lxml.etree.parse(self.schema_path))
def validate(self, odf_file_content):
error_list = []
odf_file = StringIO(odf_file_content)
for f in ('content.xml', 'meta.xml', 'styles.xml', 'settings.xml'):
error_list.extend(self._validateXML(odf_file, f))
return error_list
def _validateXML(self, odf_file, content_file_name):
zfd = zipfile.ZipFile(odf_file)
lxml.etree.parse(StringIO(zfd.read(content_file_name)))
return []
"""
# The following is the past implementation that validates with
# RelaxNG schema. But recent LibreOffice uses extended odf
# format by default, that does not pass the RelaxNG validation.
doc.docinfo.URL = content_file_name
self.relaxng.validate(doc)
return [error for error in str(self.relaxng.error_log).splitlines(True)]
"""
Validator = LXMLValidator
elif odfpy:
class OdflintValidator:
"""Validates ODF files using odflint, available on pypi
http://opendocumentfellowship.org/development/projects/odfpy
"""
def validate(self, odf_file_content):
fd, file_name = tempfile.mkstemp()
os.write(fd, odf_file_content)
os.close(fd)
stdout, stdin = popen2.popen4('odflint %s' % file_name)
stdin.close()
error_list = ''
for line in stdout:
if line.startswith('Error: '):
error_list += line
os.unlink(file_name)
return error_list
Validator = OdflintValidator
else:
class NoValidator:
"""Does not actually validate, but keep the interface."""
def validate(self, odf_file_content):
print >> sys.stderr, 'No validator available'
Validator = NoValidator
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyLocalizer
from Products.ERP5Form.Selection import Selection
from Testing import ZopeTestCase
from Products.ERP5OOo.tests.utils import Validator
import httplib
HTTP_OK = httplib.OK
# setting this to True allows the .publish() calls to provide tracebacks
debug = False
class TestOOoStyle(ERP5TypeTestCase, ZopeTestCase.Functional):
"""Tests ODF styles for ERP5."""
skin = None
......@@ -71,7 +153,7 @@ class TestOOoStyle(ERP5TypeTestCase, ZopeTestCase.Functional):
person_module.pers.newContent(portal_type='Embedded File', id='img')
if person_module._getOb('pers_without_image', None) is None:
person = person_module.newContent(
person_module.newContent(
portal_type='Person',
id = 'pers_without_image',
first_name = 'Test')
......@@ -385,7 +467,7 @@ class TestOOoStyle(ERP5TypeTestCase, ZopeTestCase.Functional):
if self.skin == 'ODT':
# Is it good to do this only for ODT ?
from Products.ERP5OOo.OOoUtils import OOoParser
from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser()
parser.openFromString(body)
content_xml = parser.oo_files['content.xml']
......@@ -415,7 +497,7 @@ class TestOOoStyle(ERP5TypeTestCase, ZopeTestCase.Functional):
body = response.getBody()
self._validate(body)
from Products.ERP5OOo.OOoUtils import OOoParser
from erp5.component.module.OOoUtils import OOoParser
parser = OOoParser()
parser.openFromString(body)
content_xml = parser.oo_files['content.xml']
......@@ -455,19 +537,14 @@ class TestOOoStyle(ERP5TypeTestCase, ZopeTestCase.Functional):
self.assertFalse(response.getHeader('content-disposition'))
self.assertTrue('office:document-content' in response.getBody())
class TestODTStyle(TestOOoStyle):
skin = 'ODT'
content_type = 'application/vnd.oasis.opendocument.text'
class TestODSStyle(TestOOoStyle):
skin = 'ODS'
content_type = 'application/vnd.oasis.opendocument.spreadsheet'
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestODTStyle))
suite.addTest(unittest.makeSuite(TestODSStyle))
return suite
class TestOOoStyleWithFlare(TestOOoStyle):
"""Tests ODF styles for ERP5 with Flare."""
def getTitle(self):
return "Test OOo Style with Flare"
def afterSetUp(self):
default_pref = self.portal.portal_preferences.default_site_preference
default_pref.setPreferredConversionCacheFactory('dms_cache_factory')
if default_pref.getPreferenceState() != 'global':
default_pref.enable()
TestOOoStyle.afterSetUp(self)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Module Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>OOoTestUtil</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.tests.utils</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>module.erp5.OOoTestUtil</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Module Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
module.erp5.ImageUtil
module.erp5.TransformImageToBmp
module.erp5.TransformImageToPcx
module.erp5.TransformLib
module.erp5.ImageUtil
\ No newline at end of file
module.erp5.OOoTestUtil
\ No newline at end of file
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2007 Nexedi SA and Contributors. All Rights Reserved.
......@@ -26,90 +27,13 @@
#
##############################################################################
"""This module provides utilities for testing ODF files.
Validator: a class defining a `validate` method that expects odf file content
as first argument and returns list of errors.
"""
import os
import sys
import tempfile
import zipfile
import popen2
import urllib2
from cStringIO import StringIO
try:
import lxml
except ImportError:
lxml = None
try:
import odfpy
except ImportError:
odfpy = None
if lxml:
class LXMLValidator:
"""Validate ODF document using RelaxNG and lxml"""
schema_url = \
'http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-schema-v1.1.rng'
def __init__(self, schema_url=schema_url):
self.schema_url = schema_url
self.schema_path = os.path.join(
os.path.dirname(__file__), os.path.basename(schema_url))
self.relaxng = lxml.etree.RelaxNG(lxml.etree.parse(self.schema_path))
def validate(self, odf_file_content):
error_list = []
odf_file = StringIO(odf_file_content)
for f in ('content.xml', 'meta.xml', 'styles.xml', 'settings.xml'):
error_list.extend(self._validateXML(odf_file, f))
return error_list
def _validateXML(self, odf_file, content_file_name):
zfd = zipfile.ZipFile(odf_file)
doc = lxml.etree.parse(StringIO(zfd.read(content_file_name)))
return []
# The following is the past implementation that validates with
# RelaxNG schema. But recent LibreOffice uses extended odf
# format by default, that does not pass the RelaxNG validation.
doc.docinfo.URL = content_file_name
self.relaxng.validate(doc)
return [error for error in str(self.relaxng.error_log).splitlines(True)]
Validator = LXMLValidator
elif odfpy:
class OdflintValidator:
"""Validates ODF files using odflint, available on pypi
http://opendocumentfellowship.org/development/projects/odfpy
"""
def validate(self, odf_file_content):
fd, file_name = tempfile.mkstemp()
os.write(fd, odf_file_content)
os.close(fd)
stdout, stdin = popen2.popen4('odflint %s' % file_name)
stdin.close()
error_list = ''
for line in stdout:
if line.startswith('Error: '):
error_list += line
os.unlink(file_name)
return error_list
Validator = OdflintValidator
else:
class NoValidator:
"""Does not actually validate, but keep the interface."""
def validate(self, odf_file_content):
print >> sys.stderr, 'No validator available'
Validator = NoValidator
from erp5.component.module.OOoTestUtil import TestOOoStyle
class TestODSStyle(TestOOoStyle):
skin = 'ODS'
content_type = 'application/vnd.oasis.opendocument.spreadsheet'
def test_suite():
import unittest
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestODSStyle))
return suite
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testODSStyle</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.tests.testOOoStyle</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testODSStyle</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -26,35 +26,14 @@
#
##############################################################################
import unittest
from testOOoStyle import TestOOoStyle
class TestOOoStyleWithFlare(TestOOoStyle):
"""Tests ODF styles for ERP5 with Flare."""
def getTitle(self):
return "Test OOo Style with Flare"
def afterSetUp(self):
default_pref = self.portal.portal_preferences.default_site_preference
default_pref.setPreferredConversionCacheFactory('dms_cache_factory')
if default_pref.getPreferenceState() != 'global':
default_pref.enable()
TestOOoStyle.afterSetUp(self)
class TestODTStyle(TestOOoStyleWithFlare):
skin = 'ODT'
content_type = 'application/vnd.oasis.opendocument.text'
from erp5.component.module.OOoTestUtil import TestOOoStyleWithFlare
class TestODSStyle(TestOOoStyleWithFlare):
skin = 'ODS'
content_type = 'application/vnd.oasis.opendocument.spreadsheet'
def test_suite():
import unittest
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestODTStyle))
suite.addTest(unittest.makeSuite(TestODSStyle))
return suite
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testODSStyleWithFlare</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.tests.testOOoStyleWithFlare</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testODSStyleWithFlare</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
test.erp5.testODSStyle
test.erp5.testODSStyleWithFlare
\ No newline at end of file
erp5_full_text_mroonga_catalog
erp5_base
erp5_ui_test
erp5_core_proxy_field_legacy
\ No newline at end of file
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2007 Nexedi SA and Contributors. All Rights Reserved.
# Jerome Perrin <jerome@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.module.OOoTestUtil import TestOOoStyle
class TestODTStyle(TestOOoStyle):
skin = 'ODT'
content_type = 'application/vnd.oasis.opendocument.text'
def test_suite():
import unittest
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestODTStyle))
return suite
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testODTStyle</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.tests.testOOoStyle</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testODTStyle</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
# -*- coding: utf-8 -*-
##############################################################################
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Nicolas Delaby <nicolas@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from erp5.component.module.OOoTestUtil import TestOOoStyleWithFlare
class TestODTStyle(TestOOoStyleWithFlare):
skin = 'ODT'
content_type = 'application/vnd.oasis.opendocument.text'
def test_suite():
import unittest
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestODTStyle))
return suite
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testODTStyleWithFlare</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>Products.ERP5OOo.tests.testOOoStyleWithFlare</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testODTStyleWithFlare</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
test.erp5.testFormPrintoutAsODG
test.erp5.testFormPrintoutAsODT
test.erp5.testODTStyle
test.erp5.testODTStyleWithFlare
test.erp5.testOOoDynamicStyle
\ No newline at end of file
# make this directory a package
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment