From 8082be66d2be78497859f52371a29d615019f72a Mon Sep 17 00:00:00 2001
From: Kevin Deldycke <kevin@nexedi.com>
Date: Tue, 25 Oct 2005 19:48:17 +0000
Subject: [PATCH] First release of guy's work.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@4128 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5OOo/CreatePropertySheet.py | 323 +++++++++++++++++++++++++
 product/ERP5OOo/FieldHelpTopic.py      |  35 +++
 product/ERP5OOo/FieldRegistry.py       | 175 ++++++++++++++
 product/ERP5OOo/ScribusUtils.py        | 139 +++++++++++
 4 files changed, 672 insertions(+)
 create mode 100755 product/ERP5OOo/CreatePropertySheet.py
 create mode 100755 product/ERP5OOo/FieldHelpTopic.py
 create mode 100755 product/ERP5OOo/FieldRegistry.py
 create mode 100755 product/ERP5OOo/ScribusUtils.py

diff --git a/product/ERP5OOo/CreatePropertySheet.py b/product/ERP5OOo/CreatePropertySheet.py
new file mode 100755
index 0000000000..ae0f56554a
--- /dev/null
+++ b/product/ERP5OOo/CreatePropertySheet.py
@@ -0,0 +1,323 @@
+#############################################################################
+#
+# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
+#                    Jean-Paul Smets-Solanes <jp@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 Products.PythonScripts.Utility import allow_class
+from ZPublisher.HTTPRequest import FileUpload
+from xml.dom.ext.reader import PyExpat
+from xml.dom import Node, minidom
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass, get_request
+from zipfile import ZipFile, ZIP_DEFLATED
+from StringIO import StringIO
+from zLOG import LOG
+import imghdr
+import random
+import getopt, sys, os
+from urllib import quote
+
+ZOPE_INSTANCE_HOME = os.environ.get("INSTANCE_HOME", "/var/lib/zope/")
+
+class Getter_Setter:
+  """
+  Create PropertySheet of module
+  """
+  
+  # Declarative security
+  security = ClassSecurityInfo()
+  
+
+  security.declarePublic('create_PropertySheet')
+  def create_PropertySheet(self, name_file = None, personnal_properties = []):
+    """
+    create PropertySheet in /var/lib/zope/Products/ERP5/PropertySheet/
+    """
+    path_name_file = os.path.join(ZOPE_INSTANCE_HOME, 'PropertySheet', str(name_file) + '.py')
+    file = open(path_name_file,'w')
+    file.seek(0)
+
+    string = """
+#############################################################################
+#
+# Copyright (c) 2002-2005 Nexedi SARL and Contributors. All Rights Reserved.
+#                         Jean-Paul Smets-Solanes <jp@nexedi.com> 
+#                         Kevin Deldycke <kevin@nexedi.com> 
+#                         Guy Oswald OBAMA <guy@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.
+#
+##############################################################################
+    """
+
+    file.write(string)
+    
+    string = '\n\nclass ' + str(name_file) + ' :\n'
+    file.write(string)
+    string = 2*' ' + '"""\n'
+    file.write(string)
+    string = 6*' ' + str(name_file) + ' properties and categories\n'
+    file.write(string)
+    string = 2*' ' + '"""\n\n'
+    file.write(string)
+    string = 2*' ' + '_properties = (\n'
+    file.write(string)
+    string = 6*' ' + '# Personal properties\n'
+    file.write(string)
+    
+    for i in range(len(personnal_properties)):
+      string = 6*' ' + "{   'id'          : '" + personnal_properties[i][0][3:] + "' \n"
+      file.write(string)
+
+      string = 6*' ' + ",   'description' : '" + personnal_properties[i][1] + "' \n"
+      file.write(string)
+
+      string = 6*' ' + ",   'type'        : '" + personnal_properties[i][2] + "' \n"
+      file.write(string)
+
+      string = 6*' ' + ",   'mode'        : '" + personnal_properties[i][3] + "' \n"
+      file.write(string)
+
+      string = 6*' ' + "}, \n"
+      file.write(string)
+
+    string = 2*' ' + ')\n'
+    file.write(string)
+
+    string = '\n\n' + 2*' ' + str("_categories = ( 'source_section', 'destination_section')") + '\n'
+    file.write(string)    
+
+    file.close()
+
+    # get text to create a new PropertySheet in portal_classes
+    file1 = open(path_name_file, 'r')
+    lines_list = file1.readlines()
+    text = ''
+    for line in lines_list:
+      text = text + line
+    file1.close() 
+   
+    path_name_file_1 = '/var/lib/zope/Products/ERP5/PropertySheet/' + str(name_file) + '.py'
+    file2 = open(path_name_file_1, 'w')
+    file2.seek(0)
+    file2.write(text)
+    file2.close()
+    
+    return text
+
+  security.declarePublic('create_Document')
+  def create_Document(self, name_file = None, object_portal_type = None):
+    """
+    create PropertySheet in /var/lib/zope/Products/ERP5/Document/
+    """
+    path_name_file = os.path.join(ZOPE_INSTANCE_HOME, 'Document', str(name_file) + '.py')
+    #print path_name_file
+    file = open(path_name_file,'w')
+    file.seek(0)
+
+    
+    string = '############################################################################# \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '# Copyright (c) 2002-2005 Nexedi SARL and Contributors. All Rights Reserved. \n'
+    file.write(string)
+    string = '#                         Jean-Paul Smets-Solanes <jp@nexedi.com> \n'
+    file.write(string)
+    string = '#                         Kevin Deldycke <kevin@nexedi.com> \n'
+    file.write(string)
+    string = '#                         Guy Oswald OBAMA <guy@nexedi.com> \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '# WARNING: This program as such is intended to be used by professional \n'
+    file.write(string)
+    string = '# programmers who take the whole responsability of assessing all potential \n'
+    file.write(string)
+    string = '# consequences resulting from its eventual inadequacies and bugs \n'
+    file.write(string)
+    string = '# End users who are looking for a ready-to-use solution with commercial \n'
+    file.write(string)
+    string = '# garantees and support are strongly adviced to contract a Free Software \n'
+    file.write(string)
+    string = '# Service Company \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '# This program is Free Software; you can redistribute it and/or \n'
+    file.write(string)
+    string = '# modify it under the terms of the GNU General Public License \n'
+    file.write(string)
+    string = '# as published by the Free Software Foundation; either version 2 \n'
+    file.write(string)
+    string = '# of the License, or (at your option) any later version. \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '# This program is distributed in the hope that it will be useful, \n'
+    file.write(string)
+    string = '# but WITHOUT ANY WARRANTY; without even the implied warranty of \n'
+    file.write(string)
+    string = '# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the \n'
+    file.write(string)
+    string = '# GNU General Public License for more details. \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '# You should have received a copy of the GNU General Public License \n'
+    file.write(string)
+    string = '# along with this program; if not, write to the Free Software \n'
+    file.write(string)
+    string = '# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. \n'
+    file.write(string)
+    string = '# \n'
+    file.write(string)
+    string = '############################################################################## \n\n\n\n'
+    file.write(string)
+    
+    string = 'from AccessControl import ClassSecurityInfo \n\n'
+    file.write(string)
+    string = 'from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface \n'
+    file.write(string)
+    string = 'from Products.ERP5Type.Utils import assertAttributePortalType \n'
+    file.write(string)
+    string = 'from Products.ERP5Type.XMLObject import XMLObject \n\n'
+    file.write(string)
+    string = 'from Products.ERP5.Core.Node import Node \n\n'
+    file.write(string)
+    string = 'from Products.ERP5.Document.Entity import Entity \n\n'
+    file.write(string)
+    string = '#from Products.ERP5Type.Base import Base \n\n'
+    file.write(string)
+    string = 'class ' + str(name_file) + '(Node, XMLObject): \n'
+    file.write(string)
+
+
+    string = 2*' ' + '""" \n'
+    file.write(string)
+    string = 2*' ' + '  An ' + str(name_file) + ' object holds the information about \n'
+    file.write(string)
+    string = 2*' ' + '  an ' + str(name_file) + '. \n\n'
+    file.write(string)
+
+    string = 2*' ' + '  ' + str(name_file) + ' objects can contain Coordinate objects \n'
+    file.write(string)
+    string = 2*' ' + '  as well a documents of various types. \n'
+    file.write(string)
+
+    string = 2*' ' + '  ' + str(name_file) + ' objects can be synchronized accross multiple \n'
+    file.write(string)
+    string = 2*' ' + '  sites. \n'
+    file.write(string)
+
+    string = 2*' ' + '  ' + str(name_file) + ' objects inherit from the Node base class \n'
+    file.write(string)
+    string = 2*' ' + '  (one of the 5 base classes in the ERP5 universal business model) \n'
+    file.write(string)
+    string = 2*' ' + '""" \n\n\n'
+    file.write(string)
+    
+    
+    string = 2*' ' + "meta_type = 'ERP5 " + str(name_file) + "' \n"
+    file.write(string)
+    string = 2*' ' + "portal_type = '" + str(object_portal_type) + "' \n"
+    file.write(string)
+    string = 2*' ' + "add_permission = Permissions.AddPortalContent \n"
+    file.write(string)
+    string = 2*' ' + "isPortalContent = 1 \n"
+    file.write(string)
+    string = 2*' ' + "isRADContent = 1 \n\n"
+    file.write(string)
+
+    string = 2*' ' + "# Declarative security \n"
+    file.write(string)
+    string = 2*' ' + "security = ClassSecurityInfo() \n"
+    file.write(string)
+    string = 2*' ' + "security.declareObjectProtected(Permissions.View) \n\n"
+    file.write(string)
+
+    string = 2*' ' + "# Declarative properties \n"
+    file.write(string)
+    string = 2*' ' + "property_sheets = ( PropertySheet.Base \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet.XMLObject \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet.CategoryCore \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet.DublinCore \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet.Arrow \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet.Task \n"
+    file.write(string)
+    string = 2*' ' + "                  , PropertySheet." + str(name_file) + " \n"
+    file.write(string)
+    string = 2*' ' + "                  ) \n\n"
+    file.write(string)
+    
+    file.close()
+
+    # get text to create a new Document in portal_classes    
+    file1 = open(path_name_file,'r')
+    lines_list = file1.readlines()
+    text = ''
+    for line in lines_list:
+      text = text + line
+    file1.close()
+
+    path_name_file_1 = '/var/lib/zope/Products/ERP5/Document/' + str(name_file) + '.py'
+    file2 = open(path_name_file_1,'w')
+    file2.seek(0)
+    file2.write(text)
+    file2.close()    
+        
+    return text
+
+InitializeClass(Getter_Setter)
+allow_class(Getter_Setter)  
+
+
+        
diff --git a/product/ERP5OOo/FieldHelpTopic.py b/product/ERP5OOo/FieldHelpTopic.py
new file mode 100755
index 0000000000..77a47ecf61
--- /dev/null
+++ b/product/ERP5OOo/FieldHelpTopic.py
@@ -0,0 +1,35 @@
+from Globals import DTMLFile
+from HelpSys import HelpTopic
+
+class FieldHelpTopic(HelpTopic.HelpTopic):
+    """A special help topic for fields.
+    """
+    meta_type = 'Help Topic'
+    
+    def __init__(self, id, title, field_class,
+                 permissions=None, categories=None):
+        self.id = id
+        self.title = title
+        self.field_class = field_class
+                                              
+        if permissions is not None:
+            self.permissions = permissions
+        if categories is not None:
+            self.categories = categories
+            
+    index_html = DTMLFile('dtml/FieldHelpTopic', globals())
+    
+    def SearchableText(self):
+        """Full text of the Help Topic, for indexing purposes."""
+        return "" # return self.index_html()
+
+    def get_groups(self):
+        """Get form groups of this field.
+        """
+        return self.field_class.form.get_groups()
+
+    def get_fields_in_group(self, group):
+        """Get the fields in the group.
+        """
+        return self.field_class.form.get_fields_in_group(group)
+    
diff --git a/product/ERP5OOo/FieldRegistry.py b/product/ERP5OOo/FieldRegistry.py
new file mode 100755
index 0000000000..e9b924438f
--- /dev/null
+++ b/product/ERP5OOo/FieldRegistry.py
@@ -0,0 +1,175 @@
+import os
+import OFS
+from Globals import ImageFile
+from FieldHelpTopic import FieldHelpTopic
+from AccessControl import ClassSecurityInfo
+from Products.PythonScripts.Utility import allow_class
+from ZPublisher.HTTPRequest import FileUpload
+from Globals import InitializeClass, get_request
+from StringIO import StringIO
+from zLOG import LOG
+import getopt, sys, os
+from urllib import quote
+
+
+class FieldRegistry:
+    """A registry of fields, maintaining a dictionary with
+    the meta_type of the field classes as key and the field class as
+    values. Updates the Form as necessary as well.
+    """
+    
+    # Declarative security
+    security = ClassSecurityInfo()
+    
+    def __init__(self):
+        """Initializer of FieldRegistry.
+        """
+        self._fields = {}
+
+    def get_field_class(self, fieldname):
+        """Get a certain field class by its name (meta_type)
+        fieldname -- the name of the field to get from the registry
+        """
+        return self._fields[fieldname]
+
+    def get_field_classes(self):
+        """Return all fields.
+        """
+        return self._fields
+    
+    def registerField(self, field_class, icon=None):
+        """Register field with Formulator.
+        field_class -- the class of the field to be registered
+        icon        -- optional filename of the icon
+        """
+        # put it in registry dictionary
+        self._fields[field_class.meta_type] = field_class
+        # set up dummy fields in field's form
+        initializeFieldForm(field_class)
+        # set up the icon if a filename is supplied
+        if icon:
+            setupIcon(field_class, icon, 'Formulator')
+
+    def registerFieldHelp(self, context):
+        """Register field help topics.
+        context -- product registration context object
+        """
+        # get help folder for product
+        help = context.getProductHelp()
+        
+        for field_name, field_class in self._fields.items():
+            # don't register help for internal fields
+            if (hasattr(field_class, 'internal_field') and
+                getattr(field_class, 'internal_field')):
+                continue
+            
+            # unregister any help topic already registered
+            if field_name in help.objectIds('Help Topic'):
+                help._delObject(field_name)
+               
+            # register help topic
+            ht = FieldHelpTopic(field_name,
+                                "Formulator Field - %s" % field_name,
+                                field_class)
+        
+            context.registerHelpTopic(field_name, ht)
+
+    def initializeFields(self):
+        """Initialize all field classes in field forms to use actual field
+        objects so we can finally eat our own dogfood.
+        """
+        # for each field, realize fields in form
+        # this is finally possible as all field classes are now
+        # fully defined.
+        for field_class in self._fields.values():
+            field_class.form._realize_fields()
+            field_class.override_form._realize_fields()
+            field_class.tales_form._realize_fields()
+            
+# initialize registry as a singleton
+FieldRegistry = FieldRegistry()
+        
+def initializeFieldForm(field_class):
+    """Initialize the properties (fields and values) on a particular
+    field class. Also add the tales and override methods.
+    """
+    from Form import BasicForm
+    from DummyField import fields
+    
+    form = BasicForm()
+    override_form = BasicForm()
+    tales_form = BasicForm()
+    for field in getPropertyFields(field_class.widget):
+        form.add_field(field, "widget")
+        tales_field = fields.TALESField(field.id,
+                                        title=field.get_value('title'),
+                                        description="",
+                                        default="",
+                                        display_width=40,
+                                        required=0)
+        tales_form.add_field(tales_field, "widget")
+        
+        method_field = fields.MethodField(field.id,
+                                          title=field.get_value("title"),
+                                          description="",
+                                          default="",
+                                          required=0)
+        override_form.add_field(method_field, "widget")
+        
+    for field in getPropertyFields(field_class.validator): 
+        form.add_field(field, "validator")
+        tales_field = fields.TALESField(field.id,
+                                        title=field.get_value('title'),
+                                        description="",
+                                        default="",
+                                        display_with=40,
+                                        required=0)
+        tales_form.add_field(tales_field, "validator")
+        
+        method_field = fields.MethodField(field.id,
+                                          title=field.get_value("title"),
+                                          description="",
+                                          default="",
+                                          required=0)
+        override_form.add_field(method_field, "validator")
+        
+    field_class.form = form         
+    field_class.override_form = override_form
+    field_class.tales_form = tales_form
+    
+def getPropertyFields(obj):
+    """Get property fields from a particular widget/validator.
+    """
+    fields = []
+    for property_name in obj.property_names:
+        fields.append(getattr(obj, property_name))
+    return fields
+
+def setupIcon(klass, icon, repository):
+    """Load icon into Zope image object and put it in Zope's
+    repository for use by the ZMI, for a particular class.
+    klass -- the class of the field we're adding
+    icon  -- the icon
+    """
+    # set up misc_ respository if not existing yet
+    if not hasattr(OFS.misc_.misc_, repository):
+        setattr(OFS.misc_.misc_, 
+                repository, 
+                OFS.misc_.Misc_(repository, {}))
+        
+    # get name of icon in the misc_ directory
+    icon_name = os.path.split(icon)[1]
+        
+    # set up image object from icon file
+    icon_image = ImageFile(icon, globals())
+    icon_image.__roles__ = None
+
+    # put icon image object in misc_/Formulator/
+    getattr(OFS.misc_.misc_, repository)[icon_name] = icon_image
+
+    # set icon attribute in field_class to point to this image obj
+    setattr(klass, 'icon', 'misc_/%s/%s' %
+            (repository, icon_name))     
+
+InitializeClass(FieldRegistry)
+allow_class(FieldRegistry)  
diff --git a/product/ERP5OOo/ScribusUtils.py b/product/ERP5OOo/ScribusUtils.py
new file mode 100755
index 0000000000..f2ef4695c2
--- /dev/null
+++ b/product/ERP5OOo/ScribusUtils.py
@@ -0,0 +1,139 @@
+##############################################################################
+#
+# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
+#               Guy Oswald OBAMA <guy@nexedi.com>
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 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 Products.PythonScripts.Utility import allow_class
+from ZPublisher.HTTPRequest import FileUpload
+from xml.dom.ext.reader import PyExpat
+from xml.dom import Node, minidom
+from AccessControl import ClassSecurityInfo
+from Globals import InitializeClass, get_request
+from zipfile import ZipFile, ZIP_DEFLATED
+from StringIO import StringIO
+from zLOG import LOG
+import imghdr
+import random
+import getopt, sys, os, string
+from urllib import quote
+
+
+
+class ScribusParser:
+  """
+  Parses a Scribus file
+  """
+  
+  # Declarative security
+  security = ClassSecurityInfo()
+  
+    
+  security.declarePublic('getXmlObjectsProperties')
+  def getXmlObjectsProperties(self, xml_string):
+    # Create the PyExpat reader
+    reader = PyExpat.Reader()
+  
+    # Create DOM tree from the xml string
+    dom_tree = reader.fromString(xml_string)
+  
+    text_field_list = {}
+    
+    dom_root = dom_tree.documentElement
+    page_object_list = dom_root.getElementsByTagName("PAGEOBJECT")
+  
+    # Take Xml objects properties
+    for page_object in page_object_list:
+      text_field_properties = {}
+      field_name = None
+      for attribute in page_object.attributes:
+        node_name  = str(attribute.nodeName)
+        node_value = str(attribute.nodeValue)
+        if node_name == 'ANNAME':
+          if node_value != '':
+            field_name = node_value
+        else:
+            text_field_properties[node_name] = node_value
+      if field_name != None:
+        text_field_list[field_name] = text_field_properties
+  
+    return text_field_list   
+
+   
+  security.declarePublic('getPropertiesConversion')
+  def getPropertiesConversion(self, text_field_list):
+  # Get Scribus field properties
+  
+    field_scribus_properties_dict = {}
+  
+    for field_name in text_field_list.keys():
+      text_field_properties = text_field_list[field_name]
+      field_scribus_properties_dict[field_name] = text_field_properties['ANTOOLTIP']
+  
+    widget_properties_list = []
+    index = 1    
+  
+    while index < len(field_scribus_properties_dict):
+      for key, item in field_scribus_properties_dict.items():
+        if string.atoi(item[:3]) == index:
+          property_field_list = item[4:].split('#')
+          widget_properties_buffer = {}
+          for property_field in property_field_list:
+            property_field_split = property_field.split(':')
+            if property_field_split[0] == 'items':
+              property_field_split[1] = property_field_split[1].split('|')
+            widget_properties_buffer[property_field_split[0]] = property_field_split[1]
+          widget_properties_list.append((key, widget_properties_buffer))
+          break
+      index = index + 1
+  
+    for key, item in field_scribus_properties_dict.items():
+      if string.atoi(item[:3]) == 999:
+        property_field_list = item[4:].split('#')
+        widget_properties_buffer = {}
+        for property_field in property_field_list:
+          property_field_split = property_field.split(':')
+          widget_properties_buffer[property_field_split[0]] = property_field_split[1]
+        widget_properties_list.append((key, widget_properties_buffer))
+  
+    return widget_properties_list
+
+        
+  security.declareProtected('Import/Export objects', 'getContentFile')
+  def getContentFile(self, file_descriptor):
+    """ Get file content """
+    return file_descriptor.read()
+  """
+  def getContentFile(self, file_path):
+    # Verify that the file exist
+    if not os.path.isfile(file_path):
+      output("ERROR: " + file_path + " doesn't exist.")
+      return None
+  
+    # Get file content
+    file_path = os.path.abspath(file_path)
+    file_object = open(file_path, 'r')
+  
+    return file_object.read()
+  """
+  
+InitializeClass(ScribusParser)
+allow_class(ScribusParser)  
+
+
+  
\ No newline at end of file
-- 
2.30.9