diff --git a/product/ERP5/Document/PDFTypeInformation.py b/product/ERP5/Document/PDFTypeInformation.py index a9a1aaccaeb9ffcaaff083d8d8f2a19a632743d0..132354af65f1fc03da02510fc2a33695957da4fc 100644 --- a/product/ERP5/Document/PDFTypeInformation.py +++ b/product/ERP5/Document/PDFTypeInformation.py @@ -1,6 +1,8 @@ +# -*- coding: utf-8 -*- ############################################################################## -# # Copyright (c) 2002-2007 Nexedi SARL and Contributors. All Rights Reserved. +# Mayoro DIAGNE <mayoro@nexedi.com> +# Guy Osvald <guy@nexedi.com> # # WARNING: This program as such is intended to be used by professional # programmers who take the whole responsability of assessing all potential @@ -25,9 +27,383 @@ # ############################################################################## +import StringIO from AccessControl import ClassSecurityInfo -from Products.ERP5Type import Permissions +from Products.ERP5Type.Cache import CachingMethod +from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type.ERP5Type import ERP5TypeInformation +from Products.ERP5Form.Form import ERP5Form +from Products.ERP5Form.PDFForm import PDFForm +from Products.ERP5Form.ScribusParser import ScribusParser +from Products.ERP5Form.PDFParser import PDFParser +from OFS.DTMLDocument import DTMLDocument +from Products.ERP5Type.Utils import convertToUpperCase +from Products.ERP5Type.Core.ActionInformation import CacheableAction + +import md5 + +def getPropertiesCSSDict(parsed_scribus + , page_gap + , image_width + , image_height + , scribus_width + , scribus_height + , space_between_pages): + """ + recover all CSS data relative to the current page_object (field) + and save these informations in the output dict + """ + #image_width = 800 + scaling_factor = min(float(image_width)/scribus_width, + float(image_height)/scribus_height) + properties_css_dict = {} + properties_css_dict['head'] = {} + properties_css_dict['standard'] = {} + properties_css_dict['error'] = {} + properties_css_dict['err_d'] = {} + pages = range(len(parsed_scribus)) + for page in pages: + page_content = parsed_scribus[page] + page_id = "page_%s" % page + properties_css_page = {} + properties_css_pagediv = {} + properties_page = {} + properties_css_page['position'] = 'relative' + # creating image class for background + properties_css_background = {} + # making background id + background_id = page_id + '_background' + # making page div id + pagediv_id = page_id + ' div' + #getting properties + properties_css_background['position'] = 'absolute' + #creating corresponding page group to form + if page == 0: + # margin-top = 0 (first page) + properties_css_page['margin-top'] = "%spx" % (0) + else: + properties_css_page['margin-top'] = "%spx" % (40) + + properties_css_page['margin'] = "0 auto 20px 0" + properties_css_page['border-color'] = "#CCCCCC" + properties_css_page['border-'] = "dotted none none" + properties_css_page['border-'] = "1px 0pt 0pt" + properties_css_page['border'] = "1px solid #999999" + + properties_css_pagediv['background'] = "transparent" + properties_css_pagediv['border'] = "0" + + # set width and height on page block + properties_css_page['width'] = str (image_width) + 'px' + properties_css_page['height'] = str (image_height) + 'px' + properties_page['actual_width'] = scribus_width + properties_page['actual_height'] = scribus_height + properties_css_background['height'] = str(image_height) + 'px' + properties_css_background['width'] = str (image_width) + 'px' + # adding properties dict to global dicts + properties_css_dict['head'][page_id] = properties_css_page + properties_css_dict['head'][background_id] = properties_css_background + properties_css_dict['head'][pagediv_id] = properties_css_pagediv + for field_name, properties_field in page_content: + properties_field['position_y'] = \ + str(float(properties_field['position_y']) - \ + (scribus_height + page_gap)* page) + + # Processing object for CSS data + # declaring dict containing all css data + # _stand for general display + field_dict = {} + properties_css_object_stand = {} + # _error when an error occurs + properties_css_object_error = {} + # _err_d to diplay the text error + properties_css_object_err_d = {} + #defining global properties + properties_css_object_stand['position'] = 'absolute' + properties_css_object_error['position'] = 'absolute' + properties_css_object_err_d['position'] = 'absolute' + properties_css_object_stand['padding'] = '0px' + properties_css_object_error['padding'] = '0px' + properties_css_object_err_d['padding'] = '0px' + # getting field height + properties_css_object_stand['height'] = \ + str(scaling_factor * float(properties_field['size_y'])) + 'px' + properties_css_object_error['height'] = \ + str(scaling_factor * float(properties_field['size_y'])) + 'px' + # defining font-size from height - 2 (this value seems to have a good + # rendering on Mozilla and Konqueror) + # do not match for TextArea (as it is a multiline object) + type_list = ['TextAreaField', 'MultiListField', 'EditorField'] + type_list += ['ListBox', 'ImageField', 'MatrixBox'] + #if properties_field['type'] not in type_list: + #if float(properties_field['size_y']) > 8.0: + #properties_css_object_stand['font-size'] = \ + #str((scaling_factor *float(properties_field['size_y']))-5.5 ) + 'px' + #properties_css_object_error['font-size'] = \ + #str((scaling_factor *float(properties_field['size_y']))-5.5) + 'px' + #else: + #properties_css_object_stand['font-size'] = \ + #str((scaling_factor *float(properties_field['size_y']))-3.5 ) + 'px' + #properties_css_object_error['font-size'] = \ + #str((scaling_factor *float(properties_field['size_y']))-3.5) + 'px' + #else: + #properties_css_object_stand['font-size'] = '12px' + #properties_css_object_error['font-size'] = '12px' + + # Use default font-size 12px for harmonization + properties_css_object_stand['font-size'] = '12px' + properties_css_object_error['font-size'] = '12px' + + properties_css_object_err_d['margin-left'] = str(image_width + + space_between_pages ) + 'px' + properties_css_object_err_d['white-space'] = 'nowrap' + properties_css_object_stand['margin-top'] = \ + str((scaling_factor *float(properties_field['position_y']))) + 'px' + properties_css_object_error['margin-top'] = \ + str((scaling_factor *float(properties_field['position_y']))) + 'px' + properties_css_object_err_d['margin-top'] = \ + str((scaling_factor *float(properties_field['position_y']))) + 'px' + # adding special text_color for text error + properties_css_object_err_d['color'] = 'rgb(255,0,0)' + # then getting additional properties + if properties_field['required'] ==1: + # field is required: using special color + # color is specified as light-blue when standard + # color = 'green' when error + properties_css_object_stand['background'] = 'rgb(236,245,220)' + properties_css_object_error['background'] = 'rgb(128,128,255)' + elif properties_field['type'] != 'TextAreaField': + properties_css_object_stand['background'] = '#F5F5DC' + properties_css_object_error['background'] = 'rgb(255,64,64)' #Previously, + #B9D9D4 - should become a parameter + else: + properties_css_object_stand['background'] = '#F5F5DC' # Previously, + #B9D9D4 - should become a parameter + properties_css_object_error['background'] = 'rgb(255,64,64)' + + # add completed properties (in our case only the class rendering the text + # beside an error) to the return dict + properties_css_dict['err_d'][field_name] = properties_css_object_err_d + # the following variable take the number of field to render for this object + field_nb = 1 + # now processing special rendering + if properties_field['rendering']=='single': + # single rendering (like StringField, TextArea, etc.). + # Do not need any special treatment + properties_css_object_stand['width'] = \ + str(scaling_factor * float(properties_field['size_x'])) + 'px' + properties_css_object_error['width'] = \ + str(scaling_factor * float(properties_field['size_x'])) + 'px' + properties_css_object_stand['margin-left'] = \ + str((scaling_factor * float(properties_field['position_x']))) + 'px' + properties_css_object_error['margin-left'] = \ + str((scaling_factor * float(properties_field['position_x']))) + 'px' + field_id = field_name + '_class' + # adding all these properties to the global dicts + properties_css_dict['standard'][field_id] = properties_css_object_stand + properties_css_dict['error'][field_id] = properties_css_object_error + else: + sub_field_dict = {} + field_dict = {} + if properties_field['type'] == 'RelationStringField': + # rendering a relationStringField, based on two input areas + # processing rendering of the two input fields. for that + # each has to be evaluated and the values will be saved in + # a dict + # uptading number of fields to render + field_nb = 2 + #field_1 = field_name + '_class_1' + # processing main StringField + field_dict[1] = {} + field_dict[1]['width'] = \ + str(scaling_factor*(float(properties_field['size_x']) / 2)) + 'px' + field_dict[1]['margin-left'] = \ + str(scaling_factor*float(properties_field['position_x'])) + 'px' + # processing secondary input picture + field_dict[2] = {} + field_dict[2]['width'] = \ + str(scaling_factor(float(properties_field['size_x']) /2)) + 'px' + field_dict[2]['margin-left'] = \ + str(scaling_factor(float(properties_field['size_x']) /2 +\ + float(properties_field['position_x']))) + 'px' + elif properties_field['type'] == 'DateTimeField': + # rendering DateTimeField, composed at least of three input + # areas, and their order can be changed + # getting the number of fields to render and their size unit + if properties_field['date_only'] == '0': + field_nb = 5 + # defining counting unit for fields + # total = 6.1 units: + # 2 > year + # 1 > month + # 1 > day + # 0.1 > space between date and time + # 1 > hour + # 1 > minutes + width_part = int(float(properties_field['size_x']) / 6.1) + else: + field_nb = 3 + # same as before but without hours and minutes + width_part = int((float(properties_field['size_x']) / 4)) + # defining global field rendering (for Date), ignoring for the moment + # the whole part about the time + # this following field refere to no existing field, it's use only + # when editable property is unchecked (there is only one field + # without _class_N but just _class, so, the 3 existing CSS selector + # can't be applied, that the reason for this new one) + field_dict[0] = {} + field_dict[0]['width'] = \ + str(scaling_factor*float(width_part*(field_nb+1))) + 'px' + field_dict[0]['margin-left'] = \ + str(scaling_factor *float(properties_field['position_x'])) + 'px' + + if properties_field['input_order'] in \ + ['day/month/year', 'dmy', 'dmY', 'month/day/year', 'mdy', 'mdY']: + # specified input order. must be dd/mm/yyyy or mm/dd/yyyy (year is + # the last field). + # processing first field + field_dict[1] = {} + field_dict[1]['width'] = str(scaling_factor*float(width_part)) + \ + 'px' + field_dict[1]['margin-left'] = \ + str(scaling_factor *float(properties_field['position_x'])) + 'px' + # processing second field + field_dict[2] = {} + field_dict[2]['width'] = str(scaling_factor*float(width_part)) + \ + 'px' + field_dict[2]['margin-left'] = \ + str(scaling_factor *(float(properties_field['position_x']) + \ + width_part)) + 'px' + # processing last field + field_dict[3] = {} + field_dict[3]['width'] = str(scaling_factor*float(width_part*2)) + \ + 'px' + field_dict[3]['margin-left'] = \ + str(scaling_factor *(float(properties_field['position_x']) + \ + width_part*2)) + 'px' + else: + # all other cases, including default one (year/month/day) + width_part = int(int(properties_field['size_x']) / 4) + # processing year field + field_dict[1] = {} + field_dict[1]['width'] = str(scaling_factor*float(width_part *2)) +\ + 'px' + field_dict[1]['margin-left'] = \ + str(scaling_factor *float(properties_field['position_x'])) + 'px' + # processing second field (two digits only) + field_dict[2] = {} + field_dict[2]['width'] = str(scaling_factor*float(width_part)) + \ + 'px' + field_dict[2]['margin-left'] = \ + str(scaling_factor *(float(properties_field['position_x']) + \ + width_part*2)) + 'px' + # processing day field + field_dict[3] = {} + field_dict[3]['width'] = str(scaling_factor*float(width_part)) + \ + 'px' + field_dict[3]['margin-left'] = \ + str(scaling_factor *(float(properties_field['position_x']) + \ + width_part*3)) + 'px' + # rendering time if necessary + if properties_field['date_only'] == '0': + # date is specified + field_dict[4] = {} + field_dict[4]['width'] = str(width_part) + 'px' + field_dict[4]['margin-left'] = \ + str(int(properties_field['position_x']) +\ + int(properties_field['size_x']) - width_part*2) + 'px' + field_dict[5] = {} + field_dict[5]['width'] = str(width_part) + 'px' + field_dict[5]['margin-left'] = \ + str(int(properties_field['position_x']) +\ + int(properties_field['size_x']) - width_part) + 'px' + + field_nb_range = field_nb + 1 + field_range = range(field_nb_range) + for iterator in field_range: + # iterator take the field_id according to the field_nb + # ie (0..field_nb) + #iterator = it + 1 + if iterator == 0: + class_name = field_name + '_class' + else: + class_name = field_name + '_class_' + str(iterator) + # managing standard class properties + properties_css_dict['standard'][class_name] = {} + for prop_id in properties_css_object_stand.keys(): + # saving global class properties into final dict + properties_css_dict['standard'][class_name][prop_id] = \ + properties_css_object_stand[prop_id] + for prop_id in field_dict[iterator].keys(): + # then adding special field properties (usually width and position_x) + properties_css_dict['standard'][class_name][prop_id] = \ + field_dict[iterator][prop_id] + # managing class error properties + properties_css_dict['error'][class_name] = {} + for prop_id in properties_css_object_error.keys(): + properties_css_dict['error'][class_name][prop_id] = \ + properties_css_object_error[prop_id] + for prop_id in field_dict[iterator].keys(): + properties_css_dict['error'][class_name][prop_id] = \ + field_dict[iterator][prop_id] + + properties_css_page = {} + properties_css_page['position'] = 'relative' + properties_css_page['margin-top'] = "%spx" % str(space_between_pages) + properties_css_dict['head']['page_end'] = properties_css_page + return properties_css_dict + +def generateCSSOutputContent(properties_css_dict): + """ + return a string containing the whole content of the CSS output + from properties_css_dict + """ + form_css_content = "/*-- special css form generated through ScribusUtils"\ + "module --*/\n" + form_css_content += "/*-- to have a graphic rendering with 'form_html' "\ + "page template --*/\n\n" + form_css_content += "/* head : classes declared for general purpose */\n" + # iterating classes in document's head + for class_name in properties_css_dict['head'].keys(): + # getting class properties_dict + class_properties = properties_css_dict['head'][class_name] + # joining exerything + output_string = "." + str(class_name) + " {" \ + + "; ".join(["%s:%s" % (id, val) for id, + val in class_properties.items()]) \ + + "}" + # adding current line to css_content_object + form_css_content += output_string + "\n" + form_css_content += "\n/* standard field classes */ \n" + # adding standard classes + for class_name in properties_css_dict['standard'].keys(): + class_properties = properties_css_dict['standard'][class_name] + output_string = "." + str(class_name) + " {" \ + + "; ".join(["%s:%s" % (id, val) for id, + val in class_properties.items()]) \ + + "}" + form_css_content += output_string + "\n" + form_css_content += "\n/* error field classes */\n" + # adding error classes + for class_name in properties_css_dict['error'].keys(): + class_properties = properties_css_dict['error'][class_name] + output_string = "." + str(class_name) + "_error {" \ + + "; ".join(["%s:%s" % (id, val) for id, + val in class_properties.items()]) \ + + "}" + form_css_content += output_string + "\n" + form_css_content += "\n/* text_error field classes */ \n" + # adding field error classes + for class_name in properties_css_dict['err_d'].keys(): + class_properties = properties_css_dict['err_d'][class_name] + output_string = "." + str(class_name) + "_error_display {" \ + + "; ".join(["%s:%s" % (id, val) for id, + val in class_properties.items()]) \ + + "}" + form_css_content += output_string + "\n" + # return final String + return form_css_content + class PDFTypeInformation(ERP5TypeInformation): """ @@ -40,7 +416,369 @@ class PDFTypeInformation(ERP5TypeInformation): # CMF Type Definition meta_type = 'ERP5 PDF Type Information' portal_type = 'PDF Type' + isPortalContent = 1 + isRADContent = 1 + + property_sheets = ( PropertySheet.PDFType, ) # Declarative security security = ClassSecurityInfo() security.declareObjectProtected(Permissions.AccessContentsInformation) + + security.declareProtected(Permissions.View, 'renderForm') + def renderForm(self, context): + """ + """ + form = self.getERP5Form() + return form.__of__(context)() + + security.declareProtected(Permissions.View, 'renderPDFForm') + def renderPDFForm(self, context): + """ + """ + form = self.getPDFForm() + return form.__of__(context)() + + security.declareProtected(Permissions.View, 'renderFormImage') + def renderFormImage(self, REQUEST, RESPONSE, page): + """ + """ + return self.getERP5FormImage(page).index_html(REQUEST, RESPONSE) + + security.declareProtected(Permissions.View, 'renderFormCSS') + def renderFormCSS(self): + """ + """ + return self.getERP5FormCSS() + + def _getParsedScribusFile(self): + """ + Returns a reusable data structure which can + be used to generate ERP5 Form, ERP5 Form CSS, + PDF Form, etc. + """ + scribus_form = self.getDefaultScribusFormValue() + if scribus_form is None: + return + + def generateParsedScribus(): + import_scribus_file = StringIO.StringIO(scribus_form.getData()) + scribus_parser = ScribusParser(import_scribus_file) + import_scribus_file.close() + return scribus_parser.getERP5PropertyDict() + generateParsedScribus = CachingMethod(generateParsedScribus, + ('PDFTypeInformation_generateParsedScribus', + md5.new(scribus_form.getData()).digest()), + cache_factory='dms_cache_factory') + return generateParsedScribus() + + def getERP5Form(self): + """ + Returns an ERP5 Form instance (stored in RAM) + """ + if self.getDefaultScribusFormValue() is None: + return + + def generateERP5Form(): + form_name = "view" + form = ERP5Form(form_name, self.getId()) + parsed_scribus = self._getParsedScribusFile() + pages = range(len(parsed_scribus)) + #get the context for default values + context = None + context_parent = self.aq_parent + if context_parent is not None: + context = context_parent.aq_parent + for page in pages: + page_content = parsed_scribus[page] + group_id = page_id = "page_%s" % page + if page != 0: + group = form.add_group(group_id) + for field_name, fields_values in page_content: + field_id = field_name + field_title = fields_values["title"] + field_order = fields_values["order"] + field_erp5_order = fields_values["nb"] + field_type = fields_values["type"] + field_required = fields_values["required"] + field_editable = fields_values["editable"] + field_rendering = fields_values["rendering"] + field_size_x = fields_values["size_x"] + field_size_y = fields_values["size_y"] + field_position_x = fields_values["position_x"] + field_position_y = fields_values["position_y"] + old_group='left' + # creating new field in form + if field_type in ['ListField', 'MultiListField']: + field = form.manage_addField(field_id, + field_title, + 'ProxyField') + field = form[field_name] + field.values['form_id'] = 'Base_viewFieldLibrary' + if field_type == 'ListField': + field.values['field_id'] = 'my_list_field' + else: + field.values['field_id'] = 'my_multi_list_field' + # ne pas d茅l茅guer les propri茅t茅s items et default + field.delegated_list += ('items', 'default') + field.manage_tales_xmlrpc({"items": + "python: here.EGov_getCategoryChildItemListByFieldName('%s')"\ + % field_id}) + field.manage_tales_xmlrpc({"default": + "python: here.getProperty('%s')" % field_id[3:]}) + elif field_type == 'DateTimeField': + field = form.manage_addField(field_id, + field_title, + 'ProxyField') + field = form[field_name] + field.values['form_id'] = 'Base_viewFieldLibrary' + field.values['field_id'] = 'my_date' + field.delegated_list += ('default',) + field.manage_tales_xmlrpc({"default": + "python: here.getProperty('%s')" % field_id[3:]}) + else: + field = form.manage_addField(field_id, + field_title, + field_type) + + field = form[field_name] + + field.values['required'] = field_required + field.values['editable'] = field_editable + + if page != 0: + # move fields to destination group + form.move_field_group(field_id, + old_group, + group_id) + + + default_groups = ['right', 'center', 'bottom', 'hidden'] + old_group='left' + group_id = 'page_0' + form.rename_group(old_group, group_id) + # remove all other groups: + for existing_group in default_groups: + form.remove_group(existing_group) + # updating form settings + # building dict containing (property, value) + values = {} + values['title'] = self.getId() + values['row_length'] = 4 + values['name'] = form_name + values['pt'] = "form_render_PDFeForm" + values['action'] = "PDFDocument_edit" + values['update_action'] = "" + values['method'] = 'POST' + values['enctype'] = 'multipart/form-data' + values['encoding'] = "UTF-8" + values['stored_encoding'] = 'UTF-8' + values['unicode_mode'] = 0 + #values['getBackgroundUrl'] = self.getBackgroundUrl(page) + #values['getCSSUrl'] = self.getCSSUrl() + + values['getBackgroundUrl'] = lambda page: \ + 'portal_types/%s/renderFormImage?page=%s' % (self.getId(), page) + values['getCSSUrl'] = lambda: 'portal_types/%s/renderFormCSS' % self.getId() + + # using the dict declared just above to set the attributes + for key, value in values.items(): + setattr(form, key, value) + return form + #generateERP5Form = CachingMethod(generateERP5Form, + # ('PDFTypeInformation_generateERP5Form', + # md5.new(self.getDefaultScribusFormValue().getData()).digest()), + # cache_factory='erp5_ui_long') + return generateERP5Form().__of__(self) + + # XXX criticize ERP5.Document.Image + # (we are forced to use xlarge preference) + def getWidth(self): + portal_preferences = self.getPortalObject().portal_preferences + return portal_preferences.getPreferredXlargeImageWidth() + + def getHeight(self): + portal_preferences = self.getPortalObject().portal_preferences + return portal_preferences.getPreferredXlargeImageHeight() + + + def getERP5FormCSS(self): + """ + Returns a CSS file containing all layout instructions + """ + if self.getDefaultScribusFormValue() is None: + return + def generateERP5FormCSS(): + parsed_scribus = self._getParsedScribusFile() + import_pdf_file = StringIO.StringIO(self.getDefaultPdfFormValue().getData()) + pdf_parser = PDFParser(import_pdf_file) + import_scribus_file = StringIO.StringIO(self.getDefaultScribusFormValue().getData()) + scribus_parser = ScribusParser(import_scribus_file) + page_gap = scribus_parser.getPageGap() + scribus_width = scribus_parser.getPageWidth() + scribus_height = scribus_parser.getPageHeight() + space_between_pages = 20 # XXX - hardcoded + image0 = self.getERP5FormImage(0) + properties_css_dict=getPropertiesCSSDict(parsed_scribus, + page_gap, + image0.getWidth(), + image0.getHeight(), + scribus_width, + scribus_height, + space_between_pages) + # declaring object that holds the CSS data + css_file_name = "%s_css.css" % self.getId().replace(' ','') + css_file_content = generateCSSOutputContent(properties_css_dict) + css_file = DTMLDocument(css_file_content, __name__ = css_file_name) + import_scribus_file.close() + import_pdf_file.close() + return css_file + + generateERP5FormCSS = CachingMethod(generateERP5FormCSS, + ('PDFTypeInformation_generateERP5FormCSS', + md5.new(self.getDefaultScribusFormValue().getData()).digest()), + cache_factory='dms_cache_factory') + self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/css') + return generateERP5FormCSS() + + + def getERP5FormImage(self, page): + """ + Returns the background image for a given page + """ + from Products.ERP5Type.Document import newTempImage + import_pdf_file = self.getDefaultPdfFormValue() + #depend on preferences, best xlargeheight = 1131 + mime, image_data = import_pdf_file.convert(format = 'jpg', + frame = page, + resolution = self.getResolution(), + quality = 600, + display = 'xlarge') + if image_data is None: + return + page_image = newTempImage(self, "page_%s" % page) + page_image.setData(image_data) + self.REQUEST.RESPONSE.setHeader('Content-Type', mime) + return page_image + + def getPDFForm(self): + """ + Returns an PDF Form instance (stored in RAM) + """ + if self.getDefaultScribusFormValue() is None: + return + portal_type_name = self.getId().replace(' ','') + pdf_form_name ='%s_view%sAsPdf' % (portal_type_name, portal_type_name) + pdf_file = StringIO.StringIO(self.getDefaultPdfFormValue().getData()) + pdf_form = PDFForm(pdf_form_name, portal_type_name, pdf_file) + pdf_form.manage_upload(pdf_file) + import_scribus_file = StringIO.StringIO(self.getDefaultScribusFormValue().getData()) + scribus_parser = ScribusParser(import_scribus_file) + erp5_properties = scribus_parser.getERP5PropertyDict() + def_usePropertySheet = 0 + my_prefix = 'my_' + prefix_len = len(my_prefix) + pages = range(len(erp5_properties)) + for page in pages: + page_content = erp5_properties[page] + for cell_name, field_dict in page_content: + # current object is PDF Form + if cell_name[:prefix_len] == my_prefix: + cell_process_name_list = [] + suffix = cell_name[prefix_len:].split('_')[-1] + # If properties field are filled in scribus, get Type form + # global_properties. Else, guess Type by suffix id (eg: List, Date,...) + list_field_type_list = ('ListField', 'MultiListField', 'LinesField',) + date_field_type_list = ('DateTimeField',) + suffix_mapping = {'List' : list_field_type_list, + 'Date' : date_field_type_list} + field_type = field_dict.get('erp_type', suffix_mapping.get(suffix, [''])[0]) + if def_usePropertySheet: + # generating PropertySheet and Document, no need to use them to + # get field data + if field_type in list_field_type_list: + TALES = "python: %s " % ', '.join( + "here.get%s()" % convertToUpperCase(cell_name[prefix_len:])) + elif field_type in date_field_type_list: + attributes_dict = field_dict['attributes'] + # assign the property input_order + input_order = attributes_dict['input_order'] + input_order = input_order.replace('y', 'Y') + # make the Tales according to the cases + date_pattern = '/'.join(['%%%s' % s for s in list(input_order)]) + if not(attributes_dict['date_only']): + date_pattern += ' %H:%M' + TALES = "python: here.get%s() is not None and here.get%s().strftime('%s') or ''"\ + % (convertToUpperCase(cell_name[prefix_len:]), + convertToUpperCase(cell_name[prefix_len:]), + date_pattern) + else: + TALES = "python: here.get%s()" %\ + convertToUpperCase(cell_name[prefix_len:]) + else: + if field_type in list_field_type_list: + TALES = "python: %s" % ', '.join( + "here.getProperty('%s')" % cell_name[prefix_len:]) + elif field_type in date_field_type_list: + attributes_dict = field_dict['attributes'] + # assign the property input_order + input_order = attributes_dict['input_order'] + input_order = input_order.replace('y', 'Y') + # make the Tales according to the cases + date_pattern = '/'.join(['%%%s' % s for s in list(input_order)]) + if not(attributes_dict['date_only']): + date_pattern += ' %H:%M' + TALES = "python: here.getProperty('%s') is not None and here.getProperty('%s').strftime('%s') or ''"\ + % (cell_name[prefix_len:], + cell_name[prefix_len:], + date_pattern) + else: + TALES = "python: here.getProperty('%s')" % cell_name[prefix_len:] + pdf_form.setCellTALES(cell_name, TALES) + import_scribus_file.close() + pdf_file.close() + self.REQUEST.RESPONSE.setHeader('Content-Type', 'application/pdf') + return pdf_form + + + def getCacheableActionList(self): + portal_type_name = self.getId().replace(' ','') + pdf_form_name ='%s_view%sAsPdf' % (portal_type_name, portal_type_name) + action_list = ERP5TypeInformation.getCacheableActionList(self) + return list(action_list) + [ + CacheableAction(id='view', + name='Form', + description='', + category='object_view', + priority=1.1, + icon=None, + action='string:${object_url}/PDFType_viewDefaultForm', + condition=None, + permission_list=['View']), + CacheableAction(id=pdf_form_name, + name='PDF Form', + description='', + category='object_print', + priority=3.0, + icon=None, + action='string:${object_url}/PDFType_viewAsPdf', + condition=None, + permission_list=['View']), + ] + + def updatePropertySheetDefinitionDict(self, definition_dict, **kw): + if self.getDefaultScribusFormValue() is None: + return + if '_properties' in definition_dict: + parsed_scribus = self._getParsedScribusFile() + for page_content in parsed_scribus.itervalues(): + for field_name, fields_values in page_content: + field_id = field_name + field_type = fields_values["data_type"] + definition_dict['_properties'].append({'id':field_name[3:], + 'type':field_type, + 'mode':'w'}) + ERP5TypeInformation.updatePropertySheetDefinitionDict(self, definition_dict) + + +