/[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 - (show annotations)
Mon Sep 28 13:27:38 2009 UTC (3 years, 7 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 ##############################################################################
2 #
3 # Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
4 # Guy Oswald OBAMA <guy@nexedi.com>
5 # thomas <thomas@nexedi.com>
6 # Mame C.Sall <mame@nexedi.com>
7 #
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 # 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 # improved and modified significantly.
28 # UPDATE => the code is almost refactored and supports
29
30 from Products.PythonScripts.Utility import allow_class
31 from ZPublisher.HTTPRequest import FileUpload
32 from xml.dom.ext.reader import PyExpat
33 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 import getopt, sys, os
42 from urllib import quote
43
44 from Products.ERP5.ERP5Site import ERP5Site
45 from Products.Formulator.TALESField import TALESMethod
46 # 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
65
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 real_object_names={}
82 # 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 new_selection.extend(selection)
118 portal_skins.manage_skinLayers(skinpath = tuple(new_selection),
119 skinname = skin_name,
120 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 form_view_list_object.rename_group('Default','bottom')
149 default_groups = []
150 # 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 ('description','Description'),
176 ('translated_simulation_state','State')]
177 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 object_portal_type
190 ):
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 #get the scaling factor
202 # 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 del default_groups[0:]
212 for page_iterator in range(global_properties['page']):
213 page_number = 'page_%s' % str(page_iterator)
214
215
216 default_groups.append(page_number)
217 # 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 return (default_groups)
248
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 #field_tales = field_values['tales']
295 # 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 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 #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 , "string:${object_url}/%s" % object_names['view_pdf']
444 , ""
445 , "View"
446 , "object_print"
447 , priority=2.0
448 )
449 object_portal_type_value.addAction( "history"
450 , "History"
451 , "string:${object_url}/Base_viewHistory"
452 , ""
453 , "View"
454 , "object_view"
455 , priority=99.0
456 )
457 object_portal_type_value.addAction( "metadata"
458 , "Metadata"
459 , "string:${object_url}/Base_viewMetadata"
460 , ""
461 , "Manage properties"
462 , "object_view"
463 , priority=100.0
464 )
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 title = title_module)
482
483
484 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 form_title)
503
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
551 else:
552 TALES = "python: here.get" + "".join(
553 cell_process_name_list) + "()"
554
555 else:
556 # PropertySheet and Document
557 if cell_process_name_list[-1] == 'List':
558 TALES = "python: " + ", ".join(
559 "here.getProperty('" + cell_name[3:] + "')")
560
561 else:
562 TALES = "python: here.getProperty('" + cell_name[3:] +"')"
563 print " %s > %s " % (cell_name,TALES)
564 c.setCellTALES(cell_name,TALES)
565
566 def getPDFFile(self, file_descriptor):
567 """ Get file content """
568 return file_descriptor.open()
569
570 security.declarePublic('setBackgroundPictures')
571 def setBackgroundPictures(self,
572 pdf_file,
573 object_names,
574 skin_folder,
575 desired_height,
576 desired_width,
577 resolution
578 ):
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 import tempfile
593 from tempfile import NamedTemporaryFile
594 # opening new file on HDD to save PDF content
595 #temp_test= NamedTemporaryFile(mode= "w+b")
596 #tempFile= NamedTemporaryFile().name
597 ScribusUtilsTempPDF= NamedTemporaryFile(mode= "w+b")
598 ScribusUtilstempsPDFName= NamedTemporaryFile().name
599 # going to the begining of the input file
600
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 pdf_file.seek(0)
612 # saving content
613 # saving content
614 temp_pdf.write(pdf_file.read())
615 temp_pdf.close()
616
617 # launching first soft to convert from PDF to PPM
618 ScribusUtilstempsPPM = NamedTemporaryFile(mode="w+b")
619 ScribusUtilstempsPPMName = NamedTemporaryFile().name
620 result = commands.getstatusoutput('pdftoppm -r %s %s %s' % (resolution, ScribusUtilstempsPDFName, ScribusUtilstempsPPMName))
621 # launching second soft to convert from PPM to JPEG
622 ScribusUtilstempsJPG = NamedTemporaryFile(mode="w+b")
623 ScribusUtilstempsJPGName = NamedTemporaryFile().name
624
625 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
628 number = ScribusUtilstempsJPGName.find('tmp')
629 directory_tmp= ScribusUtilstempsJPGName[:(number+4)]
630
631 # getting list of JPG output files
632 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 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 result = commands.getstatusoutput('rm -f /tmp/tmp*') # JPS-XXX Extremely dangerous
650 # 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 size_x = desired_height
653 size_y = desired_width
654
655 return (size_x, size_y,real_size_x,real_size_y)
656
657 security.declarePublic('getPageattributes')
658 def getPageattributes (self,
659 global_properties,
660 pdf_file
661 ):
662 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
668 # going to the begining of the input file
669
670 # 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
685 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
700 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 ,properties_css_dict
793 ,page_iterator
794 ,page_id
795 ,page_height
796 ,page_width,
797 ,original_page_width
798 ,original_page_height
799 ,width_groups,height_groups):
800 """
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 properties_page = {}
808 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 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 else:
832 # margin-top = page height
833 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 # 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 return (properties_css_dict,properties_page,actual_width,actual_height)
847
848
849
850
851
852 security.declarePublic('setFieldProperties')
853 def setFieldProperties(self
854 ,properties_css_dict
855 ,field
856 ,page_width
857 ,page_height
858 ,page_iterator
859 ,page_gap
860 ,keep_page,
861 ,original_page_width
862 ,original_page_height
863 ,properties_page,actual_width,actual_height):
864 """
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
871 # 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
878 scaling_factor1= (page_width)/(properties_page['actual_width'])
879 scaling_factor2= (page_height)/(properties_page['actual_height'])
880
881 properties_field['position_y'] = \
882 str(float(properties_field['position_y']) - \
883 (actual_height + page_gap)* page_iterator)
884
885 # 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 str(scaling_factor2 *float(properties_field['size_y'])) + 'px'
904 properties_css_object_error['height'] = \
905 str(scaling_factor2 *float(properties_field['size_y'])) + 'px'
906 # 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 if float(properties_field['size_y']) > 8.0:
911 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 properties_css_object_stand['font-size'] = \
917 str((scaling_factor2 *float(properties_field['size_y']))-3.5 ) + 'px'
918 properties_css_object_error['font-size'] = \
919 str((scaling_factor2 *float(properties_field['size_y']))-3.5) + 'px'
920 else:
921 properties_css_object_stand['font-size'] = \
922 str(12) + 'px'
923 properties_css_object_error['font-size'] = \
924 str(12) + 'px'
925 properties_css_object_err_d['margin-left'] = str(page_width + 20 ) + 'px'
926 properties_css_object_stand['margin-top'] = \
927 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
928 properties_css_object_error['margin-top'] = \
929 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
930 properties_css_object_err_d['margin-top'] = \
931 str((scaling_factor2 *float(properties_field['position_y']))) + 'px'
932 # 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 elif properties_field['type'] != 'TextAreaField':
942 properties_css_object_stand['background'] = '#F5F5DC'
943 properties_css_object_error['background'] = 'rgb(255,64,64)' # Previously #B9D9D4 - should become a parameter
944 else:
945 properties_css_object_stand['background'] = '#F5F5DC' # Previously #B9D9D4 - should become a parameter
946 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 str(scaling_factor1 *float(properties_field['size_x'])) + 'px'
960 properties_css_object_error['width'] = \
961 str(scaling_factor1 *float(properties_field['size_x'])) + 'px'
962 properties_css_object_stand['margin-left'] = \
963 str((scaling_factor1 *float(properties_field['position_x']))) + 'px'
964 properties_css_object_error['margin-left'] = \
965 str((scaling_factor1 *float(properties_field['position_x']))) + 'px'
966 # 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 str(scaling_factor1*(float(properties_field['size_x']) / 2)) + 'px'
993 field_dict[1]['margin-left'] = \
994 str(scaling_factor1*float(properties_field['position_x'])) + 'px'
995
996 # processing secondary input picture
997 field_dict[2] = {}
998 field_dict[2]['width'] = str(scaling_factor1*(float(properties_field['size_x']) /2)) + 'px'
999 field_dict[2]['margin-left'] = \
1000 str(scaling_factor1*(float(properties_field['size_x']) /2 +\
1001 float(properties_field['position_x']))) + 'px'
1002 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 width_part = int((float(properties_field['size_x']) / 4))
1025
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 ['day/month/year','dmy','month/day/year','mdy']:
1032 # 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 field_dict[1]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1037 field_dict[1]['margin-left'] = \
1038 str(scaling_factor1 *float(properties_field['position_x'])) + 'px'
1039
1040 # processing second field
1041 field_dict[2] = {}
1042 field_dict[2]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1043 field_dict[2]['margin-left'] = \
1044 str(scaling_factor1 *(float(properties_field['position_x']) + width_part)) + 'px'
1045
1046 # processing last field
1047 field_dict[3] = {}
1048 field_dict[3]['width'] = str(scaling_factor1*float(width_part*2)) + 'px'
1049 field_dict[3]['margin-left'] = \
1050 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*2)) + 'px'
1051 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 field_dict[1]['width'] = str(scaling_factor1*float(width_part *2)) + 'px'
1058 field_dict[1]['margin-left'] = \
1059 str(scaling_factor1 *float(properties_field['position_x'])) + 'px'
1060
1061 # processing second field (two digits only)
1062 field_dict[2] = {}
1063 field_dict[2]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1064 field_dict[2]['margin-left'] = \
1065 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*2)) + 'px'
1066
1067 # processing day field
1068 field_dict[3] = {}
1069 field_dict[3]['width'] = str(scaling_factor1*float(width_part)) + 'px'
1070 field_dict[3]['margin-left'] = \
1071 str(scaling_factor1 *(float(properties_field['position_x']) + width_part*3)) + 'px'
1072
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
1129
1130 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
1148 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
1197 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
1208
1209 class ScribusParser:
1210 """
1211 Parses a Scribus file (pda) with PDF-elements inside
1212 """
1213 #declare security
1214 security = ClassSecurityInfo()
1215
1216 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
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 """
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 security.declarePublic('getXmlObjectPropertiesDict')
1244 def getXmlObjectsPropertiesDict(self, xml_string):
1245 """
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
1251 # Create DOM tree from the xml string
1252 print " > create DOM tree"
1253 dom_tree = minidom.parseString(xml_string)
1254
1255 # creating the root from the input file
1256 dom_root = dom_tree.documentElement
1257
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
1275 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
1280 #making a listing of all the PAGE objects
1281 print " > making listing of all PAGE objects"
1282 page_list = dom_root.getElementsByTagName("PAGE")
1283
1284 returned_page_dict = {}
1285
1286 #for each PAGE object, searching for PAGEOBJECT
1287 for page in page_list:
1288
1289 # 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
1295 print " > PAGE NUM=" + str(page_number)
1296
1297 # making a listing of all PAGEOBJECT in a specified PAGE
1298 page_object_list = page.getElementsByTagName("PAGEOBJECT")
1299
1300 # initialising global output dictionary containing pages of elements
1301 returned_page_object_list = []
1302
1303 # for each PAGEOBJECT, building dict with atributes
1304 for page_object in page_object_list:
1305
1306 # initialising
1307 returned_page_object = {}
1308 field_name = ''
1309
1310 #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 returned_page_object[node_name] = node_value
1317
1318 if node_name == 'ANNAME':
1319 if node_value != '':
1320 field_name = node_value.replace(' ','_')
1321
1322 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
1328 #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
1334 print "=> end ScribusParser.getXmlObjectPropertiesDict"
1335 return (returned_page_dict,keep_page,0)
1336
1337 # end parsing document version 1.2.*
1338
1339 else:
1340 print " found Scribus Doucment format 1.3"
1341 # assuming version is compliant with 1.3.* specifications
1342
1343 keep_page = 1
1344
1345 # 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 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 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 """
1403 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 'ANTOOLTIP' attribute.
1408
1409 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
1418 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
1425 # declaring ScribusParser object to run other functions
1426 sp = ScribusParser()
1427
1428 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
1434 print " => PAGE = %s" % str(page_number)
1435
1436 # 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
1443 # declaring output object
1444 returned_object_dict = {}
1445
1446 # if page_content.haskey('my_fax_field')
1447 # print "my_fax_field"
1448 for object_data in page_content:
1449 # iterating through 'PAGEOBJECT' of the page
1450 # id = object_name
1451 # content = object_content
1452
1453 object_name = object_data['ANNAME']
1454 del object_data['ANNAME']
1455 object_content = object_data
1456 multiline_field= 0
1457 #multiline_field= object_content['ANFLAG']
1458 print " => PAGEOBJECT = " + str(object_name)
1459 # recovering other attributes list (string format) from 'ANTOOLTIP'
1460 text_tooltipfield_properties = \
1461 sp.getObjectTooltipProperty('ANTOOLTIP','',object_name,object_content)
1462 #recovering the page attributes
1463
1464 #declaring output file
1465 tooltipfield_properties_dict = {}
1466 #splitting the different attributes
1467 tooltipfield_properties_list = \
1468 text_tooltipfield_properties.split('#')
1469
1470 print " " + str(tooltipfield_properties_list)
1471
1472 # test if first argument is nb according to previous
1473 # naming-conventions i.e composed of three digits without
1474 # id 'nb:' written
1475 if str(tooltipfield_properties_list[0]).isdigit():
1476 # first value of tooltilfield is digit : assuming this is
1477 # a creation-order information compliant with the previous
1478 # naming convention
1479 # modifying this field to make it compatible with new convention
1480 print " => first element = " + \
1481 str(tooltipfield_properties_list[0] + " is digit...")
1482 LOG("WARNING : " + str(object_name),0,"out-of-date " \
1483 + "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 tooltipfield_properties_list.append( "nb:" + str(temp_nb))
1489 # 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 tooltipfield_properties_dict[tooltipfield_id] = \
1500 tooltipfield_value
1501 # end of 'ANTOOLTIP' parsing
1502
1503 # getting usefull attributes from scribus 'PAGEOBJECT
1504 #and 'ANTOOLTIP'
1505 #
1506 object_properties = {}
1507 page_properties = {}
1508 # getting object position and size
1509 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 '17',
1527 object_name,
1528 object_content)
1529
1530 # 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
1544 # getting object title
1545 # object title can only be user-specified in the 'tooltip' dict
1546 object_properties['title'] = \
1547 sp.getObjectTooltipProperty('title',
1548 object_name,
1549 object_name,
1550 tooltipfield_properties_dict)
1551
1552 # getting object order position for erp5 form
1553 temp_order = \
1554 sp.getObjectTooltipProperty('order',
1555 'none',
1556 object_name,
1557 tooltipfield_properties_dict)
1558
1559 if temp_order not in ['left','right']:
1560 # temp_order invalid
1561 # trying to get it from its position in original Scribus file
1562 if int(object_properties['position_x']) > 280.0 :
1563 temp_order = 'right'
1564 else :
1565 temp_order = 'left'
1566 object_properties['order'] = temp_order
1567
1568 # getting special ANFLAG sub-properties
1569 temp_ANFLAG = long(sp.getObjectTooltipProperty('ANFLAG',
1570 0,
1571 object_name,
1572 object_content))
1573 # 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 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 # substracting value
1589 temp_ANFLAG = temp_ANFLAG - long(def_noScroll)
1590 # 'do not scroll' field
1591 # adding property
1592 anflag_properties['noscroll'] = 1
1593 if temp_ANFLAG - long(def_noSpellCheck) >= 0:
1594 temp_ANFLAG = temp_ANFLAG - long(def_noSpellCheck)
1595 # 'do not spell check' field
1596 anflag_properties['noSpellCheck'] = 1
1597 if temp_ANFLAG - long(def_editable) >= 0:
1598 temp_ANFLAG = temp_ANFLAG - long(def_editable)
1599 # 'editable' field
1600 anflag_properties['editable'] = 1
1601 if temp_ANFLAG - long(def_password) >= 0:
1602 temp_ANFLAG = temp_ANFLAG - long(def_password)
1603 # 'password' field
1604 anflag_properties['password'] = 1
1605 if temp_ANFLAG - long(def_multiLine) >= 0:
1606 temp_ANFLAG = temp_ANFLAG - long(def_multiLine)
1607 # 'multiline' field
1608 anflag_properties['multiline'] = 1
1609 if temp_ANFLAG - long(def_noExport) >= 0:
1610 temp_ANFLAG = temp_ANFLAG - long(def_noExport)
1611 # 'do not export data' field
1612 anflag_properties['noExport'] = 1
1613 if temp_ANFLAG - long(def_required) >= 0:
1614 temp_ANFLAG = temp_ANFLAG - long(def_required)
1615 # 'required field
1616 anflag_properties['required'] = 1
1617 if temp_ANFLAG == long(def_readOnly):
1618 # 'read only" field
1619 anflag_properties['readOnly'] = 1
1620
1621 # getting maximum number of caracters the field can hold
1622 # 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 print " => MaxInput = %s" % object_properties['maximum_input']
1638
1639 # getting object type :
1640 # first checking for user-specified type in 'tooltip' properties
1641 if tooltipfield_properties_dict.has_key('type'):
1642 # 'type' id in tooltip : using it and ignoring other 'type'
1643 # information in scribus properties
1644 object_properties['type'] = tooltipfield_properties_dict['type']
1645 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 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 # 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 object_properties['type'] = 'StringField'
1696 print " type = " + str(object_properties['type'])
1697
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 # getting 'required' property
1714 # 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
1722 # getting type properties for special types
1723 object_properties['rendering'] = 'single'
1724 # Stringfields handle properties
1725 # 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 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 if str(object_properties['type']) == 'ListBox' :
1738 # 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 if str(object_properties['type']) == 'DateTimeField':
1746 # 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
1755 # 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
1779 # object is relationstringfield and needs some information
1780 if str(object_properties['type']) == 'RelationStringField':
1781 # 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
1804 # getting creation order from 'tooltip' properties
1805 # used to create ERP5 objects in a special order
1806 if tooltipfield_properties_dict.has_key('nb') and \
1807 str(tooltipfield_properties_dict['nb']).isdigit():
1808 # 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 print " =>'nb' property specified : using it"
1812 print " > len(list)=%s" % len(nb_property_nbkey_list)
1813 # 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
1844 # 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
1848 # 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 print " => 'nb' found for %s : %s" % (object_name,object_position)
1859
1860 # 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
1872 # 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
1876 # returning final dict containing all the modified data
1877 print " => end ScribusParser.getPropertiesConversion"
1878 return (returned_page_dict)
1879
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 global_properties['page_width']= 595
1894 global_properties['page_height']= 842
1895 # 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 security.declareProtected('Import/Export objects', 'getContentFile')
1994 def getContentFile(self, file_descriptor):
1995 """ Get file content """
1996 return file_descriptor.read()
1997 security.declareProtected('Import/Export objects', 'getFileOpen')
1998 def getFileOpen(self, file_descriptor):
1999 """ Get file content """
2000 return file_descriptor.open('r')
2001
2002 InitializeClass(ScribusParser)
2003 allow_class(ScribusParser)
2004
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