/[public]/erp5/sandbox/products-CMFActivity-plone-integration/ERP5Form/ScribusUtils.py
ERP5 logo

Contents of /erp5/sandbox/products-CMFActivity-plone-integration/ERP5Form/ScribusUtils.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 29223 - (hide annotations)
Mon Sep 28 13:27:38 2009 UTC (3 years, 8 months ago) by jm
File MIME type: text/x-python
File size: 87582 byte(s)
Rename /branches to /sandbox because it will only be used for new (big) features
1 kevin 4147 ##############################################################################
2     #
3     # Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
4     # Guy Oswald OBAMA <guy@nexedi.com>
5 yo 4537 # thomas <thomas@nexedi.com>
6 mame 14510 # Mame C.Sall <mame@nexedi.com>
7 kevin 4147 #
8     # This program is Free Software; you can redistribute it and/or
9     # modify it under the terms of the GNU General Public License
10     # as published by the Free Software Foundation; either version 2
11     # of the License, or (at your option) any later version.
12     #
13     # This program is distributed in the hope that it will be useful,
14     # but WITHOUT ANY WARRANTY; without even the implied warranty of
15     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     # GNU General Public License for more details.
17     #
18     # You should have received a copy of the GNU General Public License
19     # along with this program; if not, write to the Free Software
20     # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21     #
22     ##############################################################################
23    
24 yo 4537 # This code is under refactoring. This code will change in near future
25     # with a lot of cleanups. This is stored only for a temporary purpose.
26     # Do not rely on the real implementation. It is assumed that the code is
27 thomas 8343 # improved and modified significantly.
28     # UPDATE => the code is almost refactored and supports
29 yo 4537
30 kevin 4147 from Products.PythonScripts.Utility import allow_class
31     from ZPublisher.HTTPRequest import FileUpload
32 mame 14510 from xml.dom.ext.reader import PyExpat
33 kevin 4147 from xml.dom import Node, minidom
34     from AccessControl import ClassSecurityInfo
35     from Globals import InitializeClass, get_request
36     from zipfile import ZipFile, ZIP_DEFLATED
37     from StringIO import StringIO
38     from zLOG import LOG
39     import imghdr
40     import random
41 yo 4537 import getopt, sys, os
42 kevin 4147 from urllib import quote
43    
44 thomas 8343 from Products.ERP5.ERP5Site import ERP5Site
45 mame 14510 from Products.Formulator.TALESField import TALESMethod
46 thomas 8343 # defining global variables
47     # ANFLAG tag
48     # these values can be found in the Scribus document format
49     # (www.scribus.org.uk)
50     def_noScroll = '8388608'
51     def_noSpellCheck = '4194304'
52     def_editable = '262144'
53     def_password = '8192'
54     def_multiLine = '4096'
55     def_noExport = '4'
56     def_required = '2'
57     def_readOnly = '1'
58     # SCRIPT CONFIGURATION
59     # define if the script uses personal properties or create a
60     # PropertySheet and a Document model to save data.
61     # used in 'setPropertySheetAndDocument', 'setObjectPortalType'
62     # and 'setPDFForm'
63     def_usePropertySheet = 0
64 kevin 4147
65 thomas 8343
66     class ManageModule:
67     """
68     Manage the module that will contain the form
69     """
70     security = ClassSecurityInfo()
71    
72     security.declarePublic('setObjectNames')
73     def setObjectNames(self, object_portal_type_id, object_title):
74     """
75     initialize object names view_pdf, view_list, etc. to be able
76     to create correctly all objects in the module.
77     return a dict of names.
78     """
79     temp_portal_type = object_portal_type_id.replace(' ','')
80     object_names = {}
81 mame 14510 real_object_names={}
82 thomas 8343 # declaring object that generate pdf output
83     object_names['view_pdf'] = temp_portal_type + '_view' +\
84     temp_portal_type + 'AsPdf'
85     # declaring form to list the objects of a module
86     object_names['view_list'] = object_title.replace(' ','') +\
87     'Module_view' + temp_portal_type + 'List'
88     # declaring main object form
89     object_names['view_id'] = temp_portal_type + '_view'
90     # declaring object that holds the CSS data
91     object_names['css'] = temp_portal_type + '_css.css'
92     # declaring object name containing the background pictures
93     object_names['page'] = temp_portal_type + '_background_'
94     # return object declaration
95     return object_names
96    
97    
98     security.declarePublic('setSkinFolder')
99     def setSkinFolder(self,
100     portal,
101     portal_skins_folder):
102     """
103     create and manage skin folder according to the skin folder
104     name specified by the user (as portal_skin_folder).
105     returns skin_folder, recovered from portal.portal_skins
106     """
107     portal_skins_folder_name = portal_skins_folder
108     portal_skins = portal.portal_skins
109     if not portal_skins_folder_name in portal.portal_skins.objectIds():
110     # create new folder if does not exist yet
111     portal_skins.manage_addFolder(portal_skins_folder_name)
112     skin_folder = portal.portal_skins[portal_skins_folder_name]
113     for skin_name, selection in portal_skins.getSkinPaths():
114     selection = selection.split (',')
115     if portal_skins_folder_name not in selection:
116     new_selection = [portal_skins_folder_name,]
117 kristian 13118 new_selection.extend(selection)
118 thomas 8343 portal_skins.manage_skinLayers(skinpath = tuple(new_selection),
119 kristian 13125 skinname = skin_name,
120 thomas 8343 add_skin = 1)
121     return skin_folder
122    
123    
124     security.declarePublic('setModuleForm')
125     def setModuleForm(self,
126     object_title,
127     skin_folder,
128     #portal,
129     #portal_skins_folder,
130     form_view_list,
131     module_title,
132     module_id,
133     def_lineNumberInList
134     ):
135     """
136     Manage ERP5 Form to handle and view the Module. then process
137     the list inside this form. This procedure does not need to
138     parse the scribus file as the ModuleForm is always present
139     and generated the same way
140     returns nothing
141     """
142     # the form is already existing and has been created through
143     # setERP5Form. getting form object to update properties
144     form_view_list_object = skin_folder[form_view_list]
145     form_list_id = form_view_list_object.id
146     form_list = form_view_list_object.restrictedTraverse(form_list_id)
147     # defining groups for objects listing
148 mame 14510 form_view_list_object.rename_group('Default','bottom')
149     default_groups = []
150 thomas 8343 # adding groups
151     for group in default_groups:
152     form_view_list_object.add_group(group)
153     # defining module title
154     title_module = ''
155     for word in module_title.split():
156     title_module += str(word.capitalize() + ' ')
157     # add listbox field to list the created objects
158     id = 'listbox'
159     title = title_module
160     field_type = 'ListBox'
161     form_view_list_object.manage_addField(id,title,field_type)
162     # manage ListBox settings
163     values_settings = {}
164     values_settings['pt'] = "form_list"
165     values_settings['action'] = "Base_doSelect"
166     # set the form settings
167     for key, value in values_settings.items():
168     setattr(form_view_list_object, key, value)
169     # manage edit property of ListBox
170     field_attributes = getattr(form_view_list_object,id)
171     field_attributes.values['lines'] = def_lineNumberInList
172     # adding field columns
173     field_attributes.values['columns'] = [('id','ID'),
174     ('title','Title'),
175 mame 14510 ('description','Description'),
176     ('translated_simulation_state','State')]
177 thomas 8343 field_attributes.values['list_action'] = 'list'
178     field_attributes.values['search'] = 1
179     field_attributes.values['select'] = 1
180     field_attributes.values['list_method'] = 'searchFolder'
181     field_attributes.values['selection_name'] = '%s_selection' % module_id
182    
183     security.declarePublic('setObjectForm')
184     def setObjectForm(self,
185     skin_folder,
186     object_names,
187     option_html,
188     global_properties,
189 mame 14510 object_portal_type
190 thomas 8343 ):
191     """
192     create and manage erp5 form to handle object, and update its
193     properties (groups, values, etc.)
194     return list of groups in form (used afterwards when creating
195     fields).
196     """
197     # getting form object
198     form_view_id_object = skin_folder[object_names['view_id']]
199     form_id = form_view_id_object.id
200     form = form_view_id_object.restrictedTraverse(form_id)
201 mame 14510 #get the scaling factor
202 thomas 8343 # managing form groups
203     default_groups = []
204     if option_html !=1:
205     # using default ERP5 positioning convention
206     # based on 'left'/'right'/etc.
207     default_groups = ['left','right','center','bottom','hidden']
208     else:
209     # using special page positioning convention for
210     # pdf-like rendering
211 mame 14510 del default_groups[0:]
212 thomas 8343 for page_iterator in range(global_properties['page']):
213     page_number = 'page_%s' % str(page_iterator)
214 jp 15220
215    
216     default_groups.append(page_number)
217 thomas 8343 # default_groups list completed, need to update the form_groups
218     # renaming form default group with list's first item
219     form_view_id_object.rename_group('Default',
220     default_groups[0]
221     )
222     # adding all other items
223     for group in default_groups[0:]:
224     form_view_id_object.add_group(group)
225     # updating form settings
226     # building dict containing (property, value)
227     values = {}
228     values['title'] = str(object_portal_type)
229     values['row_length'] = 4
230     values['name'] = object_names['view_id']
231     if option_html ==1:
232     # this is the name of the new form, compatible either with html_style
233     # and xhtml_style.
234     values['pt'] = "form_render_PDFeForm"
235     else:
236     values['pt'] = "form_view"
237     values['action'] = "Base_edit"
238     values['update_action'] = ""
239     values['method'] = 'POST'
240     values['enctype'] = 'multipart/form-data'
241     values['encoding'] = "UTF-8"
242     values['stored_encoding'] = 'UTF-8'
243     values['unicode_mode'] = 0
244     # using the dict declared just above to set the attributes
245     for key, value in values.items():
246     setattr(form,key,value)
247 mame 14510 return (default_groups)
248 thomas 8343
249     security.declarePublic('setFieldsInObjectForm')
250     def setFieldsInObjectForm(self,
251     skin_folder,
252     object_names,
253     default_groups,
254     global_properties,
255     option_html
256     ):
257     """
258     create fields in form according to the page_objects
259     recovered from the scribus document file. fields are
260     then moved to their corresponding group, and are given
261     their properties
262     """
263     form_view_id_object = skin_folder[object_names['view_id']]
264     # iterating field a first time to get creation order
265     # based on the 'nb' value
266     field_nb_dict = {}
267     # this dict will handle all the information about the field_names and
268     # their creation order (field_nb).
269    
270     if option_html :
271     # render is PDF-like, need to take care of the page holding the field
272     for field_id in global_properties['object'].keys():
273     field_nb = int(global_properties['object'][field_id]['nb'])
274     #field_order = global_properties['object'][field_id]['order']
275     field_order = \
276     int(global_properties['object'][field_id]['order'].split('page_')[1])
277     # creating sub dict if does not exist yet
278     if field_order not in field_nb_dict:
279     field_nb_dict[field_order] = {}
280     field_nb_dict[field_order][field_nb] = field_id
281     # now field_nb_dict holds all the information about the
282     # fields and their creation order: just need to create
283     # them.
284    
285     for field_order_id in field_nb_dict.keys():
286     # iterating pages
287     for field_nb in range(len(field_nb_dict[field_order_id].keys())):
288     field_id = field_nb_dict[field_order_id][field_nb + 1]
289     # recovering field information
290     field_values = global_properties['object'][field_id]
291     field_type = field_values['erp_type']
292     field_title = field_values['title']
293     field_order = field_values['order']
294 mame 14510 #field_tales = field_values['tales']
295 thomas 8343 # creating new field in form
296     form_view_id_object.manage_addField(field_id,
297     field_title,
298     field_type)
299     # move fields to destination group
300     form_view_id_object.move_field_group(field_id,
301     default_groups[0],
302     field_order)
303     # recover field
304     access_field = getattr(form_view_id_object,field_id)
305 mame 14510 if field_type == 'CheckBoxField':
306     test_name= field_id[3:]
307     tales = {field_id : {'default' : 'here'+ '/'+ test_name}}
308    
309     forms = [object_names['view_id']]
310     form = form_view_id_object.restrictedTraverse(forms[0])
311     for k, v in tales.items() :
312     if hasattr(form, k) :
313     form[k].manage_tales_xmlrpc(v)
314 thomas 8343 #if field_type == 'CheckBoxField':
315     # print " dir(%s) > %s" % (field_id,dir(access_field))
316     # print "---manage_tales > %s \n\n" % dir(access_field.manage_tales)
317     # print "---manage_talesForm > %s \n\n" % \
318     # dir(access_field.manage_talesForm)
319     # print "---manage_talesForm__roles__ > %s\n\n " % \
320     # dir(access_field.manage_talesForm__roles__)
321     # print "---manage_tales__roles__ > %s" % \
322     # dir(access_field.manage_tales__roles__)
323     # print "--- 5 > %s" % dir(access_field.manage_tales_xmlrpc)
324     # print "--- 6 > %s" % \
325     # dir(access_field.manage_tales_xmlrpc__roles__)
326    
327     else:
328     # rendering as basic ERP5 form : processing all
329     # fields without taking care of their 'order'.
330     for field_id in global_properties['object'].keys():
331     field_nb = int(global_properties['object'][field_id]['nb'])
332     if field_nb in field_nb_dict.keys():
333     # field_nb is already used by another field. this can appen
334     # when there are several pages in the document. In such case
335     # the script find automatically the closest available value.
336     print " can not add %s to dict : %s already used by %s " % \
337     (field_id,field_nb,field_nb_dict[field_nb])
338     field_nb = field_nb +1
339     while field_nb in field_nb_dict.keys():
340     # trying next value
341     field_nb = field_nb + 1
342     print " add %s to %s" % (field_id,field_nb)
343     # value is available, no problem to link field_id to this field_nb
344     field_nb_dict[field_nb] = field_id
345    
346     for field_nb in range(len(field_nb_dict.keys())):
347     field_nb = field_nb +1
348     field_id = field_nb_dict[field_nb]
349     # recovering field information
350     field_values = global_properties['object'][field_id]
351     field_type = field_values['erp_type']
352     field_title = field_values['title']
353     field_order = field_values['order']
354     # create field
355     form_view_id_object.manage_addField(field_id,
356     field_title,
357     field_type)
358     # move field to relative group
359     form_view_id_object.move_field_group(field_id,
360     default_groups[0],
361     field_order)
362    
363     # field creation is complete
364     form_id = form_view_id_object.id
365     form = form_view_id_object.restrictedTraverse(form_id)
366     # updating field properties
367     # iterating fields
368     for field_id in global_properties['object'].keys():
369     field_attributes = getattr(form,field_id)
370     #print " %s => %s" % (field_id,field_attributes.values.keys())
371     for attr_id, attr_val in \
372     global_properties['object'][field_id]['attributes'].items():
373     field_attributes.values[attr_id] = attr_val
374    
375    
376    
377     security.declarePublic('setModulePortalType')
378     def setModulePortalType(self,portal_types,
379     object_portal_type_id,
380     module_portal_type,
381     object_names):
382     """
383     set portal_type for the module containing objects.
384     returns nothing
385     """
386     portal_types.manage_addTypeInformation('ERP5 Type Information'
387     ,typeinfo_name = 'ERP5Type: ERP5 Folder'
388     ,id = module_portal_type)
389     # getting portal_type access to be able to modify attributes
390     module_portal_type_value = portal_types[module_portal_type]
391     # set alowed content type
392     module_portal_type_value.allowed_content_types = (object_portal_type_id,)
393     module_portal_type_value.filter_content_types = 1
394     # making a list of all the portal_type actions to be able to delete them
395     action_list = module_portal_type_value.listActions()
396     # cleaning all portal_types actions
397     module_portal_type_value.deleteActions(
398     selections = range(0, len(action_list)))
399     # adding usefull actions (in our case the view action)
400     module_portal_type_value.addAction( "view"
401     , "View"
402     , "string:${object_url}/%s"%object_names['view_list']
403     , ""
404     , "View"
405     , "object_view"
406     )
407    
408    
409    
410     security.declarePublic('setObjectPortalType')
411     def setObjectPortalType(self,
412     portal_types,
413     object_portal_type_id,
414     object_portal_type,
415     object_names):
416     name = ''
417     if def_usePropertySheet:
418     # generating 'typeinfo_name' property for the new portal type.
419     # if class exists, then using it, otherwize using default ERP5
420     # Document type.
421     name = 'ERP5Type: ERP5 ' + object_portal_type # use with PropertySheet
422     else:
423     name = 'ERP5Type: ERP5 Document' # use with local properties
424     portal_types.manage_addTypeInformation('ERP5 Type Information',
425     typeinfo_name = name,
426     id = object_portal_type_id)
427     object_portal_type_value = portal_types[object_portal_type_id]
428    
429     # cleaning all default actions
430     action_list = object_portal_type_value.listActions()
431     object_portal_type_value.deleteActions(
432     selections = range(0, len(action_list)))
433     # adding usefull actions (in our case the view action)
434     object_portal_type_value.addAction( "view",
435     "View",
436     "string:${object_url}/%s" % object_names['view_id'],
437     "",
438     "View",
439     "object_view"
440     )
441     object_portal_type_value.addAction( "print"
442     , "Print"
443 jerome 9296 , "string:${object_url}/%s" % object_names['view_pdf']
444 thomas 8343 , ""
445     , "View"
446     , "object_print"
447 jerome 9296 , priority=2.0
448 thomas 8343 )
449     object_portal_type_value.addAction( "history"
450     , "History"
451     , "string:${object_url}/Base_viewHistory"
452     , ""
453     , "View"
454     , "object_view"
455 jerome 9296 , priority=99.0
456 thomas 8343 )
457     object_portal_type_value.addAction( "metadata"
458     , "Metadata"
459     , "string:${object_url}/Base_viewMetadata"
460     , ""
461     , "Manage properties"
462     , "object_view"
463 jerome 9296 , priority=100.0
464 thomas 8343 )
465    
466    
467     security.declarePublic('registerModule')
468     def registerModule(self,
469     portal,
470     module_id,
471     module_portal_type,
472     object_portal_type):
473     """
474     register Module inside ERP5 instance
475     """
476     title_module = ''
477     for word in object_portal_type.split():
478     title_module += str(word.capitalize() + ' ')
479     portal.newContent( id = str(module_id),
480     portal_type = str(module_portal_type),
481 jerome 9296 title = title_module)
482 thomas 8343
483 mame 14510
484 thomas 8343 class ManageFiles:
485     """
486     Manages PDF file, by importing the PDF document and then getting
487     the TALES expressions
488     """
489     security = ClassSecurityInfo()
490    
491    
492    
493     security.declarePublic('setERP5Form')
494     def setERP5Form(self,
495     factory,
496     form_name,
497     form_title):
498     """
499     create an ERP5 Form by using the factory
500     """
501     factory.addERP5Form(form_name,
502 jerome 9296 form_title)
503 thomas 8343
504    
505    
506     security.declarePublic('setCSSFile')
507     def setCSSFile(self,
508     factory,
509     form_css_id,
510     form_css_content,
511     ):
512     """
513     create an ERP5 DTML Document in the folder related
514     to factory and save the content of the CSS string
515     """
516     factory.addDTMLDocument(form_css_id,"css",form_css_content)
517    
518    
519     security.declarePublic('importFile')
520     def setPDFForm(self,
521     factory,
522     skin_folder,
523     object_names,
524     object_title,
525     pdf_file
526     ):
527     """
528     imports PDF file as a PDFForm in ERP5 and updates its TALES
529     expressions
530     """
531     pdf_file.seek(0)
532     factory.addPDFForm(object_names['view_pdf'],object_title,pdf_file)
533     # iterating objects in skin_folder
534     for c in skin_folder.objectValues():
535     if c.getId() == object_names['view_pdf']:
536     # current object is PDF Form
537     cell_name_list = c.getCellNames()
538     for cell_name in cell_name_list:
539     if cell_name[0:3] == 'my_':
540     cell_process_name_list = []
541     for word in cell_name[3:].split('_'):
542     word = word.capitalize()
543     cell_process_name_list.append(word)
544     if def_usePropertySheet == 1:
545     # generating PropertySheet and Document, no need to use them to
546     # get field data
547     if cell_process_name_list[-1] == 'List':
548     TALES = "python: " + ", ".join(
549     "here.get" + "".join(cell_process_name_list) + "()" )
550 mame 14510
551 thomas 8343 else:
552     TALES = "python: here.get" + "".join(
553     cell_process_name_list) + "()"
554 mame 14510
555 thomas 8343 else:
556     # PropertySheet and Document
557     if cell_process_name_list[-1] == 'List':
558     TALES = "python: " + ", ".join(
559     "here.getProperty('" + cell_name[3:] + "')")
560 mame 14510
561 thomas 8343 else:
562     TALES = "python: here.getProperty('" + cell_name[3:] +"')"
563     print " %s > %s " % (cell_name,TALES)
564     c.setCellTALES(cell_name,TALES)
565    
566 mame 14510 def getPDFFile(self, file_descriptor):
567     """ Get file content """
568     return file_descriptor.open()
569 thomas 8343
570     security.declarePublic('setBackgroundPictures')
571     def setBackgroundPictures(self,
572     pdf_file,
573     object_names,
574 mame 14510 skin_folder,
575 jp 15220 desired_height,
576     desired_width,
577     resolution
578 thomas 8343 ):
579     """
580     extract background pictures from pdf file and convert them
581     in the right format (JPEG) and save them in the corresponding
582     folder (skin_folder).
583     to work, this procedure needs to have pdftoppm (from Xpdf)
584     and convert (from ImageMagick) installed on the server
585     otherwise nothing is created.
586     Temp files are created in the '/tmp/' folder, and are deleted
587     once the job is done.
588     At the end, get the properties (size_x, size_y) of the first
589     image (i.e page_0) and returns them.
590     """
591     import commands
592 mame 14510 import tempfile
593     from tempfile import NamedTemporaryFile
594 thomas 8343 # opening new file on HDD to save PDF content
595 mame 14510 #temp_test= NamedTemporaryFile(mode= "w+b")
596     #tempFile= NamedTemporaryFile().name
597     ScribusUtilsTempPDF= NamedTemporaryFile(mode= "w+b")
598     ScribusUtilstempsPDFName= NamedTemporaryFile().name
599 thomas 8343 # going to the begining of the input file
600 mame 14510
601     # XXX - this is really bad because the appropriate
602     # way to run zope is to create a local instance
603     # it should be removed XXX - some people
604     # do this just to make sure "it works"
605     # but it is not even multiplatform
606     os.putenv('TMPDIR', '/tmp')
607     # saving content
608     temp_pdf = open(ScribusUtilstempsPDFName,'w')
609    
610     # going to the begining of the input file
611 thomas 8343 pdf_file.seek(0)
612     # saving content
613 jp 15220 # saving content
614 thomas 8343 temp_pdf.write(pdf_file.read())
615     temp_pdf.close()
616 mame 14510
617 thomas 8343 # launching first soft to convert from PDF to PPM
618 mame 14510 ScribusUtilstempsPPM = NamedTemporaryFile(mode="w+b")
619     ScribusUtilstempsPPMName = NamedTemporaryFile().name
620     result = commands.getstatusoutput('pdftoppm -r %s %s %s' % (resolution, ScribusUtilstempsPDFName, ScribusUtilstempsPPMName))
621 thomas 8343 # launching second soft to convert from PPM to JPEG
622 mame 14510 ScribusUtilstempsJPG = NamedTemporaryFile(mode="w+b")
623     ScribusUtilstempsJPGName = NamedTemporaryFile().name
624 jp 15220
625 mame 14510 original_result= commands.getstatusoutput('identify %s' % (ScribusUtilstempsPDFName))
626     result = commands.getstatusoutput('convert -density %s -resize %sx%s %s %s' % (resolution,desired_width,desired_height,ScribusUtilstempsPPMName + '*', 'jpg:' + ScribusUtilstempsJPGName))
627 jp 15220
628 mame 14510 number = ScribusUtilstempsJPGName.find('tmp')
629     directory_tmp= ScribusUtilstempsJPGName[:(number+4)]
630    
631 thomas 8343 # getting list of JPG output files
632 mame 14510 result = commands.getstatusoutput('ls %s | grep %s' % (directory_tmp, ScribusUtilstempsJPGName.split('/')[-1]))
633     # deleting all temporary files
634     # getting the original size of the file
635     real_size_x= 0
636     real_size_y= 0
637 thomas 8343 image_number = 0
638     if result[1] != '':
639     # result[1] contains the output string from the command,
640     # in our case the result of the ls.
641     # splitting this string to get the list of objects
642     for image in result[1].split('\n'):
643     temp_jpg = open('/tmp/%s' % image, 'r')
644     form_page_id = object_names['page'] + str(image_number)
645     addImage = skin_folder.manage_addProduct['OFSP'].manage_addImage
646     addImage(form_page_id,temp_jpg,"background image")
647     image_number += 1
648     # deleting all temporary files
649 mame 14510 result = commands.getstatusoutput('rm -f /tmp/tmp*') # JPS-XXX Extremely dangerous
650 thomas 8343 # open page_0's final background picture to recover size_x and size_y
651     final_image = getattr(skin_folder, object_names['page'] + '0')
652 mame 14510 size_x = desired_height
653     size_y = desired_width
654 jp 15220
655 mame 14510 return (size_x, size_y,real_size_x,real_size_y)
656 thomas 8343
657 mame 14510 security.declarePublic('getPageattributes')
658     def getPageattributes (self,
659 jp 15220 global_properties,
660     pdf_file
661     ):
662 mame 14510 import commands
663     from tempfile import NamedTemporaryFile
664     # opening new file on HDD to save PDF content
665     ScribusUtilsOriginalTempPDF= NamedTemporaryFile(mode= "w+b")
666     ScribusUtilsOriginaltempsPDFName= NamedTemporaryFile().name
667 jp 15220
668 mame 14510 # going to the begining of the input file
669 jp 15220
670 mame 14510 # saving content
671     temp_pdf = open(ScribusUtilsOriginaltempsPDFName,'w')
672     # going to the begining of the input file
673     pdf_file.seek(0)
674     # saving content
675     temp_pdf.write(pdf_file.read())
676     temp_pdf.close()
677     width_groups = []
678     height_groups = []
679     # launching first soft to convert from PDF to PPM
680     ScribusUtilsOriginaltempsPPM = NamedTemporaryFile(mode="w+b")
681     ScribusUtilsOriginaltempsPPMName = NamedTemporaryFile().name
682     original_result = commands.getstatusoutput('pdftoppm -r %s %s %s' % (72, ScribusUtilsOriginaltempsPDFName, ScribusUtilsOriginaltempsPPMName))
683     original_result= commands.getstatusoutput('identify %s' % (ScribusUtilsOriginaltempsPPMName + '*'))
684 jp 15220
685 mame 14510 pg_nbr = len(original_result[1].split('\n'))
686     real_size_x = {}
687     real_size_y = {}
688     for i in range(0,pg_nbr):
689     real_size_x[i]= \
690     float(original_result[1].split('\n')[i].split(' ')[2].split('x')[1])
691     real_size_y[i]= \
692     float(original_result[1].split('\n')[i].split(' ')[2].split('x')[0])
693     for page_iterator in range(global_properties['page']):
694     actual_page_height = real_size_x[page_iterator]
695     actual_page_width = real_size_y[page_iterator]
696     width_groups.append(actual_page_width)
697     height_groups.append(actual_page_height)
698     return (width_groups,height_groups)
699 jp 15220
700 thomas 8343 security.declarePublic('setPropertySheetAndDocument')
701     def setPropertySheetAndDocument(self,
702     global_properties,
703     object_portal_type,
704     generator,
705     skin_folder,
706     object_names
707     ):
708     """
709     recover personal properties from dict global_properties
710     and save them in a propertysheet
711     then create the Document related to the object.
712     PropertySheetRegistry and DocumentRegistry have to be
713     reinitialized after this procedure has been called.
714     """
715     if def_usePropertySheet:
716     print " object_names = %s" % object_names['view_id']
717     #property_form = getattr(skin_folder,object_names['view_id'])
718     # defining file name for Property Sheet
719     name_file =''
720     for word in object_portal_type.split():
721     name_file += word.capitalize()
722     # building list containing properties
723     personal_properties_list = []
724     for field_id in global_properties['object'].keys():
725     if field_id.startswith('my_') and not (
726     field_id.startswith('my_source') or
727     field_id.startswith('my_destination') or
728     field_id in ('my_start_date','my_stop_date')):
729     field_type = global_properties['object'][field_id]['data_type']
730     field_default = global_properties['object'][field_id]['default']
731     personal_properties = { 'id' : field_id[3:],
732     'description' : '',
733     'type' : field_type,
734     'mode' : 'w'}
735     ## FOLLOWING QUOTED LINES CAN BE DELETED IF NOT USES
736     ## just left in case : can be usefull to create a smart
737     ## script that would be able to automatically create the
738     ## local properties and associate them the good type (int,
739     ## string, float, date, etc.)
740     #print " (field_id,field_default_value,field_type) = \
741     # (%s,%s,%s) " % (field_id[3:], field_default, field_type)
742     #property_form.manage_addProperty(field_id[3:],
743     # field_default,
744     # field_type)
745     personal_properties_list.append(personal_properties)
746     # the following lines create the PropertySheet and the Document for the
747     # new object. Must be uncoted when such files are needed, in such case
748     # you must also specify Document type to comply with class declared in
749     # the Document. For that see 'setObjectPortalType' method
750     ## generate PropertySheet
751     generator.generateLocalPropertySheet(name_file,personal_properties_list)
752     ## generate Document
753     generator.generateLocalDocument(name_file,object_portal_type)
754    
755    
756     class ManageCSS:
757     """
758     Manages all CSS information to generate the css file used in the
759     PDF-like rendering
760     """
761     security = ClassSecurityInfo()
762    
763     security.declarePublic('setInit')
764     def setInit(self):
765     """
766     initialize various containers (dicts) used to store attributes
767     in a main dict.
768     returns global dict containing all the sub-dicts
769     """
770     # declaring dicts used to generate CSS file
771     # css_dict_head contains all the 'global' class, reffering to PAGE
772     properties_css_dict_head = {}
773     # css_dict_standard contains all the fields classes, when no error occurs
774     properties_css_dict_standard = {}
775     # css_dict_error contains the same thing, but in case error occurs.
776     # there background is different so that users can see where the problem
777     # is on the graphic view
778     properties_css_dict_error = {}
779     # css_dict_err_d contains coordinates and color to display text-error
780     properties_css_dict_err_d = {}
781     # declaring main container for all sub_dicts
782     properties_css_dict = {}
783     properties_css_dict['head'] = properties_css_dict_head
784     properties_css_dict['standard'] = properties_css_dict_standard
785     properties_css_dict['error'] = properties_css_dict_error
786     properties_css_dict['err_d'] = properties_css_dict_err_d
787     # return dict
788     return properties_css_dict
789    
790     security.declarePublic('setPageProperties')
791     def setPageProperties(self
792 jp 15220 ,properties_css_dict
793     ,page_iterator
794 thomas 8343 ,page_id
795 jp 15220 ,page_height
796     ,page_width,
797     ,original_page_width
798     ,original_page_height
799     ,width_groups,height_groups):
800 thomas 8343 """
801     recover all CSS data relative to the current page and save these
802     information in the output dict
803     """
804     # Processing current page for CSS data
805     # getting properties
806     properties_css_page = {}
807 mame 14510 properties_page = {}
808 thomas 8343 properties_css_page['position'] = 'relative'
809     # creating image class for background
810     properties_css_background = {}
811     # making background id
812     background_id = page_id + '_background'
813     #getting properties
814     properties_css_background['position'] = 'absolute'
815     #creating corresponding page group to form
816     if page_iterator == 0:
817     # margin-top = 0 (first page)
818     properties_css_page['margin-top'] = "0px"
819 mame 14510 properties_css_background['height'] = \
820     str(page_height) + 'px'
821     properties_css_background['width']= \
822     str (page_width) + 'px'
823     properties_page['actual_width'] = width_groups[page_iterator]
824     properties_page['actual_height'] = height_groups[page_iterator]
825     actual_width = width_groups[page_iterator]
826     actual_height = height_groups[page_iterator]
827     #properties_css_background['margin-top'] = \
828     # str((y_pos -10))+ 'px'
829     #properties_css_background['margin-left']= \
830     # str((x_pos- 5))+ 'px'
831 thomas 8343 else:
832     # margin-top = page height
833 mame 14510 properties_css_page['margin-top'] = "%spx" %(page_height + 20)
834     properties_page['actual_width'] = width_groups[page_iterator]
835     properties_page['actual_height'] = height_groups[page_iterator]
836     actual_width = width_groups[page_iterator-1]
837     actual_height = height_groups[page_iterator -1]
838     properties_css_background['height'] = \
839     str(page_height) + 'px'
840     properties_css_background['width']= \
841     str (page_width) + 'px'
842 thomas 8343 # adding properties dict to global dicts
843     properties_css_dict['head'][page_id] = properties_css_page
844     properties_css_dict['head'][background_id] = properties_css_background
845     # return updated dict
846 mame 14510 return (properties_css_dict,properties_page,actual_width,actual_height)
847 thomas 8343
848    
849    
850    
851    
852     security.declarePublic('setFieldProperties')
853     def setFieldProperties(self
854     ,properties_css_dict
855     ,field
856     ,page_width
857 jp 15220 ,page_height
858     ,page_iterator
859 thomas 8343 ,page_gap
860 mame 14510 ,keep_page,
861 jp 15220 ,original_page_width
862     ,original_page_height
863     ,properties_page,actual_width,actual_height):
864 thomas 8343 """
865     recover all CSS data relative to the current page_object (field)
866     and save these informations in the output dict
867     """
868     (field_name, properties_field) = field
869     print " => %s : %s" % (field_name,properties_field['rendering'])
870 jp 15220
871 thomas 8343 # updating field properties if necessary
872     if keep_page == 1:
873     # document format is 1.3.* and define object position from the top-left
874     # corner of the first page, whereas the field position is expected to
875     # be found from the current's page top left corner.
876     # that's why Y position must be updated
877 jp 15220
878 mame 14510 scaling_factor1= (page_width)/(properties_page['actual_width'])
879     scaling_factor2= (page_height)/(properties_page['actual_height'])
880 jp 15220
881 thomas 8343 properties_field['position_y'] = \
882     str(float(properties_field['position_y']) - \
883 mame 14510 (actual_height + page_gap)* page_iterator)
884    
885 thomas 8343 # Processing object for CSS data
886     # declaring dict containing all css data
887     # _stand for general display
888     field_dict = {}
889     properties_css_object_stand = {}
890     # _error when an error occurs
891     properties_css_object_error = {}
892     # _err_d to diplay the text error
893     properties_css_object_err_d = {}
894     #defining global properties
895     properties_css_object_stand['position'] = 'absolute'
896     properties_css_object_error['position'] = 'absolute'
897     properties_css_object_err_d['position'] = 'absolute'
898     properties_css_object_stand['padding'] = '0px'
899     properties_css_object_error['padding'] = '0px'
900     properties_css_object_err_d['padding'] = '0px'
901     # getting field height
902     properties_css_object_stand['height'] = \
903 mame 14510 str(scaling_factor2 *float(properties_field['size_y'])) + 'px'
904 thomas 8343 properties_css_object_error['height'] = \
905 mame 14510 str(scaling_factor2 *float(properties_field['size_y'])) + 'px'
906 thomas 8343 # defining font-size from height - 2 (this value seems to have a good
907     # rendering on Mozilla and Konqueror)
908     # do not match for TextArea (as it is a multiline object)
909     if properties_field['type'] != 'TextAreaField':
910 jp 15220 if float(properties_field['size_y']) > 8.0:
911 mame 14510 properties_css_object_stand['font-size'] = \
912     str((scaling_factor2 *float(properties_field['size_y']))-5.5 ) + 'px'
913     properties_css_object_error['font-size'] = \
914     str((scaling_factor2 *float(properties_field['size_y']))-5.5) + 'px'
915     else:
916 jp 15220 properties_css_object_stand['font-size'] = \
917 mame 14510 str((scaling_factor2 *float(properties_field['size_y']))-3.5 ) + 'px'
918     properties_css_object_error['font-size'] = \
919 jp 15220 str((scaling_factor2 *float(properties_field['size_y']))-3.5) + 'px'
920 mame 14510 else:
921 thomas 8343 properties_css_object_stand['font-size'] = \
922 mame 14510 str(12) + 'px'
923 thomas 8343 properties_css_object_error['font-size'] = \
924 mame 14510 str(12) + 'px'
925 thomas 8343 properties_css_object_err_d['margin-left'] = str(page_width + 20 ) + 'px'
926     properties_css_object_stand['margin-top'] = \
927 mame 14510 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
928 thomas 8343 properties_css_object_error['margin-top'] = \
929 mame 14510 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
930 thomas 8343 properties_css_object_err_d['margin-top'] = \
931 mame 14510 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
932 thomas 8343 # adding special text_color for text error
933     properties_css_object_err_d['color'] = 'rgb(255,0,0)'
934     # then getting additional properties
935     if properties_field['required'] ==1:
936     # field is required: using special color
937     # color is specified as light-blue when standard
938     # color = 'green' when error
939     properties_css_object_stand['background'] = 'rgb(192,192,255)'
940     properties_css_object_error['background'] = 'rgb(128,128,255)'
941 mame 14510 elif properties_field['type'] != 'TextAreaField':
942     properties_css_object_stand['background'] = '#F5F5DC'
943 jp 15220 properties_css_object_error['background'] = 'rgb(255,64,64)' # Previously #B9D9D4 - should become a parameter
944 thomas 8343 else:
945 jp 15220 properties_css_object_stand['background'] = '#F5F5DC' # Previously #B9D9D4 - should become a parameter
946 thomas 8343 properties_css_object_error['background'] = 'rgb(255,64,64)'
947    
948     # add completed properties (in our case only the class rendering the text
949     # beside an error) to the return dict
950     properties_css_dict['err_d'][field_name] = properties_css_object_err_d
951     # the following variable take the number of field to render for this object
952     field_nb = 1
953    
954     # now processing special rendering
955     if properties_field['rendering']=='single':
956     # single rendering (like StringField, TextArea, etc.).
957     # Do not need any special treatment
958     properties_css_object_stand['width'] = \
959 mame 14510 str(scaling_factor1 *float(properties_field['size_x'])) + 'px'
960 thomas 8343 properties_css_object_error['width'] = \
961 mame 14510 str(scaling_factor1 *float(properties_field['size_x'])) + 'px'
962 thomas 8343 properties_css_object_stand['margin-left'] = \
963 mame 14510 str((scaling_factor1 *float(properties_field['position_x']))) + 'px'
964 thomas 8343 properties_css_object_error['margin-left'] = \
965 mame 14510 str((scaling_factor1 *float(properties_field['position_x']))) + 'px'
966 thomas 8343 # in case of checkboxfield, '_class_2' is used because field is rendered
967     # as two fields, the first one hidden. (supports xhtml_style)
968     # UPDATE : modified because need to keep compatibility with html_style
969     #if properties_field['type'] == 'CheckBoxField':
970     # field_id = field_name + '_class_2'
971     #else:
972     field_id = field_name + '_class'
973     # adding all these properties to the global dicts
974     properties_css_dict['standard'][field_id] = properties_css_object_stand
975     properties_css_dict['error'][field_id] = properties_css_object_error
976     else:
977     sub_field_dict = {}
978     field_dict = {}
979     if properties_field['type'] == 'RelationStringField':
980     # rendering a relationStringField, based on two input areas
981     # processing rendering of the two input fields. for that
982     # each has to be evaluated and the values will be saved in
983     # a dict
984    
985     # uptading number of fields to render
986     field_nb = 2
987    
988     #field_1 = field_name + '_class_1'
989     # processing main StringField
990     field_dict[1] = {}
991     field_dict[1]['width'] = \
992 mame 14510 str(scaling_factor1*(float(properties_field['size_x']) / 2)) + 'px'
993 thomas 8343 field_dict[1]['margin-left'] = \
994 mame 14510 str(scaling_factor1*float(properties_field['position_x'])) + 'px'
995 thomas 8343
996     # processing secondary input picture
997     field_dict[2] = {}
998 mame 14510 field_dict[2]['width'] = str(scaling_factor1*(float(properties_field['size_x']) /2)) + 'px'
999 thomas 8343 field_dict[2]['margin-left'] = \
1000 mame 14510 str(scaling_factor1*(float(properties_field['size_x']) /2 +\
1001     float(properties_field['position_x']))) + 'px'
1002 thomas 8343 elif properties_field['type'] == 'DateTimeField':
1003     # rendering DateTimeField, composed at least of three input
1004     # areas, and their order can be changed
1005     print " Type DateTimeField"
1006    
1007     # getting the number of fields to render and their size unit
1008     if properties_field['date_only'] == '0':
1009     print " Option : Not Date Only"
1010     field_nb = 5
1011     # defining counting unit for fields
1012     # total = 6.1 units:
1013     # 2 > year
1014     # 1 > month
1015     # 1 > day
1016     # 0.1 > space between date and time
1017     # 1 > hour
1018     # 1 > minutes
1019     width_part = int(float(properties_field['size_x']) / 6.1)
1020     else:
1021     print " Option : Date Only"
1022     field_nb = 3
1023     # same as before but without hours and minutes
1024 mame 14510 width_part = int((float(properties_field['size_x']) / 4))
1025 thomas 8343
1026    
1027     print " input_order=%s" % properties_field['input_order']
1028     # defining global field rendering (for Date), ignoring for the moment
1029     # the whole part about the time
1030     if properties_field['input_order'] in \
1031 mame 14510 ['day/month/year','dmy','month/day/year','mdy']:
1032 thomas 8343 # specified input order. must be dd/mm/yyyy or mm/dd/yyyy (year is
1033     # the last field).
1034     # processing first field
1035     field_dict[1] = {}
1036 mame 14510 field_dict[1]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1037 thomas 8343 field_dict[1]['margin-left'] = \
1038 mame 14510 str(scaling_factor1 *float(properties_field['position_x'])) + 'px'
1039 thomas 8343
1040     # processing second field
1041     field_dict[2] = {}
1042 mame 14510 field_dict[2]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1043 thomas 8343 field_dict[2]['margin-left'] = \
1044 mame 14510 str(scaling_factor1 *(float(properties_field['position_x']) + width_part)) + 'px'
1045 thomas 8343
1046     # processing last field
1047     field_dict[3] = {}
1048 mame 14510 field_dict[3]['width'] = str(scaling_factor1*float(width_part*2)) + 'px'
1049 thomas 8343 field_dict[3]['margin-left'] = \
1050 mame 14510 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*2)) + 'px'
1051 thomas 8343 else:
1052     # all other cases, including default one (year/month/day)
1053     width_part = int(int(properties_field['size_x']) / 4)
1054    
1055     # processing year field
1056     field_dict[1] = {}
1057 mame 14510 field_dict[1]['width'] = str(scaling_factor1*float(width_part *2)) + 'px'
1058 thomas 8343 field_dict[1]['margin-left'] = \
1059 mame 14510 str(scaling_factor1 *float(properties_field['position_x'])) + 'px'
1060 thomas 8343
1061     # processing second field (two digits only)
1062     field_dict[2] = {}
1063 mame 14510 field_dict[2]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1064 thomas 8343 field_dict[2]['margin-left'] = \
1065 mame 14510 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*2)) + 'px'
1066 thomas 8343
1067     # processing day field
1068     field_dict[3] = {}
1069 mame 14510 field_dict[3]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1070 thomas 8343 field_dict[3]['margin-left'] = \
1071 mame 14510 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*3)) + 'px'
1072 thomas 8343
1073    
1074     # rendering time if necessary
1075     if properties_field['date_only'] == '0':
1076     # date is specified
1077     print " position_x=%s" % properties_field['position_x']
1078     print " size_x=%s" % properties_field['size_x']
1079     field_dict[4] = {}
1080     field_dict[4]['width'] = str(width_part) + 'px'
1081     field_dict[4]['margin-left'] = \
1082     str(int(properties_field['position_x']) +\
1083     int(properties_field['size_x']) - width_part*2) + 'px'
1084    
1085     field_dict[5] = {}
1086     field_dict[5]['width'] = str(width_part) + 'px'
1087     field_dict[5]['margin-left'] = \
1088     str(int(properties_field['position_x']) +\
1089     int(properties_field['size_x']) - width_part) + 'px'
1090    
1091     # number of fields to generate
1092     print "\n field_number = %s" % field_nb
1093    
1094     field_nb_range = field_nb + 1
1095     field_range = range(field_nb_range)
1096     field_range = field_range[1:]
1097     for iterator in field_range:
1098     # iterator take the field_id according to the field_nb
1099     # ie (0..field_nb)
1100     #iterator = it + 1
1101     print " sub_field_id=%s" % iterator
1102     class_name = field_name + '_class_' + str(iterator)
1103     print " class_name=%s" % class_name
1104    
1105     # managing standard class properties
1106     properties_css_dict['standard'][class_name] = {}
1107     for prop_id in properties_css_object_stand.keys():
1108     # saving global class properties into final dict
1109     properties_css_dict['standard'][class_name][prop_id] = properties_css_object_stand[prop_id]
1110     for prop_id in field_dict[iterator].keys():
1111     # then adding special field properties (usually width and position_x)
1112     properties_css_dict['standard'][class_name][prop_id] = field_dict[iterator][prop_id]
1113    
1114     # managing class error properties
1115     properties_css_dict['error'][class_name] = {}
1116     for prop_id in properties_css_object_error.keys():
1117     properties_css_dict['error'][class_name][prop_id] = properties_css_object_error[prop_id]
1118     for prop_id in field_dict[iterator].keys():
1119     properties_css_dict['error'][class_name][prop_id] = field_dict[iterator][prop_id]
1120    
1121     # final printing for testing
1122     print "\n\n final printing"
1123     for iterator in field_range:
1124     class_name = field_name + '_class_' + str(iterator)
1125     print " class=%s" % class_name
1126     for prop_id in properties_css_dict['standard'][class_name].keys():
1127     print " prop:%s=%s" % (prop_id,properties_css_dict['standard'][class_name][prop_id])
1128 jp 15220
1129    
1130 thomas 8343 return properties_css_dict
1131    
1132     security.declarePublic('setFinalProperties')
1133     def setFinalProperties(self
1134     ,properties_css_dict
1135     ,page_height):
1136     """
1137     adding 'page_end' class to add a div at the end of the last page
1138     in order to display the full last page under Konqueror
1139     Otherwize last page is cut and the user is not able to see the
1140     bottom of the document
1141     """
1142     properties_css_page = {}
1143     properties_css_page['position'] = 'relative'
1144     properties_css_page['margin-top'] = "%spx" % str( page_height)
1145     properties_css_dict['head']['page_end'] = properties_css_page
1146     return properties_css_dict
1147 jp 15220
1148 thomas 8343 security.declarePublic('generateOutputContent')
1149     def generateOutputContent(self
1150     ,properties_css_dict
1151     ):
1152     """
1153     return a string containing the whole content of the CSS output
1154     from properties_css_dict
1155     """
1156     print " createmodule > printing output from css_class_generator"
1157     form_css_content = "/*-- special css form generated through ScribusUtils module --*/\n"
1158     form_css_content += "/*-- to have a graphic rendering with 'form_html' page template --*/\n\n"
1159     form_css_content += "/* head : classes declared for general purpose */\n"
1160     # iterating classes in document's head
1161     for class_name in properties_css_dict['head'].keys():
1162     # getting class properties_dict
1163     class_properties = properties_css_dict['head'][class_name]
1164     # joining exerything
1165     output_string = "." + str(class_name) + " {" \
1166     + "; ".join(["%s:%s" % (id, val) for id, val in class_properties.items()]) \
1167     + "}"
1168     # adding current line to css_content_object
1169     form_css_content += output_string + "\n"
1170     form_css_content += "\n/* standard field classes */ \n"
1171     # adding standard classes
1172     for class_name in properties_css_dict['standard'].keys():
1173     class_properties = properties_css_dict['standard'][class_name]
1174     output_string = "." + str(class_name) + " {" \
1175     + "; ".join(["%s:%s" % (id,val) for id,val in class_properties.items()]) \
1176     + "}"
1177     form_css_content += output_string + "\n"
1178     form_css_content += "\n/* error field classes */\n"
1179     # adding error classes
1180     for class_name in properties_css_dict['error'].keys():
1181     class_properties = properties_css_dict['error'][class_name]
1182     output_string = "." + str(class_name) + "_error {" \
1183     + "; ".join(["%s:%s" % (id,val) for id, val in class_properties.items()]) \
1184     + "}"
1185     form_css_content += output_string + "\n"
1186     form_css_content += "\n/* text_error field classes */ \n"
1187     # adding field error classes
1188     for class_name in properties_css_dict['err_d'].keys():
1189     class_properties = properties_css_dict['err_d'][class_name]
1190     output_string = "." + str(class_name) + "_error_display {" \
1191     + "; ".join(["%s:%s" % (id,val) for id,val in class_properties.items()]) \
1192     + "}"
1193     form_css_content += output_string + "\n"
1194     # return final String
1195     return form_css_content
1196 jp 15220
1197 thomas 8343 security.declarePublic('createOutputFile')
1198     def createOutputFile(self
1199     ,form_css_content
1200     ,form_css_id
1201     ,factory):
1202     """
1203     add a new file_object in zope, named form_css_id and containing
1204     the form_css_content
1205     """
1206     factory.addDTMLDocument(form_css_id,"css",form_css_content)
1207 jp 15220
1208    
1209 kevin 4147 class ScribusParser:
1210     """
1211 thomas 8343 Parses a Scribus file (pda) with PDF-elements inside
1212 kevin 4147 """
1213 yo 4537 #declare security
1214 kevin 4147 security = ClassSecurityInfo()
1215 jp 15220
1216 yo 4537 security.declarePublic('getObjectTooltipProperty')
1217     def getObjectTooltipProperty(self, check_key, default_value, object_name, object_dict):
1218     """
1219     check if 'check_key' exists in 'object_dict' and has a value
1220     if true, then returns this value, else returns 'default_value' and log 'object_name'
1221 thomas 8343
1222     This function is used to get attributes'values in an object_dict and to be sure
1223     a compatible value is returned (for that use default value)
1224 yo 4537 """
1225     #return object_dict.get(check_key, None) or default_value
1226     if object_dict.has_key(check_key):
1227     # 'check_key' exists
1228     if len(object_dict[check_key]) != 0:
1229     # check_key corresponding value is not null
1230     # returning this value
1231     return object_dict[check_key]
1232     else:
1233     # check_key is null, logging and asigning default value
1234     LOG("WARNING : " + str(object_name),0,"invalid " + str(check_key) \
1235     + ": using " + str(default_value))
1236     return default_value
1237     else:
1238     # check_key is null, logging and asigning default value
1239     LOG("WARNING : " + str(object_name),0,"no " + str(check_key) \
1240     + ": using " + str(default_value))
1241     return default_value
1242    
1243 thomas 8343 security.declarePublic('getXmlObjectPropertiesDict')
1244     def getXmlObjectsPropertiesDict(self, xml_string):
1245 yo 4537 """
1246     takes a string containing a whole document and returns
1247     a full dict of 'PAGE', containing a dict of 'PAGEOBJECT',
1248     containing a dict of all the relative attributes
1249     """
1250 jp 15220
1251 kevin 4147 # Create DOM tree from the xml string
1252 yo 4537 print " > create DOM tree"
1253 thomas 8343 dom_tree = minidom.parseString(xml_string)
1254 jp 15220
1255 yo 4537 # creating the root from the input file
1256 kevin 4147 dom_root = dom_tree.documentElement
1257 thomas 8343
1258    
1259     # Here two cases are possible :
1260     # - if the Scribus Document format is 1.2.* or less, then
1261     # the 'PAGE' contains all its 'PAGEOBJECT' elements so
1262     # - if the Scribus Document format is 1.3.*, then the 'PAGE'
1263     # does not contain any other object, and each 'PAGEOBJECT'
1264     # refers to its relative page_number using its 'OwnPage'
1265     # property
1266     keep_page = 0
1267     if "Version" not in dom_root.attributes.keys():
1268     # no version propery is contained in the document
1269     # the content does not comply with the Scribus document
1270     # specification
1271     print " Bad Scribus document format : no 'Version' property "
1272     return (None,keep_page,0)
1273     else:
1274 jp 15220
1275 thomas 8343 version = dom_root.attributes["Version"].value
1276     if version[:3] == "1.2" :
1277     # Scribus document format is 1.2
1278     print " found Scribus document format 1.2"
1279 jp 15220
1280 thomas 8343 #making a listing of all the PAGE objects
1281     print " > making listing of all PAGE objects"
1282     page_list = dom_root.getElementsByTagName("PAGE")
1283 jp 15220
1284 thomas 8343 returned_page_dict = {}
1285 jp 15220
1286 thomas 8343 #for each PAGE object, searching for PAGEOBJECT
1287     for page in page_list:
1288 yo 4537
1289 thomas 8343 # getting page number
1290     # parsing method from the previous ScribusUtils
1291     page_number = -1
1292     if 'NUM' in page.attributes.keys():
1293     page_number = str(page.attributes['NUM'].value)
1294 jp 15220
1295 thomas 8343 print " > PAGE NUM=" + str(page_number)
1296 jp 15220
1297 thomas 8343 # making a listing of all PAGEOBJECT in a specified PAGE
1298     page_object_list = page.getElementsByTagName("PAGEOBJECT")
1299 jp 15220
1300 thomas 8343 # initialising global output dictionary containing pages of elements
1301     returned_page_object_list = []
1302 jp 15220
1303 thomas 8343 # for each PAGEOBJECT, building dict with atributes
1304     for page_object in page_object_list:
1305 jp 15220
1306 thomas 8343 # initialising
1307     returned_page_object = {}
1308     field_name = ''
1309 kevin 4147
1310 thomas 8343 #iterating PAGEOBJECT attributes
1311     #old parsing method employed also here
1312     for node_id in page_object.attributes.keys():
1313     node_name = str(node_id)
1314     node_value = str(page_object.attributes[node_id].value)
1315    
1316 yo 4537 returned_page_object[node_name] = node_value
1317 thomas 8343
1318     if node_name == 'ANNAME':
1319     if node_value != '':
1320     field_name = node_value.replace(' ','_')
1321 jp 15220
1322 thomas 8343 if field_name != '' :
1323     #if 'PAGEOBJECT' has a valid name, then adding it to the global
1324     #dictionary containing all the 'PAGEOBJECT' of the 'PAGE'
1325     returned_page_object_list.append(returned_page_object)
1326     print " > PAGEOBJECT = " + str(field_name)
1327 jp 15220
1328 thomas 8343 #after having scanned all 'PAGEOBJECT' from a 'PAGE', adding the
1329     #relative informations to the list of 'PAGE' before going to the next one
1330     #in case the page is not empty
1331     if len(returned_page_object_list) != 0:
1332     returned_page_dict[page_number] = returned_page_object_list
1333 yo 4537
1334 thomas 8343 print "=> end ScribusParser.getXmlObjectPropertiesDict"
1335     return (returned_page_dict,keep_page,0)
1336 yo 4537
1337 thomas 8343 # end parsing document version 1.2.*
1338 mame 14510
1339 thomas 8343 else:
1340     print " found Scribus Doucment format 1.3"
1341     # assuming version is compliant with 1.3.* specifications
1342 yo 4537
1343 mame 14510 keep_page = 1
1344 yo 4537
1345 thomas 8343 # first of all getting DOCUMENT element to recover Scratch coordinates
1346     document_list = dom_root.getElementsByTagName("DOCUMENT")
1347     scratch_left = int(float(document_list[0].attributes["ScratchLeft"].value))
1348     scratch_top = int(float(document_list[0].attributes["ScratchTop"].value))
1349 mame 14510 page_gap = int(float(document_list[0].attributes["BORDERTOP"].value))
1350     scribus_page_width= int(float(document_list[0].attributes["PAGEWIDTH"].value))
1351     scribus_page_height = \
1352     int(float(document_list[0].attributes["PAGEHEIGHT"].value))
1353 thomas 8343 print " DOCUMENT > scratch_left = %s scratch_top = %s" % (scratch_left,scratch_top)
1354     #page_list = dom_root.getElementsByTagName("PAGE")
1355     page_object_list = dom_root.getElementsByTagName("PAGEOBJECT")
1356    
1357     # iterating 'PAGE' to build the first layer of the output structure
1358     #for page in page_list:
1359     # page_number = page
1360    
1361     # iterating 'PAGEOBJECT' to check compatibility (need a 'ANNAME' property)
1362     # and recover the related 'PAGE'
1363     returned_page_dict = {}
1364     for page_object in page_object_list:
1365     returned_page_object = {}
1366     field_name = ''
1367     field_OwnPage = ''
1368     # iterating field attributes
1369     for node_id in page_object.attributes.keys():
1370     node_name = str(node_id)
1371     node_value = str(page_object.attributes[node_id].value)
1372    
1373     if node_name == 'ANNAME':
1374     if node_value != '':
1375     field_name = node_value.replace(' ','_')
1376     print "> found field : %s" % field_name
1377     elif node_name == 'OwnPage':
1378     field_OwnPage = node_value
1379     elif node_name == 'XPOS':
1380     print " > updating Xpos : %s - %s = %s" % (scratch_left+int(float(node_value)),scratch_left,node_value)
1381     node_value = str(int(float(node_value)) - scratch_left)
1382     elif node_name == 'YPOS':
1383     print " > updating Ypos : %s - %s = %s" % (scratch_top+int(float(node_value)),scratch_top,node_value)
1384     node_value = str(int(float(node_value)) - scratch_top)
1385    
1386     returned_page_object[node_name] = node_value
1387    
1388     if field_name != '':
1389     print " > field has the name : %s" % field_name
1390     # field seems to be ok, just need to check if the related page
1391     # already exists in the 'returned_page_dict'
1392     if not field_OwnPage in returned_page_dict.keys():
1393     # page does not exists, need to create it before adding the field
1394     print " > adding new page"
1395     returned_page_dict[field_OwnPage] = []
1396     returned_page_dict[field_OwnPage].append(returned_page_object)
1397     return (returned_page_dict,keep_page,page_gap)
1398    
1399    
1400     security.declarePublic('getPropertiesConversionDict')
1401     def getPropertiesConversionDict(self, text_page_dict):
1402 yo 4537 """
1403 thomas 8343 takes a dict generated from 'getXmlObjectsProperties' method
1404     and returns a dict of PAGE including a list with usefull
1405     'PAGEOBJECT' attributes updated with standard attributes
1406     and special informations contained in the
1407 yo 4537 'ANTOOLTIP' attribute.
1408 jp 15220
1409 yo 4537 usefull attributes are
1410     - position & size
1411     - type & inputformat (for erp5 and html)
1412     - creation order (using 'nb' property)
1413     - erp5 relative position (left, right, etc.)
1414     - title information
1415     - other properties (read_only, multiline, etc.)
1416     - etc.
1417 jp 15220
1418 yo 4537 for each PAGE, all PAGEOBJECT are sorted according to their creation order
1419     'nb'
1420     """
1421    
1422     print "\n => ScribusParser.getPropertiesConversion"
1423     returned_page_dict = {}
1424 jp 15220
1425 yo 4537 # declaring ScribusParser object to run other functions
1426     sp = ScribusParser()
1427 jp 15220
1428 yo 4537 for page_number in text_page_dict.keys():
1429     # iterating through 'PAGE' object of the document
1430     # id = page_number
1431     # content = page_content
1432     page_content = text_page_dict[page_number]
1433 jp 15220
1434 thomas 8343 print " => PAGE = %s" % str(page_number)
1435 jp 15220
1436 yo 4537 # declaring special lists used to generate nb for all objects
1437     # this 'nb' property is usefull to define the object creation order
1438     # all objects are sorted (has nb / has no nb) and all objects without
1439     # nb attribte are added t othe end of the 'has nb' list
1440     nb_property_nbkey_list = []
1441     nb_property_nonbkey_list = []
1442 mame 14510
1443 yo 4537 # declaring output object
1444     returned_object_dict = {}
1445 mame 14510
1446 yo 4537 # if page_content.haskey('my_fax_field')
1447     # print "my_fax_field"
1448 thomas 8343 for object_data in page_content:
1449 yo 4537 # iterating through 'PAGEOBJECT' of the page
1450     # id = object_name
1451     # content = object_content
1452 mame 14510
1453 thomas 8343 object_name = object_data['ANNAME']
1454     del object_data['ANNAME']
1455     object_content = object_data
1456 mame 14510 multiline_field= 0
1457     #multiline_field= object_content['ANFLAG']
1458 yo 4537 print " => PAGEOBJECT = " + str(object_name)
1459 thomas 8343 # recovering other attributes list (string format) from 'ANTOOLTIP'
1460     text_tooltipfield_properties = \
1461     sp.getObjectTooltipProperty('ANTOOLTIP','',object_name,object_content)
1462 mame 14510 #recovering the page attributes
1463    
1464 yo 4537 #declaring output file
1465     tooltipfield_properties_dict = {}
1466     #splitting the different attributes
1467 thomas 8343 tooltipfield_properties_list = \
1468     text_tooltipfield_properties.split('#')
1469 mame 14510
1470 yo 4537 print " " + str(tooltipfield_properties_list)
1471 mame 14510
1472 thomas 8343 # test if first argument is nb according to previous
1473     # naming-conventions i.e composed of three digits without
1474     # id 'nb:' written
1475 yo 4537 if str(tooltipfield_properties_list[0]).isdigit():
1476 thomas 8343 # first value of tooltilfield is digit : assuming this is
1477     # a creation-order information compliant with the previous
1478     # naming convention
1479 yo 4537 # modifying this field to make it compatible with new convention
1480 thomas 8343 print " => first element = " + \
1481     str(tooltipfield_properties_list[0] + " is digit...")
1482     LOG("WARNING : " + str(object_name),0,"out-of-date " \
1483 yo 4537 + "for tooltipfield, please check naming_conventions")
1484     temp_nb = tooltipfield_properties_list[0]
1485     # deleting actual entry
1486     tooltipfield_properties_list.remove(temp_nb)
1487     # adding new entry to the list
1488 thomas 8343 tooltipfield_properties_list.append( "nb:" + str(temp_nb))
1489 yo 4537 # end of translating work to get new standard compliant code
1490     for tooltipfield_property in tooltipfield_properties_list:
1491     #printing each property before spliting
1492     print " " + str(tooltipfield_property)
1493     # splitting attribute_id / attribute_value
1494     tooltipfield_properties_split = tooltipfield_property.split(':')
1495     if len(tooltipfield_properties_split) == 2:
1496     tooltipfield_id = tooltipfield_properties_split[0]
1497     tooltipfield_value = tooltipfield_properties_split[1]
1498     # making dictionary from 'ANTOOLTIP' attributes
1499 thomas 8343 tooltipfield_properties_dict[tooltipfield_id] = \
1500     tooltipfield_value
1501 yo 4537 # end of 'ANTOOLTIP' parsing
1502 jp 15220
1503 thomas 8343 # getting usefull attributes from scribus 'PAGEOBJECT
1504     #and 'ANTOOLTIP'
1505     #
1506     object_properties = {}
1507 mame 14510 page_properties = {}
1508 yo 4537 # getting object position and size
1509 thomas 8343 object_properties['position_x'] = \
1510     sp.getObjectTooltipProperty('XPOS',
1511     '0',
1512     object_name,
1513     object_content)
1514     object_properties['position_y'] = \
1515     sp.getObjectTooltipProperty('YPOS',
1516     '0',
1517     object_name,
1518     object_content)
1519     object_properties['size_x'] = \
1520     sp.getObjectTooltipProperty('WIDTH',
1521     '100',
1522     object_name,
1523     object_content)
1524     object_properties['size_y'] = \
1525     sp.getObjectTooltipProperty('HEIGHT',
1526 mame 14510 '17',
1527 thomas 8343 object_name,
1528     object_content)
1529 jp 15220
1530 thomas 8343 # converting values to integer-compliant to prevent errors
1531     # when using them for that converting from 'str' -> 'float'
1532     # -> 'int' -> 'str'
1533     object_properties['position_x'] = \
1534     str(int(float(object_properties['position_x'])))
1535     object_properties['position_x'] = \
1536     str(int(float(object_properties['position_x'])))
1537     object_properties['position_y'] = \
1538     str(int(float(object_properties['position_y'])))
1539     object_properties['size_x'] = \
1540     str(int(float(object_properties['size_x'])))
1541     object_properties['size_y'] = \
1542     str(int(float(object_properties['size_y'])))
1543 jp 15220
1544 yo 4537 # getting object title
1545     # object title can only be user-specified in the 'tooltip' dict
1546 thomas 8343 object_properties['title'] = \
1547     sp.getObjectTooltipProperty('title',
1548     object_name,
1549     object_name,
1550     tooltipfield_properties_dict)
1551 jp 15220
1552 yo 4537 # getting object order position for erp5 form
1553 thomas 8343 temp_order = \
1554     sp.getObjectTooltipProperty('order',
1555     'none',
1556     object_name,
1557     tooltipfield_properties_dict)
1558    
1559 yo 4537 if temp_order not in ['left','right']:
1560     # temp_order invalid
1561 thomas 8343 # trying to get it from its position in original Scribus file
1562     if int(object_properties['position_x']) > 280.0 :
1563 yo 4537 temp_order = 'right'
1564     else :
1565     temp_order = 'left'
1566     object_properties['order'] = temp_order
1567    
1568     # getting special ANFLAG sub-properties
1569 thomas 8343 temp_ANFLAG = long(sp.getObjectTooltipProperty('ANFLAG',
1570     0,
1571     object_name,
1572     object_content))
1573 yo 4537 # initialising results
1574     anflag_properties = {}
1575     anflag_properties['noScroll'] = 0
1576     anflag_properties['noSpellCheck'] = 0
1577     anflag_properties['editable'] = 0
1578     anflag_properties['password'] = 0
1579     anflag_properties['multiline'] = 0
1580     anflag_properties['noExport'] = 0
1581     anflag_properties['required'] = 0
1582     anflag_properties['readOnly'] = 0
1583     # analysing result
1584 thomas 8343 print " => ANFLAG = " + str(temp_ANFLAG)
1585     # These tests uses some special variables
1586     # defined at the begining of the script
1587     if temp_ANFLAG - long(def_noScroll) >= 0:
1588 yo 4537 # substracting value
1589 thomas 8343 temp_ANFLAG = temp_ANFLAG - long(def_noScroll)
1590 yo 4537 # 'do not scroll' field
1591     # adding property
1592     anflag_properties['noscroll'] = 1
1593 thomas 8343 if temp_ANFLAG - long(def_noSpellCheck) >= 0:
1594     temp_ANFLAG = temp_ANFLAG - long(def_noSpellCheck)
1595 yo 4537 # 'do not spell check' field
1596     anflag_properties['noSpellCheck'] = 1
1597 thomas 8343 if temp_ANFLAG - long(def_editable) >= 0:
1598     temp_ANFLAG = temp_ANFLAG - long(def_editable)
1599 yo 4537 # 'editable' field
1600     anflag_properties['editable'] = 1
1601 thomas 8343 if temp_ANFLAG - long(def_password) >= 0:
1602     temp_ANFLAG = temp_ANFLAG - long(def_password)
1603 yo 4537 # 'password' field
1604     anflag_properties['password'] = 1
1605 thomas 8343 if temp_ANFLAG - long(def_multiLine) >= 0:
1606     temp_ANFLAG = temp_ANFLAG - long(def_multiLine)
1607 yo 4537 # 'multiline' field
1608     anflag_properties['multiline'] = 1
1609 thomas 8343 if temp_ANFLAG - long(def_noExport) >= 0:
1610     temp_ANFLAG = temp_ANFLAG - long(def_noExport)
1611 yo 4537 # 'do not export data' field
1612     anflag_properties['noExport'] = 1
1613 thomas 8343 if temp_ANFLAG - long(def_required) >= 0:
1614     temp_ANFLAG = temp_ANFLAG - long(def_required)
1615 yo 4537 # 'required field
1616     anflag_properties['required'] = 1
1617 thomas 8343 if temp_ANFLAG == long(def_readOnly):
1618 yo 4537 # 'read only" field
1619     anflag_properties['readOnly'] = 1
1620    
1621     # getting maximum number of caracters the field can hold
1622 thomas 8343 # note : only used for textfields ('StringField', 'IntegerField',
1623     # 'FloatField', etc.)
1624     # first checking user specifications in tooltipfield
1625     object_properties['maximum_input'] = \
1626     sp.getObjectTooltipProperty('maximum_input',
1627     0,
1628     object_name,
1629     tooltipfield_properties_dict)
1630     # if returned value is empty, then trying 'ANMC' Scribus property
1631     if object_properties['maximum_input'] == 0:
1632     object_properties['maximum_input'] = \
1633     sp.getObjectTooltipProperty('ANMC',
1634     '0',
1635     object_name,
1636     object_content)
1637 yo 4537 print " => MaxInput = %s" % object_properties['maximum_input']
1638 jp 15220
1639 yo 4537 # getting object type :
1640     # first checking for user-specified type in 'tooltip' properties
1641     if tooltipfield_properties_dict.has_key('type'):
1642 thomas 8343 # 'type' id in tooltip : using it and ignoring other 'type'
1643     # information in scribus properties
1644 yo 4537 object_properties['type'] = tooltipfield_properties_dict['type']
1645 thomas 8343 elif tooltipfield_properties_dict.has_key('title_item'):
1646     # if page_object has a special attribute 'title_item' this means
1647     # the field is a CheckBoxField
1648     object_properties['type'] = 'CheckBoxField'
1649     # if no user-specified type has been found, trying to
1650     # find scribus-type
1651 yo 4537 elif object_content.has_key('ANTYPE'):
1652     # from scribus type (selected in the scribus PDF-form properties)
1653     object_type = str(object_content['ANTYPE'])
1654     if object_type == '2':
1655     #type 2 = PDF-Button
1656     object_properties['type'] = 'Button'
1657     elif object_type == '3':
1658     #type 3 = PDF-Text : Stringfield by default
1659     object_properties['type'] = 'StringField'
1660     if anflag_properties['multiline'] == 1:
1661     # Stringfield is multiline, converting to TextAreaField
1662     object_properties['type'] = 'TextAreaField'
1663     elif object_content.has_key('ANFORMAT'):
1664     object_format = str(object_content['ANFORMAT'])
1665     # checking kind of Stringfield
1666     if object_format == '1':
1667     #type is number
1668     object_properties['type'] = 'IntegerField'
1669     elif object_format == '2':
1670     #type is percentage
1671     object_properties['type'] = 'FloatField'
1672     elif object_format == '3':
1673     #type is date
1674     object_properties['type'] = 'DateTimeField'
1675     elif object_format == '4':
1676     #type is time
1677     object_properties['type'] = 'DateTimeField'
1678     elif object_type == '4':
1679     # type 4 = PDF-Checkbox
1680     object_properties['type'] = 'CheckBoxField'
1681     elif object_type == '5':
1682     # type 5 = PDF-Combobox
1683     object_properties['type'] = 'ComboBox'
1684     elif object_type == '6':
1685     # type 6 = PDF-ListBox
1686     object_properties['type'] = 'ListBox'
1687     else:
1688 thomas 8343 # object type not found in user-properties neither in
1689     # document-properties. logging and initialising with
1690     # default type
1691     LOG("WARNING : " + str(object_name),
1692     0,
1693     "no 'type' found, please check your document properties")
1694     print " => no type specified : default = StringField"
1695 yo 4537 object_properties['type'] = 'StringField'
1696     print " type = " + str(object_properties['type'])
1697 thomas 8343
1698    
1699     # getting data_type relative to object type (used in
1700     # object property_sheet to save field value.
1701     object_properties['data_type'] = 'string'
1702     object_properties['default_data'] = ''
1703     if object_properties['type'] == 'IntegerField':
1704     object_properties['data_type'] = 'int'
1705     object_properties['default_data'] = 0
1706     if object_properties['type'] == 'CheckBoxField':
1707     object_properties['data_type'] = 'boolean'
1708     object_properties['default_data'] = 0
1709     if object_properties['type'] == 'DateTimeField':
1710     object_properties['data_type'] = 'date'
1711     object_properties['default_data'] = '1970/01/01'
1712    
1713 yo 4537 # getting 'required' property
1714 thomas 8343 # checking for user data in tooltipfield. if nothing found then
1715     # taking hard-written value in anflag properties
1716     object_properties['required'] = \
1717     sp.getObjectTooltipProperty('required',
1718     anflag_properties['required'],
1719     object_name,
1720     tooltipfield_properties_dict)
1721 jp 15220
1722 yo 4537 # getting type properties for special types
1723 thomas 8343 object_properties['rendering'] = 'single'
1724     # Stringfields handle properties
1725 yo 4537 # checkbox objects belongs to a group of checkbox
1726     if str(object_properties['type']) == 'CheckBox' :
1727     # checking if THIS checkbox is in a group
1728 thomas 8343 object_properties['group'] = \
1729     sp.getObjectTooltipProperty('group',
1730     '0',
1731     object_name,
1732     tooltipfield_properties_dict)
1733     print " group = " + str(object_properties['group'])
1734     # object is listbox, and listbox have several possible values
1735     # WARNING listbox have not been tested in graphic rendering for
1736     # the moment. is there any use for listbox in PDF-like rendering ?
1737 yo 4537 if str(object_properties['type']) == 'ListBox' :
1738 thomas 8343 # checking if this listbox has different possible values
1739     object_properties['items'] = \
1740     sp.getObjectTooltipProperty('items',
1741     '',
1742     object_name,
1743     tooltipfield_properties_dict)
1744     # object is datetimefield and need several informations
1745 yo 4537 if str(object_properties['type']) == 'DateTimeField':
1746 thomas 8343 # has been tested successfully
1747     object_properties['rendering'] = 'multiple'
1748     # checking if field has input_order property
1749     object_properties['input_order'] = \
1750     sp.getObjectTooltipProperty('input_order',
1751     'ymd',
1752     object_name,
1753     tooltipfield_properties_dict)
1754 jp 15220
1755 thomas 8343 # checking if field has date_only property
1756     object_properties['date_only'] = \
1757     sp.getObjectTooltipProperty('date_only',
1758     '1',
1759     object_name,
1760     tooltipfield_properties_dict)
1761    
1762     # checking if special date separator is specified
1763     # most of PDF forms already have '/' character to differenciate
1764     # date fields, in this case no separator is needed and the script
1765     # will automatically insert ' ' between element.
1766     # > this value is not used in ScribusUtils.py , but in PDFForm.py
1767     # when creating the fdf file to fill the PDF form.
1768     object_properties['date_separator'] = \
1769     sp.getObjectTooltipProperty('date_separator',
1770     ' ',
1771     object_name,
1772     tooltipfield_properties_dict)
1773     object_properties['time_separator'] = \
1774     sp.getObjectTooltipProperty('time_separator',
1775     ' ',
1776     object_name,
1777     tooltipfield_properties_dict)
1778 jp 15220
1779 thomas 8343 # object is relationstringfield and needs some information
1780 yo 4537 if str(object_properties['type']) == 'RelationStringField':
1781 thomas 8343 # has been tested successfully
1782     object_properties['rendering'] = 'multiple'
1783     object_properties['portal_type'] = \
1784     sp.getObjectTooltipProperty('portal_type',
1785     '0',
1786     object_name,
1787     tooltipfield_properties_dict)
1788     object_properties['base_category'] = \
1789     sp.getObjectTooltipProperty('base_category',
1790     '0',
1791     object_name,
1792     tooltipfield_properties_dict)
1793     object_properties['catalog_index'] = \
1794     sp.getObjectTooltipProperty('catalog_index',
1795     '0',
1796     object_name,
1797     tooltipfield_properties_dict)
1798     object_properties['default_module'] = \
1799     sp.getObjectTooltipProperty('default_module',
1800     '0',
1801     object_name,
1802     tooltipfield_properties_dict)
1803 jp 15220
1804 yo 4537 # getting creation order from 'tooltip' properties
1805     # used to create ERP5 objects in a special order
1806 thomas 8343 if tooltipfield_properties_dict.has_key('nb') and \
1807     str(tooltipfield_properties_dict['nb']).isdigit():
1808 yo 4537 # object has a nb properties containing its creation position
1809     # adding the object in the ordered list
1810     nb_value = int(tooltipfield_properties_dict['nb'])
1811 thomas 8343 print " =>'nb' property specified : using it"
1812     print " > len(list)=%s" % len(nb_property_nbkey_list)
1813 yo 4537 # iterating through existing list to find right position
1814     # before inserting value
1815     if len(nb_property_nbkey_list) == 0:
1816     print " => 'nb' list empty : adding without sorting"
1817     # list is empty : adding value without sort
1818     nb_property_nbkey_list.insert(0,(nb_value,object_name))
1819     elif nb_property_nbkey_list[len(nb_property_nbkey_list)-1][0] <= nb_value:
1820     print " => 'nb' end : adding at the end"
1821     # last element is smaller than new element : adding at the end
1822     nb_property_nbkey_list.append((nb_value,object_name))
1823     else:
1824     print " => checking for place to add the element"
1825     # searching where to insert the element in the ordered list
1826     for temp_key in range(len(nb_property_nbkey_list)):
1827     temp_value = nb_property_nbkey_list[temp_key][0]
1828     temp_content = nb_property_nbkey_list[temp_key][1]
1829     print " @" + str(temp_key) + " temp=" + str(temp_value) + "/" + str(nb_value)
1830     if nb_value < temp_value:
1831     #first position where actual 'nb' is smaller than temp 'nb'
1832     # inserting new couple (nb_value,object_name) here
1833     print " inserting here : " + str(temp_value) + "/" + str(nb_value)
1834     nb_property_nbkey_list.insert(temp_key,(nb_value,object_name))
1835     # element has been insered , no need to continue the search => breaking
1836     break
1837     else:
1838     # object has no nb property. logging and adding it to the list of
1839     # nb-less objects. Script will automatically find a 'nb' value for this element
1840     LOG("WARNING : " + str(object_name),0,"no 'nb' defined : finding a free slot")
1841     print " => no 'nb' property specified : post-processing will try to define one"
1842     nb_property_nonbkey_list.append(object_name)
1843 jp 15220
1844 yo 4537 # adding current object with its relative properties to the dict
1845     # before going to the next page_object
1846     returned_object_dict[object_name] = object_properties
1847 jp 15220
1848 yo 4537 # final processing before returning full page with modified
1849     # page_object_properties : setting 'nb' property to all objects
1850     # without user-specified 'nb' property
1851     for object_name in nb_property_nonbkey_list:
1852     # listing all objects with no 'nb' declared
1853     # defining final position in output list : absolute pos + relative pos
1854     object_position = len(nb_property_nbkey_list) + 1
1855     # and addind it to the end of the final nb-list
1856     # to give them a 'nb' property
1857     nb_property_nbkey_list.append((object_position,object_name))
1858 thomas 8343 print " => 'nb' found for %s : %s" % (object_name,object_position)
1859 jp 15220
1860 yo 4537 # now all page_object are referenced in the list, we just need to sort
1861     # the elements in the good order. for that a new list of objects is needed
1862     returned_object_list = []
1863     for nb_ind in range(len(nb_property_nbkey_list)):
1864     # iterating through final nb-list
1865     # getting list-object information
1866     (nb_key, nb_value) = nb_property_nbkey_list[nb_ind]
1867     # setting object's 'nb' property
1868     returned_object_dict[nb_value]['nb'] = nb_ind + 1
1869     # add the object at the end of the new list
1870     returned_object_list.append((nb_value,returned_object_dict[nb_value]))
1871 jp 15220
1872 yo 4537 # adding returned list of object to the page dict
1873     # before going to the next page
1874     returned_page_dict[page_number] = returned_object_list
1875 jp 15220
1876 yo 4537 # returning final dict containing all the modified data
1877     print " => end ScribusParser.getPropertiesConversion"
1878 mame 14510 return (returned_page_dict)
1879 thomas 8343
1880     security.declarePublic('initFieldDict')
1881     def initFieldDict(self):
1882     """
1883     initialize the global_properties dict. this dict will be filled
1884     with Field attributes (from getFieldAttributes)
1885     """
1886     # initializing sub dicts and attributes
1887     global_object_dict = {}
1888     global_page_number = 0
1889     # defining main dict
1890     global_properties = {}
1891     global_properties['object'] = global_object_dict
1892     global_properties['page'] = global_page_number
1893 mame 14510 global_properties['page_width']= 595
1894     global_properties['page_height']= 842
1895 thomas 8343 # return final main dict
1896     return global_properties
1897    
1898    
1899    
1900    
1901     security.declarePublic('getFieldAttributes')
1902     def getFieldAttributes(self,
1903     field,
1904     option_html,
1905     page_id,
1906     global_properties
1907     ):
1908     """
1909     get only useful field attributes from properties_field
1910     and save them in global_properties
1911     """
1912     (id,properties_field) = field
1913     # declaring dict to store data
1914     object_dict = {}
1915     # getting usefull properties for field generation
1916     object_dict['title'] = str(properties_field['title'])
1917     object_dict['erp_type'] = str(properties_field['type'])
1918     object_dict['data_type'] = str(properties_field['data_type'])
1919     object_dict['default'] = properties_field['default_data']
1920     object_dict['nb'] = str(properties_field['nb'])
1921     object_dict['attributes'] = {}
1922     if option_html ==1:
1923     # pdf-like rendering
1924     object_dict['order'] = page_id
1925     else:
1926     # erp rendering
1927     object_dict['order'] = properties_field['order']
1928     # recovering attributes
1929     # required attribute specify if the user has to fill this field
1930     object_dict['attributes']['required'] =\
1931     properties_field['required']
1932     # max number of caracters that can be entered in a field
1933     # only used with String fieds (including Integer and Float fields)
1934     if 'maximum_input' in properties_field.keys():
1935     if 'display_maxwidth' in object_dict['attributes'].keys():
1936     object_dict['attributes']['display_maxwidth'] = \
1937     int(properties_field['maximum_input'])
1938     # can only be effective without css class, i.e only effective
1939     # in a ERP5-like rendering
1940     if 'display_width' in object_dict['attributes'].keys():
1941     object_dict['attributes']['display_width'] = \
1942     int(properties_field['maximum_width'])
1943    
1944     # getting special properties for DateTimeField objects
1945     if object_dict['erp_type'] == 'DateTimeField':
1946     # recovering ERP equivalent for user's input_order
1947     if properties_field['input_order'] in ['day/month/year','dmy']:
1948     object_dict['attributes']['input_order'] = 'dmy'
1949     elif properties_field['input_order'] in ['month/day/year','mdy']:
1950     object_dict['attributes']['input_order'] = 'mdy'
1951     elif properties_field['input_order'] in ['year/month/day','ymd']:
1952     object_dict['attributes']['input_order'] = 'ymd'
1953     else:
1954     print " found incompatible 'input_order', assuming default ymd"
1955     object_dict['attributes']['input_order'] = 'ymd'
1956     # checking if date only or date + time
1957     object_dict['attributes']['date_only'] = int(properties_field['date_only'])
1958     if option_html == 1:
1959     # defining default separators to '' to prevent bug when rendering in
1960     # graphic mode
1961     object_dict['attributes']['date_separator'] = ''
1962     object_dict['attributes']['time_separator'] = ''
1963     else:
1964     # rendering is ERP5 type, can keep the final date and time separators
1965     object_dict['attributes']['date_separator'] = properties_field['date_separator']
1966     object_dict['attributes']['time_separator'] = properties_field['time_separator']
1967     # getting special attributes for RelationStringField
1968     elif object_dict['erp_type'] == 'RelationStringField':
1969     portal_type_item = properties_field['portal_type'].capitalize()
1970     object_dict['attributes']['portal_type'] =\
1971     [(portal_type_item,portal_type_item)]
1972     object_dict['attributes']['base_category'] =\
1973     properties_field['base_category']
1974     object_dict['attributes']['catalog_index'] =\
1975     properties_field['catalog_index']
1976     object_dict['attributes']['default_module'] =\
1977     properties_field['default_module']
1978     # idem : special field concerning RadioField (not tested)
1979     elif object_dict['erp_type'] == 'RadioField':
1980     # radio fields have not been tested for the moment
1981     items = []
1982     for word_item in properties_field['item'].split('|'):
1983     items.append((word_item,word_item.capitalize()))
1984     object_dict['attributes'] = items
1985     #elif object_dict['erp_type'] == 'CheckBoxField':
1986     # checkboxfield needs to have their field data updated
1987     # this is not done automatically so it is needed to do
1988     # it manually
1989    
1990     # save attributes to the global_properties dict
1991     global_properties['object'][id] = object_dict
1992    
1993 kevin 4147 security.declareProtected('Import/Export objects', 'getContentFile')
1994     def getContentFile(self, file_descriptor):
1995     """ Get file content """
1996     return file_descriptor.read()
1997 mame 14510 security.declareProtected('Import/Export objects', 'getFileOpen')
1998     def getFileOpen(self, file_descriptor):
1999     """ Get file content """
2000     return file_descriptor.open('r')
2001 kevin 4147
2002     InitializeClass(ScribusParser)
2003     allow_class(ScribusParser)
2004 thomas 8343
2005     InitializeClass(ManageCSS)
2006     allow_class(ManageCSS)
2007    
2008     InitializeClass(ManageFiles)
2009     allow_class(ManageFiles)
2010    
2011     InitializeClass(ManageModule)
2012     allow_class(ManageModule)

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.2