Commit 68d8f3f7 authored by Thomas Bernard's avatar Thomas Bernard

improved code

handle exceptions and errors during process, and display explicit error origin



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@7574 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 4b344a77
...@@ -36,7 +36,6 @@ from Products.PythonScripts.Utility import allow_class ...@@ -36,7 +36,6 @@ from Products.PythonScripts.Utility import allow_class
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Globals import InitializeClass from Globals import InitializeClass
from Form import BasicForm from Form import BasicForm
from Products.Formulator.Field import ZMIField from Products.Formulator.Field import ZMIField
from Products.Formulator.DummyField import fields from Products.Formulator.DummyField import fields
...@@ -56,10 +55,12 @@ from Products.CMFCore.utils import getToolByName ...@@ -56,10 +55,12 @@ from Products.CMFCore.utils import getToolByName
from Products.ERP5Type.Utils import getPath from Products.ERP5Type.Utils import getPath
from Products.ERP5Type.Message import Message
class PlanningBoxValidator(Validator.StringBaseValidator): class PlanningBoxValidator(Validator.StringBaseValidator):
""" """
Class holding all methods used to validate a modified PlanningBox Class holding all methods used to validate a modified PlanningBox
can be called only from a HTML rendering using wz_dragdrop script can be called only from an HTML rendering using wz_dragdrop script
""" """
def validate(self,field,key,REQUEST): def validate(self,field,key,REQUEST):
""" """
...@@ -84,7 +85,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -84,7 +85,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
############## REBUILD STRUCTURE ################# ############## REBUILD STRUCTURE #################
################################################## ##################################################
# build structure # build structure
structure = PlanningBoxWidgetInstance.render_structure(field=field, key=key, value=value, REQUEST=REQUEST, here=here) structure = PlanningBoxWidgetInstance.render_structure(field=field,
key=key, value=value, REQUEST=REQUEST, here=here)
# getting coordinates script generator # getting coordinates script generator
planning_coordinates_method = getattr(here,'planning_coordinates') planning_coordinates_method = getattr(here,'planning_coordinates')
...@@ -98,17 +100,18 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -98,17 +100,18 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
block_moved_list = self.getBlockPositionFromString(block_moved_string) block_moved_list = self.getBlockPositionFromString(block_moved_string)
# block_moved_list now holds a list of structure recovered from the REQUEST # block_moved_list now holds a list of structure recovered from the REQUEST
# and correspondig to the movements done before validating # and correspondig to the movements done before validating
block_previous_list = self.getBlockPositionFromString(block_previous_string) block_previous_list =\
self.getBlockPositionFromString(block_previous_string)
# list of previous blocks moved if an error occured during previous # list of previous blocks moved if an error occured during previous
# validation # validation
# updating block_moved_list using block_previous_list. This is very important # updating block_moved_list using block_previous_list.
# not to escape processing blocks that have been moved during a previous # This is very important not to escape processing blocks that have been
# validation attempt. # moved during a previous validation attempt.
if block_previous_list != [] and block_moved_list != []: if block_previous_list != [] and block_moved_list != []:
for block_previous in block_previous_list: for block_previous in block_previous_list:
# checking if the block has been moved again in this validation attempt. # checking if the block has been moved again in this validation attempt
# if it is the case, the block must be also present in the current # if it is the case, the block must be also present in the current
# block_moved_list # block_moved_list
block_found = {} block_found = {}
...@@ -124,8 +127,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -124,8 +127,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
block_found['old_X'] = block_previous['old_X'] block_found['old_X'] = block_previous['old_X']
block_found['old_Y'] = block_previous['old_Y'] block_found['old_Y'] = block_previous['old_Y']
else: else:
# block has not been moved again, adding old block informations to the # block has not been moved again, adding old block informations to
# current list of block_moved # the current list of block_moved
block_moved_list.append(block_previous) block_moved_list.append(block_previous)
elif block_previous_list != []: elif block_previous_list != []:
# block_moved_list is empty but not block_previous_list. This means the # block_moved_list is empty but not block_previous_list. This means the
...@@ -143,11 +146,9 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -143,11 +146,9 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# dict aimed to hold all informations about block # dict aimed to hold all informations about block
final_block_dict = {} final_block_dict = {}
# dict holding all the activities that will need an update because at least
# dict holding all the activities that will need an update because at least one # one of the blocks concerned is moved
# of the blocks concerned is moved
activity_dict = {} activity_dict = {}
# list holding all the activities having one of their block not validated # list holding all the activities having one of their block not validated
# in such a case the update process of the activity is canceled # in such a case the update process of the activity is canceled
warning_activity_list = [] warning_activity_list = []
...@@ -164,13 +165,17 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -164,13 +165,17 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
for block_moved in block_moved_list: for block_moved in block_moved_list:
final_block = {} final_block = {}
# recovering the block object from block_moved informations # recovering the block object from block_moved informations
final_block['block_object'] = self.getBlockObject(block_moved['name'], structure.planning.content) final_block['block_object'] = self.getBlockObject(block_moved['name'], \
structure.planning.content)
# recovering original activity object # recovering original activity object
final_block['activity_origin'] = final_block['block_object'].parent_activity final_block['activity_origin'] = \
final_block['block_object'].parent_activity
# recovering original axis_group object # recovering original axis_group object
final_block['group_origin'] = final_block['activity_origin'].parent_axis_element.parent_axis_group final_block['group_origin'] = \
final_block['activity_origin'].parent_axis_element.parent_axis_group
# recovering relative block information in planning_coordinates # recovering relative block information in planning_coordinates
final_block['block_info'] = planning_coordinates['content'][block_moved['name']] final_block['block_info'] = \
planning_coordinates['content'][block_moved['name']]
# calculating delta # calculating delta
# block_moved holds coordinates recovered from drag&drop script, while # block_moved holds coordinates recovered from drag&drop script, while
...@@ -197,7 +202,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -197,7 +202,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
group_length = 'height' group_length = 'height'
# used afterwards to get secondary axis displacements and modifications # used afterwards to get secondary axis displacements and modifications
axis_length = 'width' axis_length = 'width'
else: else:
block_moved['main_axis_position'] = block_moved['left'] block_moved['main_axis_position'] = block_moved['left']
block_moved['main_axis_length'] = block_moved['width'] block_moved['main_axis_length'] = block_moved['width']
...@@ -208,12 +212,15 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -208,12 +212,15 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
axis_length = 'height' axis_length = 'height'
# calculating center of block over main axis to check block position # calculating center of block over main axis to check block position
block_moved['center'] = (block_moved['main_axis_length'] / 2) + block_moved['main_axis_position'] block_moved['center'] = (block_moved['main_axis_length'] / 2) + \
block_moved['main_axis_position']
# now that block coordinates are recovered as well as planning coordinates # now that block coordinates are recovered as well as planning
# recovering destination group over the main axis to know if the block has # coordinates, recovering destination group over the main axis to know
# been moved from a group to another # if the block has been moved from a group to another
group_destination = self.getDestinationGroup(structure, block_moved,planning_coordinates['main_axis'], group_position, group_length) group_destination = self.getDestinationGroup(structure,
block_moved,planning_coordinates['main_axis'],
group_position, group_length)
if group_destination == None: if group_destination == None:
# !! Generate an Error !! # !! Generate an Error !!
...@@ -229,7 +236,9 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -229,7 +236,9 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# now that all informations about the main axis changes are # now that all informations about the main axis changes are
# known, checking modifications over the secondary axis. # known, checking modifications over the secondary axis.
secondary_axis_positions = self.getDestinationBounds(structure, block_moved, final_block['block_object'], planning_coordinates, axis_length) secondary_axis_positions = self.getDestinationBounds(structure,
block_moved, final_block['block_object'],
planning_coordinates, axis_length)
if secondary_axis_positions[2] == 1 : if secondary_axis_positions[2] == 1 :
# !! Generate an Error !! # !! Generate an Error !!
# block has been moved outside the content area (bounds do not match # block has been moved outside the content area (bounds do not match
...@@ -259,8 +268,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -259,8 +268,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
################################################## ##################################################
update_dict = {} update_dict = {}
errors_list = [] errors_list = []
# getting start & stop property names # getting start & stop property names
start_property = structure.basic.field.get_value('x_start_bloc') start_property = structure.basic.field.get_value('x_start_bloc')
stop_property = structure.basic.field.get_value('x_stop_bloc') stop_property = structure.basic.field.get_value('x_stop_bloc')
...@@ -272,32 +279,27 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -272,32 +279,27 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
activity_block_moved_list = activity_dict[activity_name] activity_block_moved_list = activity_dict[activity_name]
# recovering activity object from first moved block # recovering activity object from first moved block
activity_object = activity_block_moved_list[0]['activity_origin'] activity_object = activity_block_moved_list[0]['activity_origin']
# now getting list of blocks related to the activity (moved or not) # now getting list of blocks related to the activity (moved or not)
activity_block_list = activity_object.block_list activity_block_list = activity_object.block_list
if activity_object.name in warning_activity_list: if activity_object.name in warning_activity_list:
# activity contains a block that has not be validated # activity contains a block that has not be validated
# The validation update process is canceled, and the error is reported # The validation update process is canceled, and the error is reported
err = ValidationError(StandardError,activity_object) err = ValidationError(StandardError,activity_object)
errors_list.append(err) errors_list.append(err)
pass pass
else: else:
# no error : continue # no error : continue
# recovering new activity bounds # recovering new activity bounds
(start_value, stop_value) = self.getActivityBounds(activity_object, (start_value, stop_value) = \
activity_block_moved_list, self.getActivityBounds(activity_object, activity_block_moved_list,
activity_block_list) activity_block_list)
# call specific external method to round value
# XXX call specific external method to round value in case hh:mn:s are useless
if round_script != None: if round_script != None:
start_value = round_script(start_value) start_value = round_script(start_value)
stop_value = round_script(stop_value) stop_value = round_script(stop_value)
# saving updated informations in the final dict
# saving updating informations in the final dict update_dict[activity_object.object.getUrl()] = \
update_dict[activity_object.object.getUrl()]={start_property:start_value, {start_property:start_value, stop_property:stop_value}
stop_property:stop_value}
# testing if need to raise errors # testing if need to raise errors
...@@ -319,8 +321,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -319,8 +321,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# - dict with error results # - dict with error results
raise FormValidationError(errors_list, {} ) raise FormValidationError(errors_list, {} )
# the whole process is now finished, just need to return final dict # the whole process is now finished, just need to return final dict
# for updating data
return update_dict return update_dict
...@@ -375,8 +377,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -375,8 +377,6 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
return block_string return block_string
def getBlockObject(self, block_name, content_list): def getBlockObject(self, block_name, content_list):
""" """
recover the block related to the block_name inside the content_list recover the block related to the block_name inside the content_list
...@@ -386,8 +386,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -386,8 +386,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
return block return block
def getDestinationGroup(self, structure, block_moved, axis_groups,
def getDestinationGroup(self, structure, block_moved, axis_groups, group_position, group_length): group_position, group_length):
""" """
recover destination group from block coordinates and main axis coordinates recover destination group from block coordinates and main axis coordinates
block_moved is a dict of properties. block_moved is a dict of properties.
...@@ -396,12 +396,14 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -396,12 +396,14 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
good_group_name = '' good_group_name = ''
# recovering group name # recovering group name
for axis_name in axis_groups.keys(): for axis_name in axis_groups.keys():
if axis_groups[axis_name][group_position] < block_moved['center'] and axis_groups[axis_name][group_position] + axis_groups[axis_name][group_length] > block_moved['center']: if axis_groups[axis_name][group_position] < block_moved['center'] and \
axis_groups[axis_name][group_position] + \
axis_groups[axis_name][group_length] > block_moved['center']:
# the center of the block is between group min and max bounds # the center of the block is between group min and max bounds
# the group we are searching for is known # the group we are searching for is known
good_group_name = axis_name good_group_name = axis_name
break break
# if no group is found, this means the block has been put outside the bounds # if no group is found, this means the block is outside the bounds
if good_group_name == '': if good_group_name == '':
return None return None
# group name is known, searching corresponding group object # group name is known, searching corresponding group object
...@@ -412,7 +414,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -412,7 +414,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
def getDestinationBounds(self, structure, block_moved, block_object, planning_coordinates, axis_length): def getDestinationBounds(self, structure, block_moved, block_object,
planning_coordinates, axis_length):
""" """
check the new bounds of the block over the secondary axis according to its check the new bounds of the block over the secondary axis according to its
new position new position
...@@ -423,8 +426,11 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -423,8 +426,11 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# implies that all groups have the same bounds, which is not the case in # implies that all groups have the same bounds, which is not the case in
# calendar mode. for that will need to add special informations about the # calendar mode. for that will need to add special informations about the
# group itself to know its own bounds. # group itself to know its own bounds.
delta_start = block_moved['secondary_axis_position'] / planning_coordinates['frame']['content'][axis_length] delta_start = block_moved['secondary_axis_position'] / \
delta_stop = (block_moved['secondary_axis_position'] + block_moved['secondary_axis_length']) / planning_coordinates['frame']['content'][axis_length] planning_coordinates['frame']['content'][axis_length]
delta_stop = (block_moved['secondary_axis_position'] + \
block_moved['secondary_axis_length']) / \
planning_coordinates['frame']['content'][axis_length]
# testing different cases of invalidation # testing different cases of invalidation
if delta_stop < 0 or delta_start > 1 : if delta_stop < 0 or delta_start > 1 :
...@@ -436,11 +442,14 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -436,11 +442,14 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# part of the block is inside # part of the block is inside
pass pass
axis_range = structure.basic.secondary_axis_info['bound_stop'] - structure.basic.secondary_axis_info['bound_start'] axis_range = structure.basic.secondary_axis_info['bound_stop'] - \
structure.basic.secondary_axis_info['bound_start']
# defining new final block bounds # defining new final block bounds
new_start = structure.basic.secondary_axis_info['bound_start'] + delta_start * axis_range new_start = structure.basic.secondary_axis_info['bound_start'] + \
new_stop = structure.basic.secondary_axis_info['bound_start'] + delta_stop * axis_range delta_start * axis_range
new_stop = structure.basic.secondary_axis_info['bound_start'] + \
delta_stop * axis_range
# update block bounds (round to the closest round day) # update block bounds (round to the closest round day)
...@@ -451,7 +460,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -451,7 +460,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
def getActivityBounds(self, activity, activity_block_moved_list, activity_block_list): def getActivityBounds(self, activity, activity_block_moved_list,
activity_block_list):
""" """
takes a list with modified blocks and another one with original blocks, takes a list with modified blocks and another one with original blocks,
returning new startactivity_block_moved_list & stop for the activity returning new startactivity_block_moved_list & stop for the activity
...@@ -459,7 +469,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -459,7 +469,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
value will not be updated (as the block was not on the real activity bound) value will not be updated (as the block was not on the real activity bound)
""" """
# getting list moved block names # getting list moved block names
block_moved_name_list = map(lambda x: x['block_moved']['name'], activity_block_moved_list) block_moved_name_list = map(lambda x: x['block_moved']['name'],
activity_block_moved_list)
for activity_block in activity_block_list: for activity_block in activity_block_list:
...@@ -470,8 +481,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator): ...@@ -470,8 +481,8 @@ class PlanningBoxValidator(Validator.StringBaseValidator):
# recovering corresponding moved block # recovering corresponding moved block
if temp_block_moved['block_moved']['name'] == activity_block.name: if temp_block_moved['block_moved']['name'] == activity_block.name:
# moved block has been found # moved block has been found
temp_start = temp_block_moved['block_moved']['secondary_axis_start'] temp_start =temp_block_moved['block_moved']['secondary_axis_start']
temp_stop = temp_block_moved['block_moved']['secondary_axis_stop'] temp_stop = temp_block_moved['block_moved']['secondary_axis_stop']
break break
else: else:
# the block has not been moved # the block has not been moved
...@@ -514,9 +525,11 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -514,9 +525,11 @@ class PlanningBoxWidget(Widget.Widget):
# number of groups over the main axis # number of groups over the main axis
'main_axis_groups', 'main_axis_groups',
# width properties # width properties
'size_border_width_left','size_planning_width','size_y_axis_space','size_y_axis_width', 'size_border_width_left','size_planning_width','size_y_axis_space',
'size_y_axis_width',
# height properties # height properties
'size_header_height', 'size_planning_height','size_x_axis_space','size_x_axis_height', 'size_header_height','size_planning_height','size_x_axis_space',
'size_x_axis_height',
# axis position # axis position
'y_axis_position', 'x_axis_position', 'y_axis_position', 'x_axis_position',
'report_root_list','selection_name', 'report_root_list','selection_name',
...@@ -527,11 +540,13 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -527,11 +540,13 @@ class PlanningBoxWidget(Widget.Widget):
# specific block properties # specific block properties
'x_start_bloc','x_stop_bloc', 'y_size_block', 'x_start_bloc','x_stop_bloc', 'y_size_block',
# name of scripts # name of scripts
'stat_method','split_method','color_script','round_script','sec_axis_script', 'stat_method','split_method','color_script',
'round_script','sec_axis_script',
# number of delimitations over the secondary axis # number of delimitations over the secondary axis
'delimiter', 'delimiter',
# specific methods for inserting info block # specific methods for inserting info block
'info_center', 'info_topleft','info_topright','info_backleft','info_backright' 'info_center','info_topleft','info_topright',
'info_backleft','info_backright'
] ]
""" """
...@@ -743,14 +758,16 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -743,14 +758,16 @@ class PlanningBoxWidget(Widget.Widget):
required=0) required=0)
round_script = fields.StringField('round_script', round_script = fields.StringField('round_script',
title='name of script rounding blocks during validation (ex. Planning_roundBoundToDay)', title='name of script rounding blocks during validation (ex.\
Planning_roundBoundToDay)',
description=('script for block bounds rounding when validating'), description=('script for block bounds rounding when validating'),
default='', default='',
required=0) required=0)
sec_axis_script = fields.StringField('sec_axis_script', sec_axis_script = fields.StringField('sec_axis_script',
title='name of script building secondary axis (ex. Planning_generateAxis)', title='name of script building secondary axis (ex.\
Planning_generateAxis)',
description=('script for building secondary axis'), description=('script for building secondary axis'),
default='Planning_generateAxis', default='Planning_generateAxis',
required=1) required=1)
...@@ -813,30 +830,28 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -813,30 +830,28 @@ class PlanningBoxWidget(Widget.Widget):
relative to the structure that need to be rendered relative to the structure that need to be rendered
""" """
# build structure
here = REQUEST['here'] here = REQUEST['here']
pdb.set_trace()
#pdb.set_trace() # build structure
structure = self.render_structure(field=field, key=key, value=value, REQUEST=REQUEST, here=here) # render_structure will call all method necessary to build the entire
# structure relative to the planning
# creates and fill up self.basic, self.planning and self.build_error_list
self.render_structure(field=field, key=key, value=value,
REQUEST=REQUEST, here=here)
if structure != None:
# getting CSS script generator # getting CSS script generator
planning_css_method = getattr(REQUEST['here'],'planning_css') planning_css_method = getattr(REQUEST['here'],'planning_css')
# recover CSS data buy calling DTML document
CSS_data = planning_css_method(structure=self)
# saving structure inside the request for HTML render
REQUEST.set('structure',self)
# recover CSS data buy calling DTML document return CSS_data
CSS_data = planning_css_method(structure=structure)
# saving structure inside the request to be able to recover it afterwards when needing
# to render the HTML code
REQUEST.set('structure',structure)
# return CSS data
return CSS_data
else:
REQUEST.set('structure',None)
return None
def render(self,field,key,value,REQUEST): def render(self,field,key,value,REQUEST):
""" """
...@@ -844,24 +859,21 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -844,24 +859,21 @@ class PlanningBoxWidget(Widget.Widget):
for that recover the structure previouly saved in the REQUEST, and then for that recover the structure previouly saved in the REQUEST, and then
call a special Page Template aimed to render call a special Page Template aimed to render
""" """
# need to test if render is HTML (to be implemented in a page template) # need to test if render is HTML (to be implemented in a page template)
# or list (to generated a PDF output or anything else). # or list (to generated a PDF output or anything else).
# recover structure # recover structure
structure = REQUEST.get('structure') structure = REQUEST.get('structure')
if structure != None:
#pdb.set_trace()
# getting HTML rendering Page Template
planning_html_method = getattr(REQUEST['here'],'planning_content')
# recovering HTML data by calling Page Template document pdb.set_trace()
HTML_data = planning_html_method(struct=structure)
return HTML_data # getting HTML rendering Page Template
else: planning_html_method = getattr(REQUEST['here'],'planning_content')
return 'error' # recovering HTML data by calling Page Template document
HTML_data = planning_html_method(struct=structure)
# return HTML data
return HTML_data
def render_structure(self, field, key, value, REQUEST, here): def render_structure(self, field, key, value, REQUEST, here):
...@@ -872,16 +884,16 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -872,16 +884,16 @@ class PlanningBoxWidget(Widget.Widget):
implementation of PlanningBox. The final rendering must be done through implementation of PlanningBox. The final rendering must be done through
a PageTemplate parsing the PlanningStructure object. a PageTemplate parsing the PlanningStructure object.
""" """
# XXX testing : uncoment to put selection to null => used for debugging
#here.portal_selections.setSelectionFor(selection_name, None)
# DATA DEFINITION ####### DATA DEFINITION #######
self.build_error_list = None
# recovering usefull planning properties # recovering usefull planning properties
form = field.aq_parent # getting form form = field.aq_parent # getting form
list_method = field.get_value('list_method') # method used to list objects list_method = field.get_value('list_method') # method used to list objects
report_root_list = field.get_value('report_root_list') # list of domains report_root_list = field.get_value('report_root_list') # list of domains
# defining the possible root portal_types = field.get_value('portal_types') # Portal Types of objects
portal_types = field.get_value('portal_types') # Portal Types of objects to list
# selection name used to store selection params # selection name used to store selection params
selection_name = field.get_value('selection_name') selection_name = field.get_value('selection_name')
# getting sorting keys and order (list) # getting sorting keys and order (list)
...@@ -890,15 +902,8 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -890,15 +902,8 @@ class PlanningBoxWidget(Widget.Widget):
# for them a special rendering is done (special colors for example) # for them a special rendering is done (special colors for example)
list_error=REQUEST.get('list_block_error') list_error=REQUEST.get('list_block_error')
if list_error==None : list_error = [] if list_error==None : list_error = []
# END DATA DEFINITION
# XXX testing : uncoment to put selection to null
#here.portal_selections.setSelectionFor(selection_name, None)
selection = here.portal_selections.getSelectionFor( selection = here.portal_selections.getSelectionFor(
selection_name, REQUEST) selection_name, REQUEST)
# params contained in the selection object is a dictionnary. # params contained in the selection object is a dictionnary.
# must exist as an empty dictionnary if selection is empty. # must exist as an empty dictionnary if selection is empty.
try: try:
...@@ -906,30 +911,35 @@ class PlanningBoxWidget(Widget.Widget): ...@@ -906,30 +911,35 @@ class PlanningBoxWidget(Widget.Widget):
except (AttributeError,KeyError): except (AttributeError,KeyError):
params = {} params = {}
#if selection.has_attribute('getParams'):
# params = selection.getParams() ###### CALL CLASS METHODS TO BUILD BASIC STRUCTURE ######
# CALL CLASS METHODS TO BUILD BASIC STRUCTURE
# creating BasicStructure instance (and initializing its internal values) # creating BasicStructure instance (and initializing its internal values)
self.basic = BasicStructure(here=here,form=form, field=field, REQUEST=REQUEST, list_method=list_method, selection=selection, params = params, selection_name=selection_name, report_root_list=report_root_list, portal_types=portal_types, sort=sort, list_error=list_error) self.basic = BasicStructure(here=here,form=form, field=field,
REQUEST=REQUEST, list_method=list_method,
selection=selection, params = params,
selection_name=selection_name,
report_root_list=report_root_list,
portal_types=portal_types, sort=sort,
list_error=list_error)
# call build method to generate BasicStructure # call build method to generate BasicStructure
returned_value = self.basic.build() status = self.basic.build()
if status != 1:
if returned_value == None: self.build_error_list = status
# in case group list is empty return self
return None
# CALL CLASS METHODS TO BUILD PLANNING STRUCTURE ###### CALL CLASS METHODS TO BUILD PLANNING STRUCTURE ######
# creating PlanningStructure instance and initializing its internal values # creating PlanningStructure instance and initializing its internal values
self.planning = PlanningStructure() self.planning = PlanningStructure()
# call build method to generate final Planning Structure # call build method to generate final Planning Structure
self.planning.build(basic_structure = self.basic,field=field, REQUEST=REQUEST) status = self.planning.build(basic_structure = self.basic,field=field,
REQUEST=REQUEST)
if status != 1:
# in case error during planning structure generation
self.build_error_list = status
return self
# end of main process
# structure is completed, now just need to return structure
return self return self
# instanciating class # instanciating class
PlanningBoxWidgetInstance = PlanningBoxWidget() PlanningBoxWidgetInstance = PlanningBoxWidget()
...@@ -954,8 +964,7 @@ class BasicStructure: ...@@ -954,8 +964,7 @@ class BasicStructure:
self.selection = selection self.selection = selection
self.params = params self.params = params
self.list_method = list_method self.list_method = list_method
self.selection_name = selection_name # used in case no valid list_method self.selection_name = selection_name
# has been found
self.report_root_list = report_root_list self.report_root_list = report_root_list
self.portal_types = portal_types self.portal_types = portal_types
self.basic_group_list = None self.basic_group_list = None
...@@ -987,7 +996,8 @@ class BasicStructure: ...@@ -987,7 +996,8 @@ class BasicStructure:
#recovering selection if necessary #recovering selection if necessary
if self.selection is None: if self.selection is None:
self.selection = Selection(params=default_params, default_sort_on=self.sort) self.selection = Selection(params=default_params,
default_sort_on=self.sort)
else: else:
# immediately updating the default sort value # immediately updating the default sort value
self.selection.edit(default_sort_on=self.sort) self.selection.edit(default_sort_on=self.sort)
...@@ -1009,12 +1019,12 @@ class BasicStructure: ...@@ -1009,12 +1019,12 @@ class BasicStructure:
portal_categories = getattr(self.form,'portal_categories',None) portal_categories = getattr(self.form,'portal_categories',None)
portal_domains = getattr(self.form,'portal_domains',None) portal_domains = getattr(self.form,'portal_domains',None)
################################################## ##################################################
############### BUILDING QUERY ################### ############### BUILDING QUERY ###################
################################################## ##################################################
kw = self.params kw = self.params
# remove selection_expression if present # remove selection_expression if present
# This is necessary for now, because the actual selection expression in # This is necessary for now, because the actual selection expression in
# search catalog does not take the requested columns into account. If # search catalog does not take the requested columns into account. If
...@@ -1023,8 +1033,6 @@ class BasicStructure: ...@@ -1023,8 +1033,6 @@ class BasicStructure:
# names. # names.
if 'select_expression' in kw: if 'select_expression' in kw:
del kw['select_expression'] del kw['select_expression']
if hasattr(self.list_method, 'method_name'): if hasattr(self.list_method, 'method_name'):
if self.list_method.method_name == 'ObjectValues': if self.list_method.method_name == 'ObjectValues':
# list_method is available # list_method is available
...@@ -1042,12 +1050,10 @@ class BasicStructure: ...@@ -1042,12 +1050,10 @@ class BasicStructure:
elif kw.has_key('portal_type'): elif kw.has_key('portal_type'):
if kw['portal_type'] == '': if kw['portal_type'] == '':
del kw['portal_type'] del kw['portal_type']
# remove useless matter # remove useless matter
for cname in self.params.keys(): for cname in self.params.keys():
if self.params[cname] != '' and self.params[cname] != None: if self.params[cname] != '' and self.params[cname] != None:
kw[cname] = self.params[cname] kw[cname] = self.params[cname]
# try to get the method through acquisition # try to get the method through acquisition
try: try:
self.list_method = getattr(self.here, self.list_method.method_name) self.list_method = getattr(self.here, self.list_method.method_name)
...@@ -1057,27 +1063,20 @@ class BasicStructure: ...@@ -1057,27 +1063,20 @@ class BasicStructure:
# use current selection # use current selection
self.list_method = None self.list_method = None
################################################## ##################################################
############## DEFINING STAT METHOD ############## ############## DEFINING STAT METHOD ##############
################################################## ##################################################
# XXX implementing this new functionality
stat_method = self.field.get_value('stat_method') stat_method = self.field.get_value('stat_method')
#stat_method = getattr(self.REQUEST['here'],stat_method)
stat_method = getattr(self.here,stat_method, None) stat_method = getattr(self.here,stat_method, None)
if stat_method == None: if stat_method == None:
show_stat = 0 show_stat = 0
else: else:
show_stat = 1 show_stat = 1
################################################## ##################################################
############ BUILDING REPORT_TREE ################ ############ BUILDING REPORT_TREE ################
################################################## ##################################################
# assuming result is report tree, building it # assuming result is report tree, building it
# When building the body, need to go through all report lines # When building the body, need to go through all report lines
# each report line is a tuple of the form : # each report line is a tuple of the form :
...@@ -1099,9 +1098,12 @@ class BasicStructure: ...@@ -1099,9 +1098,12 @@ class BasicStructure:
selection_report_current = self.selection.getReportList() selection_report_current = self.selection.getReportList()
# building report_tree_list # building report_tree_list
report_tree_list = makeTreeList(here=self.here, form=self.form, root_dict=None, report_tree_list = makeTreeList(here=self.here, form=self.form,
report_path=selection_report_path, base_category=None, depth=0, root_dict=None,
unfolded_list=selection_report_current, selection_name=self.selection_name, report_path=selection_report_path,
base_category=None, depth=0,
unfolded_list=selection_report_current,
selection_name=self.selection_name,
report_depth=report_depth,is_report_opened=is_report_opened, report_depth=report_depth,is_report_opened=is_report_opened,
sort_on=self.selection.sort_on,form_id=self.form.id) sort_on=self.selection.sort_on,form_id=self.form.id)
...@@ -1149,7 +1151,12 @@ class BasicStructure: ...@@ -1149,7 +1151,12 @@ class BasicStructure:
self.selection.edit(params = kw) self.selection.edit(params = kw)
# recovering statistics if needed # recovering statistics if needed
# getting list of statistic blocks # getting list of statistic blocks
stat_list = stat_method(selection=self.selection, list_method=self.list_method, selection_context=self.here, report_tree_list=report_tree_list, object_tree_line=object_tree_line, REQUEST=self.REQUEST, field=self.field) stat_list = stat_method(selection=self.selection,
list_method=self.list_method,
selection_context=self.here,
report_tree_list=report_tree_list,
object_tree_line=object_tree_line,
REQUEST=self.REQUEST, field=self.field)
if original_select_expression is None: if original_select_expression is None:
del kw['select_expression'] del kw['select_expression']
...@@ -1215,7 +1222,8 @@ class BasicStructure: ...@@ -1215,7 +1222,8 @@ class BasicStructure:
if exception_uid_list is not None: if exception_uid_list is not None:
# case of parent tree mode (first/unique object). # case of parent tree mode (first/unique object).
# beware object_list is not null in case folded sons exists so # beware object_list is not null in case folded sons exists so
# do not export voluntary object_list to prevent bad interpretation # do not export voluntary object_list to prevent bad
# interpretation
self.report_groups += [(object_tree_line, [], info_dict)] self.report_groups += [(object_tree_line, [], info_dict)]
self.nbr_groups += 1 self.nbr_groups += 1
else: else:
...@@ -1228,7 +1236,6 @@ class BasicStructure: ...@@ -1228,7 +1236,6 @@ class BasicStructure:
# reset to original value # reset to original value
self.selection.edit(report = None) self.selection.edit(report = None)
self.selection.edit(report_list=None) self.selection.edit(report_list=None)
# update report list if report_depth was specified # update report list if report_depth was specified
...@@ -1236,47 +1243,49 @@ class BasicStructure: ...@@ -1236,47 +1243,49 @@ class BasicStructure:
unfolded_list = [] unfolded_list = []
for (report_line, object_list, info_dict) in self.report_groups: for (report_line, object_list, info_dict) in self.report_groups:
if report_line.depth < report_depth and not info_dict['stat'] : if report_line.depth < report_depth and not info_dict['stat'] :
# depth of current report_line is inferior to the current report_depth # depth of current report_line is inferior to the current
# and current report_line is not stat line. saving information # report_depth and current report_line is not stat line.
# saving information
unfolded_list.append(report_line.getObject().getRelativeUrl()) unfolded_list.append(report_line.getObject().getRelativeUrl())
self.selection.edit(report_list=unfolded_list) self.selection.edit(report_list=unfolded_list)
################################################## ##################################################
########### GETTING MAIN AXIS BOUNDS ############# ########### GETTING MAIN AXIS BOUNDS #############
################################################## ##################################################
# before building group_object structure, need to recover axis begin & end # before building group_object structure, need to recover axis begin & end
# for main to be able to generate a 'smart' structure taking into account # for main to be able to generate a 'smart' structure taking into account
# only the area that need to be rendered. This prevents from useless processing # only the area that need to be rendered. This prevents from useless
# processing
# calculating main axis bounds # calculating main axis bounds
self.getMainAxisInfo(self.main_axis_info) self.getMainAxisInfo(self.main_axis_info)
# applying main axis selection # applying main axis selection
if self.report_groups != []: if self.report_groups != []:
self.report_groups = self.report_groups[self.main_axis_info['bound_start']: self.report_groups=self.report_groups[self.main_axis_info['bound_start']:
self.main_axis_info['bound_stop']] self.main_axis_info['bound_stop']]
else: else:
# XXX need to handle this kind of error: # ERROR : self.report_groups = []
# no group is available so the Y and X axis will be empty... # no group is available so the Y and X axis will be empty...
return None message = 'selection method returned empty list of objects : please check\
your list_method and report_root'
return [(Message(domain=None, message=message,mapping=None))]
################################################## ##################################################
############ GETTING SEC AXIS BOUNDS ############# ############ GETTING SEC AXIS BOUNDS #############
################################################## ##################################################
# now that our report_group structure has been cut need to get secondary axis # now that our report_group structure has been cut need to get secondary
# bounds to add only the blocs needed afterwards # axis bounds to add only the blocs needed afterwards
# getting secondary_axis_occurence to define begin and end secondary_axis # getting secondary_axis_occurence to define begin and end secondary_axis
# bounds (getting absolute size) # bounds (getting absolute size)
self.secondary_axis_occurence = self.getSecondaryAxisOccurence() self.secondary_axis_occurence = self.getSecondaryAxisOccurence()
# now getting start & stop bounds (getting relative size to the current # now getting start & stop bounds (getting relative size to the current
# rendering) # rendering)
self.getSecondaryAxisInfo(self.secondary_axis_info) status = self.getSecondaryAxisInfo(self.secondary_axis_info)
if status != 1:
# ERROR
# Found error while setting secondary axis bounds
return status
################################################## ##################################################
...@@ -1284,7 +1293,9 @@ class BasicStructure: ...@@ -1284,7 +1293,9 @@ class BasicStructure:
################################################## ##################################################
if self.list_method is not None and self.render_format != 'list': if self.list_method is not None and self.render_format != 'list':
self.selection.edit(params = self.params) self.selection.edit(params = self.params)
self.here.portal_selections.setSelectionFor(self.selection_name, self.selection, REQUEST = self.REQUEST) self.here.portal_selections.setSelectionFor(self.selection_name,
self.selection,
REQUEST = self.REQUEST)
################################################## ##################################################
...@@ -1293,11 +1304,13 @@ class BasicStructure: ...@@ -1293,11 +1304,13 @@ class BasicStructure:
# building group_object structure using sub lines depth (in case of a # building group_object structure using sub lines depth (in case of a
# report tree) by doing this. # report tree) by doing this.
# taking into account page bounds to generate only the structure needed # taking into account page bounds to generate only the structure needed
# instanciate BasicGroup class in BasicStructure so that the structure can # instanciate BasicGroup class in BasicStructure so that the structure can
# be built # be built
self.buildGroupStructure() status = self.buildGroupStructure()
if status != 1:
# ERROR
# Found errors while setting group structure
return status
# everything is fine # everything is fine
return 1 return 1
...@@ -1305,7 +1318,9 @@ class BasicStructure: ...@@ -1305,7 +1318,9 @@ class BasicStructure:
def getSecondaryAxisOccurence(self): def getSecondaryAxisOccurence(self):
""" """
get secondary_axis occurences in order to define begin and end bounds get secondary_axis occurences in order to define begin and end bounds.
Just make a listing of all the start and stop values for all the
report_group objects
""" """
secondary_axis_occurence = [] secondary_axis_occurence = []
...@@ -1315,31 +1330,32 @@ class BasicStructure: ...@@ -1315,31 +1330,32 @@ class BasicStructure:
for (object_tree_group, object_list, info_dict) in self.report_groups: for (object_tree_group, object_list, info_dict) in self.report_groups:
# recover method to get begin and end limits # recover method to get begin and end limits
#if method_start == None and child_activity_list != None:
if object_list not in (None, [], {}) : if object_list not in (None, [], {}) :
for object_request in object_list: for object_request in object_list:
if start_property_id != None: if start_property_id != None:
block_begin = object_request.getObject().getProperty(start_property_id) block_begin = \
object_request.getObject().getProperty(start_property_id,None)
else: else:
block_begin = None block_begin = None
if stop_property_id != None: if stop_property_id != None:
block_stop = object_request.getObject().getProperty(stop_property_id) block_stop = \
object_request.getObject().getProperty(stop_property_id,None)
else: else:
block_stop = None block_stop = None
secondary_axis_occurence.append([block_begin,block_stop]) secondary_axis_occurence.append([block_begin,block_stop])
else: else:
if start_property_id != None: if start_property_id != None:
block_begin = object_tree_group.object.getObject().getProperty(start_property_id) block_begin = \
object_tree_group.object.getObject().getProperty(start_property_id,
None)
else: else:
block_begin = None block_begin = None
if stop_property_id != None: if stop_property_id != None:
block_stop = object_tree_group.object.getObject().getProperty(stop_property_id) block_stop = \
object_tree_group.object.getObject().getProperty(stop_property_id,
None)
else: else:
block_stop = None block_stop = None
secondary_axis_occurence.append([block_begin,block_stop]) secondary_axis_occurence.append([block_begin,block_stop])
return secondary_axis_occurence return secondary_axis_occurence
...@@ -1353,6 +1369,8 @@ class BasicStructure: ...@@ -1353,6 +1369,8 @@ class BasicStructure:
it is now possible to recover begin and end value of the planning and then it is now possible to recover begin and end value of the planning and then
apply selection informations to get start and stop. apply selection informations to get start and stop.
""" """
# recovering zoom properties
axis_dict['zoom_start'] = int(self.params.get('zoom_start',0)) axis_dict['zoom_start'] = int(self.params.get('zoom_start',0))
axis_dict['zoom_level'] = float(self.params.get('zoom_level',1)) axis_dict['zoom_level'] = float(self.params.get('zoom_level',1))
...@@ -1360,35 +1378,46 @@ class BasicStructure: ...@@ -1360,35 +1378,46 @@ class BasicStructure:
axis_dict['bound_begin'] = self.secondary_axis_occurence[0][0] axis_dict['bound_begin'] = self.secondary_axis_occurence[0][0]
axis_dict['bound_end'] = axis_dict['bound_begin'] axis_dict['bound_end'] = axis_dict['bound_begin']
for occurence in self.secondary_axis_occurence: for occurence in self.secondary_axis_occurence:
if (occurence[0] < axis_dict['bound_begin'] or axis_dict['bound_begin'] == None) and occurence[0] != None: if (occurence[0] < axis_dict['bound_begin'] or \
axis_dict['bound_begin'] == None) and occurence[0] != None:
axis_dict['bound_begin'] = occurence[0] axis_dict['bound_begin'] = occurence[0]
if (occurence[1] > axis_dict['bound_end'] or axis_dict['bound_end'] == None) and occurence[1] != None: if (occurence[1] > axis_dict['bound_end'] or \
axis_dict['bound_end'] == None) and occurence[1] != None:
axis_dict['bound_end'] = occurence[1] axis_dict['bound_end'] = occurence[1]
if axis_dict['bound_end']==None or axis_dict['bound_begin']==None: if axis_dict['bound_end']==None or axis_dict['bound_begin']==None:
# XXX need to handle this kind of error : # ERROR
# no bounds over the secondary axis have been defined # no bounds over the secondary axis have been defined
return PlanningError(error_name,error_message) # can append if bad property has been selected
message = 'can not find secondary axis bounds for planning view :\
No object has good start & stop properties, please check your objects \
and their corresponding properties'
return [(Message(domain=None, message=message,mapping=None))]
axis_dict['bound_range'] = axis_dict['bound_end'] - axis_dict['bound_begin']
axis_dict['bound_range'] = axis_dict['bound_end']-axis_dict['bound_begin']
# now start and stop have the extreme values of the second axis bound. # now start and stop have the extreme values of the second axis bound.
# this represents in fact the size of the Planning # this represents in fact the size of the Planning's secondary axis
# can now getting selection informations ( float range 0..1) # can now get selection informations ( float range 0..1)
axis_dict['bound_start'] = 0 axis_dict['bound_start'] = 0
axis_dict['bound_stop'] = 1 axis_dict['bound_stop'] = 1
if self.selection != None: if self.selection != None:
# selection is not None, trying to recover previously saved values about
# secondary axis (axis start and stop bounds)
try: try:
axis_dict['bound_start'] = self.selection.getSecondaryAxisStart() axis_dict['bound_start'] = self.selection.getSecondaryAxisStart()
axis_dict['bound_stop'] = self.selection.getSecondaryAxisStop() axis_dict['bound_stop'] = self.selection.getSecondaryAxisStop()
except AttributeError: #XXX except AttributeError:
# bounds were not defined, escaping test
pass pass
# getting secondary axis page step # getting secondary axis page step
axis_zoom_step = axis_dict['bound_range'] / axis_dict['zoom_level'] axis_zoom_step = axis_dict['bound_range'] / axis_dict['zoom_level']
# now setting bound_start # now setting bound_start
axis_dict['bound_start'] = axis_dict['zoom_start'] * axis_zoom_step + axis_dict['bound_begin'] axis_dict['bound_start'] = axis_dict['zoom_start'] * axis_zoom_step + \
axis_dict['bound_begin']
# for bound_stop just add page step # for bound_stop just add page step
axis_dict['bound_stop'] = axis_dict['bound_start'] + axis_zoom_step axis_dict['bound_stop'] = axis_dict['bound_start'] + axis_zoom_step
...@@ -1396,6 +1425,8 @@ class BasicStructure: ...@@ -1396,6 +1425,8 @@ class BasicStructure:
self.params['zoom_level'] = axis_dict['zoom_level'] self.params['zoom_level'] = axis_dict['zoom_level']
self.params['zoom_start'] = axis_dict['zoom_start'] self.params['zoom_start'] = axis_dict['zoom_start']
# everything is OK, returning 'true' flag
return 1
def getMainAxisInfo(self, axis_dict): def getMainAxisInfo(self, axis_dict):
...@@ -1441,16 +1472,21 @@ class BasicStructure: ...@@ -1441,16 +1472,21 @@ class BasicStructure:
axis_dict['bound_start'] = axis_dict['bound_end'] axis_dict['bound_start'] = axis_dict['bound_end']
# updating start position to fit page size. # updating start position to fit page size.
axis_dict['bound_start'] -= (axis_dict['bound_start'] % axis_dict['bound_axis_groups']) axis_dict['bound_start'] -= \
(axis_dict['bound_start'] % axis_dict['bound_axis_groups'])
# setting last group displayed on page # setting last group displayed on page
axis_dict['bound_stop'] = min (axis_dict['bound_start'] + axis_dict['bound_axis_groups'], axis_dict['bound_end']) axis_dict['bound_stop'] = min (axis_dict['bound_end'],
axis_dict['bound_start'] + axis_dict['bound_axis_groups'])
# calculating total number of pages # calculating total number of pages
axis_dict['bound_page_total'] = int(max(axis_dict['bound_end'] - 1,0) / axis_dict['bound_axis_groups']) + 1 axis_dict['bound_page_total'] = int(max(axis_dict['bound_end'] - 1,0) / \
axis_dict['bound_axis_groups']) + 1
# calculating current page number # calculating current page number
axis_dict['bound_page_current'] = int(axis_dict['bound_start'] / axis_dict['bound_axis_groups']) + 1 axis_dict['bound_page_current'] = int(axis_dict['bound_start'] / \
axis_dict['bound_axis_groups']) + 1
# adjusting first group displayed on current page # adjusting first group displayed on current page
axis_dict['bound_start'] = min(axis_dict['bound_start'], max(0, (axis_dict['bound_page_total']-1) * axis_dict['bound_axis_groups'])) axis_dict['bound_start'] = min(axis_dict['bound_start'], max(0,
(axis_dict['bound_page_total']-1) * axis_dict['bound_axis_groups']))
self.params['list_lines'] = axis_dict['bound_axis_groups'] self.params['list_lines'] = axis_dict['bound_axis_groups']
self.params['list_start'] = axis_dict['bound_start'] self.params['list_start'] = axis_dict['bound_start']
...@@ -1464,12 +1500,15 @@ class BasicStructure: ...@@ -1464,12 +1500,15 @@ class BasicStructure:
position = 0 position = 0
# iterating each element # iterating each element
for (report_group_object, object_list, property_dict) in self.report_groups: for (report_group_object, object_list, property_dict) in \
self.report_groups:
stat_result = {} stat_result = {}
stat_context = report_group_object.getObject().asContext(**stat_result) stat_context = report_group_object.getObject().asContext(**stat_result)
stat_context.domain_url = report_group_object.getObject().getRelativeUrl() stat_context.domain_url = \
stat_context.absolute_url = lambda x: report_group_object.getObject().absolute_url() report_group_object.getObject().getRelativeUrl()
stat_context.absolute_url = \
lambda x: report_group_object.getObject().absolute_url()
url=getattr(stat_context,'domain_url','') url=getattr(stat_context,'domain_url','')
# updating position_informations # updating position_informations
position +=1 position +=1
...@@ -1481,17 +1520,17 @@ class BasicStructure: ...@@ -1481,17 +1520,17 @@ class BasicStructure:
is_pure_summary = report_group_object.getIsPureSummary() is_pure_summary = report_group_object.getIsPureSummary()
# creating new group_object with all the informations collected # creating new group_object with all the informations collected
child_group = BasicGroup( title=title, name=name, url=url, constraints=None, depth=depth, position=position, field =self.field, object=report_group_object, is_open=is_open, is_pure_summary=is_pure_summary, property_dict = property_dict) child_group = BasicGroup(title=title, name=name, url=url,
constraints=None, depth=depth,
# creating activities related to the new group position=position, field =self.field,
# first recovering activity list if exists object=report_group_object, is_open=is_open,
#report_activity_list = [] is_pure_summary=is_pure_summary,
#if title in self.report_activity_dict.keys(): property_dict = property_dict)
# report_activity_list = self.report_activity_dict[title]
# linking activities to the bloc. the parameter is a list of elements
# to link to the child_group object.
if object_list != None: if object_list != None:
child_group.setBasicActivities(object_list,self.list_error,self.secondary_axis_info) child_group.setBasicActivities(object_list,self.list_error,
self.secondary_axis_info)
try: try:
self.basic_group_list.append(child_group) self.basic_group_list.append(child_group)
...@@ -1499,6 +1538,8 @@ class BasicStructure: ...@@ -1499,6 +1538,8 @@ class BasicStructure:
self.basic_group_list = [] self.basic_group_list = []
self.basic_group_list.append(child_group) self.basic_group_list.append(child_group)
return 1
class BasicGroup: class BasicGroup:
""" """
...@@ -1512,7 +1553,9 @@ class BasicGroup: ...@@ -1512,7 +1553,9 @@ class BasicGroup:
ReportTree mode to handle child groups. ReportTree mode to handle child groups.
""" """
def __init__ (self, title='', name='',url='', constraints='', depth=0, position=0, field = None, object = None, is_open=0, is_pure_summary=1, property_dict = {}): def __init__ (self, title='', name='',url='', constraints='', depth=0,
position=0, field = None, object = None, is_open=0,
is_pure_summary=1, property_dict = {}):
self.title = title self.title = title
self.name = name self.name = name
self.url = url self.url = url
...@@ -1523,14 +1566,12 @@ class BasicGroup: ...@@ -1523,14 +1566,12 @@ class BasicGroup:
self.position = position # position of current group in the selection self.position = position # position of current group in the selection
self.field = field # field object itself. used for several purposes self.field = field # field object itself. used for several purposes
self.object = object # ERP5 object returned & related to the group self.object = object # ERP5 object returned & related to the group
self.is_open = is_open # define is report is opened or not self.is_open = is_open
self.is_pure_summary = is_pure_summary # define id report is single or has sons self.is_pure_summary = is_pure_summary
# specific start and stop bound values specifiec to the current group and
# specific start and stop bound values specifiec to the current group and used # used in case of calendar mode
# in case of calendar mode
self.start = None self.start = None
self.stop = None self.stop = None
# property_dict holds all information about the current axis_group # property_dict holds all information about the current axis_group
# type of group, stat, etc. # type of group, stat, etc.
self.property_dict = property_dict self.property_dict = property_dict
...@@ -1539,66 +1580,53 @@ class BasicGroup: ...@@ -1539,66 +1580,53 @@ class BasicGroup:
def setBasicActivities(self,activity_list, list_error,secondary_axis_info): def setBasicActivities(self,activity_list, list_error,secondary_axis_info):
""" """
link a list of activities to the current object. link a list of activities to the current object.
+ recover group properties. Used in case activity is built from Group itself *Recover group properties. Used in case activity is built from Group
+ create a BasicActivity for each activity referenced in the list if itself
necessary *create a BasicActivity for each activity referenced in the list if
+ add the activity to the current group. necessary
+ update secondary_axis_occurence *add the activity to the current group.
*update secondary_axis_occurence
""" """
info = {}
# specific begin & stop property names for secondary axis # specific begin & stop property names for secondary axis
object_property_begin = self.field.get_value('x_start_bloc') object_property_begin = self.field.get_value('x_start_bloc')
object_property_end = self.field.get_value('x_stop_bloc') object_property_end = self.field.get_value('x_stop_bloc')
# specific block text_information methods # specific block text_information methods
info_center = self.field.get_value('info_center') info_center = self.field.get_value('info_center')
info_topleft = self.field.get_value('info_topleft') info_topleft = self.field.get_value('info_topleft')
info_topright = self.field.get_value('info_topright') info_topright = self.field.get_value('info_topright')
info_backleft = self.field.get_value('info_backleft') info_backleft = self.field.get_value('info_backleft')
info_backright = self.field.get_value('info_backright') info_backright = self.field.get_value('info_backright')
info = {}
# getting info method from activity itself if exists # getting info method from activity itself if exists
info_center_method = getattr(self.object.getObject(),info_center,None) info_center_method = getattr(self.object.getObject(),info_center,None)
info_topright_method = getattr(self.object.getObject(),info_topright,None) info_topright_method = getattr(self.object.getObject(),info_topright,None)
info_topleft_method = getattr(self.object.getObject(),info_topleft,None) info_topleft_method = getattr(self.object.getObject(),info_topleft,None)
info_backleft_method = getattr(self.object.getObject(),info_backleft,None) info_backleft_method = getattr(self.object.getObject(),info_backleft,None)
info_backright_method = getattr(self.object.getObject(),info_backright,None) info_backright_method = \
getattr(self.object.getObject(),info_backright,None)
# if method recovered is not null, then updating # if method recovered is not null, then updating
if info_center_method!=None: info['info_center'] =str(info_center_method()) if info_center_method!=None: \
if info_topright_method!=None: info['info_topright'] =str(info_topright_method()) info['info_center'] = str(info_center_method())
if info_topleft_method!=None: info['info_topleft'] =str(info_topleft_method()) if info_topright_method!=None: \
if info_backleft_method!=None: info['info_backleft'] =str(info_backleft_method()) info['info_topright'] = str(info_topright_method())
if info_backright_method!=None: info['info_backright']=str(info_backright_method()) if info_topleft_method!=None: \
info['info_topleft'] = str(info_topleft_method())
if info_backleft_method!=None: \
info['info_backleft'] = str(info_backleft_method())
if info_backright_method!=None: \
info['info_backright'] = str(info_backright_method())
#if method_begin == None and activity_list not in ([],None):
if activity_list not in ([],None): if activity_list not in ([],None):
# modifying iterating mode from original PlanningBox.py script to prevent
# useless and repetitive tests.
# this process should be somehow quicker and smarter
indic=0 indic=0
# iterating each activity linked to the current group # iterating each activity linked to the current group
for activity_content in activity_list: for activity_content in activity_list:
# interpreting results and getting begin and end values from # interpreting results and getting begin and end values from
# previously recovered method # previously recovered method
block_begin = None block_begin = None
block_end = None block_end = None
if object_property_begin !=None: if object_property_begin !=None:
block_begin = getattr(activity_content.getObject(),object_property_begin) block_begin = \
getattr(activity_content.getObject(),object_property_begin)
else: else:
block_begin = None block_begin = None
...@@ -1607,7 +1635,6 @@ class BasicGroup: ...@@ -1607,7 +1635,6 @@ class BasicGroup:
else: else:
block_end = None block_end = None
# handling case where activity bound is not defined # handling case where activity bound is not defined
if block_begin == None: if block_begin == None:
block_begin = secondary_axis_info['bound_start'] block_begin = secondary_axis_info['bound_start']
...@@ -1615,9 +1642,10 @@ class BasicGroup: ...@@ -1615,9 +1642,10 @@ class BasicGroup:
if block_end == None: if block_end == None:
block_end = secondary_axis_info['bound_stop'] block_end = secondary_axis_info['bound_stop']
current_color='#E4CCE1' current_color='#E4CCE1'
# testing if activity is visible according to the current zoom selection over # testing if activity is visible according to the current zoom
# the secondary_axis # selection over the secondary_axis
if block_begin > secondary_axis_info['bound_stop'] or block_end < secondary_axis_info['bound_start']: if block_begin > secondary_axis_info['bound_stop'] or \
block_end < secondary_axis_info['bound_start']:
# activity will not be displayed, stopping process # activity will not be displayed, stopping process
pass pass
else: else:
...@@ -1633,7 +1661,6 @@ class BasicGroup: ...@@ -1633,7 +1661,6 @@ class BasicGroup:
block_stop = block_end block_stop = block_end
# defining name # defining name
#name = "Activity_%s_%s" % (self.object.getObject().getTitle(),str(indic))
name = "Activity_%s" % (str(indic)) name = "Activity_%s" % (str(indic))
error = 'false' error = 'false'
...@@ -1651,7 +1678,8 @@ class BasicGroup: ...@@ -1651,7 +1678,8 @@ class BasicGroup:
object = activity_content object = activity_content
url='' url=''
object_property_height = self.field.get_value('y_size_block') object_property_height = self.field.get_value('y_size_block')
height = getattr(activity_content.getObject(),object_property_height) height = \
getattr(activity_content.getObject(),object_property_height)
else: else:
info = None info = None
info = {} info = {}
...@@ -1660,18 +1688,25 @@ class BasicGroup: ...@@ -1660,18 +1688,25 @@ class BasicGroup:
info_topright_method = getattr(activity_content,info_topright,None) info_topright_method = getattr(activity_content,info_topright,None)
info_topleft_method = getattr(activity_content,info_topleft,None) info_topleft_method = getattr(activity_content,info_topleft,None)
info_backleft_method = getattr(activity_content,info_backleft,None) info_backleft_method = getattr(activity_content,info_backleft,None)
info_backright_method = getattr(activity_content,info_backright,None) info_backright_method = \
getattr(activity_content,info_backright,None)
# if value recovered is not null, then updating # if value recovered is not null, then updating
if info_center_method!=None: info['info_center']=str(info_center_method()) if info_center_method!=None:
if info_topright_method!=None: info['info_topright']=str(info_topright_method()) info['info_center']=str(info_center_method())
if info_topleft_method!=None: info['info_topleft']=str(info_topleft_method()) if info_topright_method!=None:
if info_backleft_method!=None: info['info_backleft'] =str(info_backleft_method()) info['info_topright']=str(info_topright_method())
if info_backright_method!=None: info['info_backright']=str(info_backright_method()) if info_topleft_method!=None:
info['info_topleft']=str(info_topleft_method())
if info_backleft_method!=None:
info['info_backleft'] =str(info_backleft_method())
if info_backright_method!=None:
info['info_backright']=str(info_backright_method())
title = info['info_center'] title = info['info_center']
color_script = getattr(activity_content.getObject(), self.field.get_value('color_script'),None) color_script = getattr(activity_content.getObject(),
self.field.get_value('color_script'),None)
# calling color script if exists to set up activity_color # calling color script if exists to set up activity_color
if color_script !=None: if color_script !=None:
current_color = color_script(activity_content.getObject()) current_color = color_script(activity_content.getObject())
...@@ -1684,9 +1719,12 @@ class BasicGroup: ...@@ -1684,9 +1719,12 @@ class BasicGroup:
break break
stat_result = {} stat_result = {}
stat_context = activity_content.getObject().asContext(**stat_result) stat_context = \
stat_context.domain_url = activity_content.getObject().getRelativeUrl() activity_content.getObject().asContext(**stat_result)
stat_context.absolute_url = lambda x: activity_content.getObject().absolute_url() stat_context.domain_url = \
activity_content.getObject().getRelativeUrl()
stat_context.absolute_url = \
lambda x: activity_content.getObject().absolute_url()
object = stat_context.getObject() object = stat_context.getObject()
url = stat_context.getUrl() url = stat_context.getUrl()
...@@ -1694,7 +1732,14 @@ class BasicGroup: ...@@ -1694,7 +1732,14 @@ class BasicGroup:
height = None height = None
# creating new activity instance # creating new activity instance
activity = BasicActivity(title=title, name=name, object=object, url=url, absolute_begin=block_begin, absolute_end=block_end, absolute_start=block_start, absolute_stop=block_stop, height = height, color=current_color, info_dict=info, error=error, property_dict=self.property_dict) activity = BasicActivity(title=title, name=name, object=object,
url=url, absolute_begin=block_begin,
absolute_end=block_end,
absolute_start=block_start,
absolute_stop=block_stop, height = height,
color=current_color, info_dict=info,
error=error,
property_dict=self.property_dict)
# adding new activity to personal group activity list # adding new activity to personal group activity list
...@@ -1710,20 +1755,18 @@ class BasicGroup: ...@@ -1710,20 +1755,18 @@ class BasicGroup:
else: else:
# specific color script
# specific color scriptactivity color_script = getattr(self.object.getObject(),
color_script = getattr(self.object.getObject(), self.field.get_value('color_script'),None) self.field.get_value('color_script'),None)
# calling color script if exists to set up activity_color # calling color script if exists to set up activity_color
current_color='' current_color=''
if color_script !=None: if color_script !=None:
current_color = color_script(self.object.getObject()) current_color = color_script(self.object.getObject())
# getting begin and end values from previously recovered method # getting begin and end values from previously recovered method
if object_property_begin !=None: if object_property_begin !=None:
block_begin = self.object.getObject().getProperty(object_property_begin) block_begin = \
self.object.getObject().getProperty(object_property_begin)
else: else:
block_begin = None block_begin = None
...@@ -1732,16 +1775,17 @@ class BasicGroup: ...@@ -1732,16 +1775,17 @@ class BasicGroup:
else: else:
block_end = None block_end = None
# testing if activity is visible according to the current zoom selection over # testing if activity is visible according to the current zoom selection
# the secondary_axis # over the secondary_axis
if block_begin == None: if block_begin == None:
block_begin = secondary_axis_info['bound_start'] block_begin = secondary_axis_info['bound_start']
current_color='#E4CCE1' current_color='#E4CCE1'
if block_end == None: if block_end == None:
block_end = secondary_axis_info['bound_stop'] block_end = secondary_axis_info['bound_stop']
current_color='#E4CCE1' current_color='#E4CCE1'
if (block_begin > secondary_axis_info['bound_stop'] or block_end < secondary_axis_info['bound_start']): if (block_begin > secondary_axis_info['bound_stop'] or \
# # activity will not be displayed, stopping process block_end < secondary_axis_info['bound_start']):
# activity will not be displayed, stopping process
pass pass
else: else:
# activity is somehow displayed. checking if need to cut its bounds # activity is somehow displayed. checking if need to cut its bounds
...@@ -1770,7 +1814,14 @@ class BasicGroup: ...@@ -1770,7 +1814,14 @@ class BasicGroup:
height = None height = None
# creating new activity instance # creating new activity instance
activity=BasicActivity(title=info['info_center'], name=name, object=self.object.object, url=self.url, absolute_begin=block_begin, absolute_end=block_end, absolute_start=block_start, absolute_stop=block_stop, height=height, color=current_color, info_dict=info, error=error, property_dict=self.property_dict) activity=BasicActivity(title=info['info_center'], name=name,
object=self.object.object, url=self.url,
absolute_begin=block_begin,
absolute_end=block_end,
absolute_start=block_start,
absolute_stop=block_stop, height=height,
color=current_color, info_dict=info,
error=error, property_dict=self.property_dict)
# adding new activity to personal group activity list # adding new activity to personal group activity list
try: try:
...@@ -1787,8 +1838,10 @@ class BasicActivity: ...@@ -1787,8 +1838,10 @@ class BasicActivity:
""" Represents an activity, a task, in the group it belongs to. Beware """ Represents an activity, a task, in the group it belongs to. Beware
nothing about multitask rendering. """ nothing about multitask rendering. """
def __init__ (self, title='', name='',object = None, url='', absolute_begin=None, def __init__ (self, title='', name='',object = None, url='',
absolute_end=None,absolute_start=None,absolute_stop=None, height=None, constraints='', color=None, error='false', info_dict= None, property_dict = {}): absolute_begin=None, absolute_end=None, absolute_start=None,
absolute_stop=None, height=None, constraints='', color=None,
error='false', info_dict= None, property_dict = {}):
self.title = title self.title = title
self.name = name self.name = name
self.object = object self.object = object
...@@ -1799,7 +1852,7 @@ class BasicActivity: ...@@ -1799,7 +1852,7 @@ class BasicActivity:
self.absolute_start = absolute_start self.absolute_start = absolute_start
self.absolute_stop = absolute_stop self.absolute_stop = absolute_stop
self.height = height self.height = height
self.constraints = constraints# constraints specific to the current Activity self.constraints = constraints
self.color = color self.color = color
self.info_dict = info_dict self.info_dict = info_dict
self.error = error self.error = error
...@@ -1826,19 +1879,14 @@ class PlanningStructure: ...@@ -1826,19 +1879,14 @@ class PlanningStructure:
def build(self,basic_structure=None, field=None, REQUEST=None): def build(self,basic_structure=None, field=None, REQUEST=None):
""" """
main procedure for building Planning Structure main procedure for building Planning Structure
do all the necessary process to construct a full Structure compliant with all do all the necessary process to construct a full Structure compliant with
expectations (axis, zoom, colors, report_tree, multi_lines, etc.). From this all expectations (axis, zoom, colors, report_tree, multi_lines, etc.).
final structure just need to run a PageTemplate to get an HTML output, or any From this final structure just need to run a PageTemplate to get an HTML
other script to get the Planning result in the format you like... output, or any other script to get the Planning result in the format you
like...
""" """
# recovering render format ('YX' or 'XY')
# XXX defining render_format
# afterwards will be defined as a planningBox's property field or (perhaps even better)
# a on the fly button integrated over the planning representation
#render_format = field.get_value('render_format')
self.render_format = field.get_value('representation_type') self.render_format = field.get_value('representation_type')
#self.render_format = 'YX'
# declaring main axis # declaring main axis
self.main_axis = Axis(title='main axis', name='axis', self.main_axis = Axis(title='main axis', name='axis',
...@@ -1861,11 +1909,12 @@ class PlanningStructure: ...@@ -1861,11 +1909,12 @@ class PlanningStructure:
self.X.name = 'axis_x' self.X.name = 'axis_x'
self.Y.name = 'axis_y' self.Y.name = 'axis_y'
#pdb.set_trace()
# recovering secondary_axis_ bounds # recovering secondary_axis_ bounds
self.secondary_axis.start = basic_structure.secondary_axis_info['bound_start'] self.secondary_axis.start = \
self.secondary_axis.stop = basic_structure.secondary_axis_info['bound_stop'] basic_structure.secondary_axis_info['bound_start']
self.secondary_axis.stop = \
basic_structure.secondary_axis_info['bound_stop']
self.main_axis.size = self.buildGroups(basic_structure=basic_structure) self.main_axis.size = self.buildGroups(basic_structure=basic_structure)
...@@ -1873,17 +1922,25 @@ class PlanningStructure: ...@@ -1873,17 +1922,25 @@ class PlanningStructure:
# call method to build secondary axis structure # call method to build secondary axis structure
# need start_bound, stop_bound and number of groups to build # need start_bound, stop_bound and number of groups to build
self.buildSecondaryAxis(basic_structure,field) status = self.buildSecondaryAxis(basic_structure,field)
if status != 1:
# ERROR while building secondary axis
return status
# completing axisgroup informations according to their bounds # completing axisgroup informations according to their bounds
self.completeAxis() status = self.completeAxis()
if status != 1:
# ERROR while completing axis
return status
# the whole structure is almost completed : axis_groups are defined, as # the whole structure is almost completed : axis_groups are defined, as
# axis_elements with their activities. Just need to create blocks related to # axis_elements with their activities. Just need to create blocks related
# the activities (special process only for Calendar mode) with their # to the activities (special process only for Calendar mode) with their
# BlockPosition # BlockPosition
self.buildBlocs(REQUEST = REQUEST) status = self.buildBlocs(REQUEST = REQUEST)
if status != 1:
# ERROR while building blocks
return status
# everything is fine, returning 'true' flag.
return 1
def buildSecondaryAxis(self,basic_structure, field): def buildSecondaryAxis(self,basic_structure, field):
...@@ -1896,14 +1953,25 @@ class PlanningStructure: ...@@ -1896,14 +1953,25 @@ class PlanningStructure:
axis_stop = (self.secondary_axis.stop) axis_stop = (self.secondary_axis.stop)
axis_start = (self.secondary_axis.start) axis_start = (self.secondary_axis.start)
#pdb.set_trace()
axis_script=getattr(basic_structure.here,basic_structure.field.get_value('sec_axis_script'),None) axis_script=getattr(basic_structure.here,
basic_structure.field.get_value('sec_axis_script'),None)
if axis_script == None:
# ERROR
message = 'unable to find secondary axis generation script : "%s" does \
not exist' % basic_structure.field.get_value('sec_axis_script')
return [(Message(domain=None, message=message, mapping=None))]
# calling script to get list of delimiters to implement # calling script to get list of delimiters to implement
# just need to pass start, stop, and the minimum number of delimiter wanted. # just need to pass start, stop, and the minimum number of delimiter
# a structure is returned : list of delimiters, each delimiter defined by a # wanted. a structure is returned : list of delimiters, each delimiter
# list [ relative position, title, tooltip , delimiter_type] # defined by a list [ relative position, title, tooltip , delimiter_type]
delimiter_list = axis_script(axis_start,axis_stop,delimiter_min_number) try:
delimiter_list = axis_script(axis_start,axis_stop,delimiter_min_number)
except (ArithmeticError, LookupError, AttributeError, TypeError):
message = 'error raised in secondary axis generation script : please \
check "%s"'% basic_structure.field.get_value('sec_axis_script')
return [(Message(domain=None, message=message,mapping=None))]
axis_stop = int(axis_stop) axis_stop = int(axis_stop)
axis_start = int(axis_start) axis_start = int(axis_start)
...@@ -1917,12 +1985,15 @@ class PlanningStructure: ...@@ -1917,12 +1985,15 @@ class PlanningStructure:
# group position and size informations are saved in position_secondary # group position and size informations are saved in position_secondary
# using relative coordinates # using relative coordinates
for delimiter in delimiter_list: for delimiter in delimiter_list:
axis_group = AxisGroup(name='Group_sec_' + str(axis_group_number), title=delimiter[1], delimiter_type=delimiter[3]) axis_group = AxisGroup(name='Group_sec_' + str(axis_group_number),
title=delimiter[1], delimiter_type=delimiter[3])
axis_group.tooltip = delimiter[2] axis_group.tooltip = delimiter[2]
axis_group.position_secondary.relative_begin = int(delimiter[0]) - int(axis_start) axis_group.position_secondary.relative_begin = \
int(delimiter[0]) - int(axis_start)
# set defaut stop bound and size # set defaut stop bound and size
axis_group.position_secondary.relative_end = int(axis_stop) axis_group.position_secondary.relative_end = int(axis_stop)
axis_group.position_secondary.relative_range = int(axis_stop) - int(delimiter[0]) axis_group.position_secondary.relative_range = \
int(axis_stop) - int(delimiter[0])
if delimiter == delimiter_list[0]: if delimiter == delimiter_list[0]:
# actual delimiter is the first delimiter entered # actual delimiter is the first delimiter entered
# do not need to update previous delimiter informations # do not need to update previous delimiter informations
...@@ -1930,13 +2001,19 @@ class PlanningStructure: ...@@ -1930,13 +2001,19 @@ class PlanningStructure:
else: else:
# actual delimiter info has a previous delimiter # actual delimiter info has a previous delimiter
# update its informations # update its informations
self.secondary_axis.axis_group[-1].position_secondary.relative_end = axis_group.position_secondary.relative_begin self.secondary_axis.axis_group[-1].position_secondary.relative_end = \
self.secondary_axis.axis_group[-1].position_secondary.relative_range = axis_group.position_secondary.relative_begin - self.secondary_axis.axis_group[-1].position_secondary.relative_begin axis_group.position_secondary.relative_begin
self.secondary_axis.axis_group[-1].position_secondary.relative_range =\
axis_group.position_secondary.relative_begin - \
self.secondary_axis.axis_group[-1].position_secondary.relative_begin
# add current axis_group to axis_group list # add current axis_group to axis_group list
self.secondary_axis.axis_group.append(axis_group) self.secondary_axis.axis_group.append(axis_group)
axis_group_number += 1 axis_group_number += 1
return 1
def completeAxis (self): def completeAxis (self):
""" """
complete axis infomations (and more precisely axis position objects) thanks complete axis infomations (and more precisely axis position objects) thanks
...@@ -1945,9 +2022,15 @@ class PlanningStructure: ...@@ -1945,9 +2022,15 @@ class PlanningStructure:
# processing main axis # processing main axis
for axis_group_element in self.main_axis.axis_group: for axis_group_element in self.main_axis.axis_group:
axis_group_element.position_main.absolute_begin = float(axis_group_element.axis_element_start - 1) / float(self.main_axis.size) axis_group_element.position_main.absolute_begin = (
axis_group_element.position_main.absolute_end = float(axis_group_element.axis_element_stop) / float(self.main_axis.size) float(axis_group_element.axis_element_start - 1) /
axis_group_element.position_main.absolute_range = float(axis_group_element.axis_element_number) / float(self.main_axis.size) float(self.main_axis.size))
axis_group_element.position_main.absolute_end = (
float(axis_group_element.axis_element_stop) /
float(self.main_axis.size))
axis_group_element.position_main.absolute_range = (
float(axis_group_element.axis_element_number) /
float(self.main_axis.size))
axis_group_element.position_secondary.absolute_begin = 0 axis_group_element.position_secondary.absolute_begin = 0
axis_group_element.position_secondary.absolute_end = 1 axis_group_element.position_secondary.absolute_end = 1
axis_group_element.position_secondary.absolute_range= 1 axis_group_element.position_secondary.absolute_range= 1
...@@ -1968,6 +2051,9 @@ class PlanningStructure: ...@@ -1968,6 +2051,9 @@ class PlanningStructure:
axis_group_element.position_main.absolute_end = 1 axis_group_element.position_main.absolute_end = 1
axis_group_element.position_main.absolute_range = 1 axis_group_element.position_main.absolute_range = 1
# returning 'true' flag at the end of the process
return 1
def buildGroups (self, basic_structure=None): def buildGroups (self, basic_structure=None):
...@@ -1979,7 +2065,17 @@ class PlanningStructure: ...@@ -1979,7 +2065,17 @@ class PlanningStructure:
axis_element_already_present=0 axis_element_already_present=0
for basic_group_object in basic_structure.basic_group_list: for basic_group_object in basic_structure.basic_group_list:
axis_group_number += 1 axis_group_number += 1
axis_group = AxisGroup(name='Group_' + str(axis_group_number), title=basic_group_object.title, object = basic_group_object.object, axis_group_number = axis_group_number, is_open=basic_group_object.is_open, is_pure_summary=basic_group_object.is_pure_summary, url = basic_group_object.url,depth = basic_group_object.depth, secondary_axis_start= self.secondary_axis.start, secondary_axis_stop= self.secondary_axis.stop, property_dict = basic_group_object.property_dict) axis_group= AxisGroup(name='Group_' + str(axis_group_number),
title=basic_group_object.title,
object=basic_group_object.object,
axis_group_number = axis_group_number,
is_open=basic_group_object.is_open,
is_pure_summary=basic_group_object.is_pure_summary,
url = basic_group_object.url,
depth=basic_group_object.depth,
secondary_axis_start= self.secondary_axis.start,
secondary_axis_stop= self.secondary_axis.stop,
property_dict = basic_group_object.property_dict)
if self.render_format == 'YX': if self.render_format == 'YX':
axis_group.position_y = axis_group.position_main axis_group.position_y = axis_group.position_main
axis_group.position_x = axis_group.position_secondary axis_group.position_x = axis_group.position_secondary
...@@ -1987,13 +2083,12 @@ class PlanningStructure: ...@@ -1987,13 +2083,12 @@ class PlanningStructure:
axis_group.position_y = axis_group.position_secondary axis_group.position_y = axis_group.position_secondary
axis_group.position_x = axis_group.position_main axis_group.position_x = axis_group.position_main
# init absolute position over the axis # init absolute position over the axis
# XXX if a special axisGroup length is needed (statistics, or report_tree),
# then it should be implemented here.
axis_group.position_secondary.absolute_begin = 0 axis_group.position_secondary.absolute_begin = 0
axis_group.position_secondary.absolute_end= 1 axis_group.position_secondary.absolute_end= 1
axis_group.position_secondary.absolute_range = 1 axis_group.position_secondary.absolute_range = 1
# updating axis_group properties # updating axis_group properties
axis_group.fixProperties(form_id = basic_structure.form.id, selection_name = basic_structure.selection_name) axis_group.fixProperties(form_id = basic_structure.form.id,
selection_name = basic_structure.selection_name)
# updating start value # updating start value
axis_group.axis_element_start = axis_element_already_present + 1 axis_group.axis_element_start = axis_element_already_present + 1
activity_number = 0 activity_number = 0
...@@ -2006,30 +2101,53 @@ class PlanningStructure: ...@@ -2006,30 +2101,53 @@ class PlanningStructure:
for basic_activity_object in basic_group_object.basic_activity_list: for basic_activity_object in basic_group_object.basic_activity_list:
activity_number += 1 activity_number += 1
# create new activity in the PlanningStructure # create new activity in the PlanningStructure
activity = Activity(name='Group_' + str(axis_group_number) + '_Activity_' + str(activity_number), title=basic_activity_object.title, object=basic_activity_object.object, color=basic_activity_object.color, link=basic_activity_object.url, secondary_axis_begin=basic_activity_object.absolute_begin, secondary_axis_end=basic_activity_object.absolute_end, secondary_axis_start=basic_activity_object.absolute_start, secondary_axis_stop=basic_activity_object.absolute_stop, primary_axis_block=self, info=basic_activity_object.info_dict, render_format=self.render_format, property_dict = basic_group_object.property_dict) activity=Activity(name='Group_%s_Activity_%s' %(
str(axis_group_number),
str(activity_number)),
title=basic_activity_object.title,
object=basic_activity_object.object,
color=basic_activity_object.color,
link=basic_activity_object.url,
secondary_axis_begin= \
basic_activity_object.absolute_begin,
secondary_axis_end= \
basic_activity_object.absolute_end,
secondary_axis_start= \
basic_activity_object.absolute_start,
secondary_axis_stop= \
basic_activity_object.absolute_stop,
primary_axis_block=self,
info=basic_activity_object.info_dict,
render_format=self.render_format,
property_dict=basic_group_object.property_dict)
# adding activity to the current group # adding activity to the current group
axis_group.addActivity(activity,axis_element_already_present) axis_group.addActivity(activity,axis_element_already_present)
else: else:
# case group is stat group. Using special method that prevent # case group is stat group. Using special method that prevent
# from generating more than 1 axis element and divide tasks size if # from generating more than 1 axis element and divide tasks size if
# necessary # necessary
axis_group.addStatActivities(basic_activity_list=basic_group_object.basic_activity_list, axis_group.addStatActivities(
basic_activity_list=basic_group_object.basic_activity_list,
axis_group_number=axis_group_number, axis_group_number=axis_group_number,
axis_element_already_present = axis_element_already_present, axis_element_already_present=axis_element_already_present,
render_format = self.render_format, render_format=self.render_format, primary_axis_block=self,
primary_axis_block=self, property_dict=basic_group_object.property_dict)
property_dict = basic_group_object.property_dict)
else: else:
# basic_activity_list is empty : need to add a empty axis_element to # basic_activity_list is empty : need to add a empty axis_element to
# prevent bug or crash # prevent bug or crash
axis_group.axis_element_number = 1 axis_group.axis_element_number = 1
new_axis_element = AxisElement(name='Group_' + str(axis_group_number) + '_AxisElement_1', relative_number= 1 , absolute_number = axis_group.axis_element_start, parent_axis_group=axis_group) new_axis_element=AxisElement(name='Group_%s_AxisElement_1' %
str(axis_group_number),
relative_number= 1,
absolute_number=axis_group.axis_element_start,
parent_axis_group=axis_group)
# add new activity to this brand new axis_element # add new activity to this brand new axis_element
new_axis_element.activity_list = [] new_axis_element.activity_list = []
axis_group.axis_element_list = [] axis_group.axis_element_list = []
axis_group.axis_element_list.append(new_axis_element) axis_group.axis_element_list.append(new_axis_element)
axis_group.axis_element_stop = axis_element_already_present + axis_group.axis_element_number axis_group.axis_element_stop = (axis_element_already_present +
axis_group.axis_element_number)
axis_element_already_present = axis_group.axis_element_stop axis_element_already_present = axis_group.axis_element_stop
try: try:
self.main_axis.axis_group.append(axis_group) self.main_axis.axis_group.append(axis_group)
...@@ -2049,8 +2167,6 @@ class PlanningStructure: ...@@ -2049,8 +2167,6 @@ class PlanningStructure:
error_block_list = REQUEST.get('error_block_list',[]) error_block_list = REQUEST.get('error_block_list',[])
error_info_dict = REQUEST.get('error_info_dict',{}) error_info_dict = REQUEST.get('error_info_dict',{})
for axis_group_object in self.main_axis.axis_group: for axis_group_object in self.main_axis.axis_group:
for axis_element_object in axis_group_object.axis_element_list: for axis_element_object in axis_group_object.axis_element_list:
for activity in axis_element_object.activity_list: for activity in axis_element_object.activity_list:
...@@ -2059,14 +2175,21 @@ class PlanningStructure: ...@@ -2059,14 +2175,21 @@ class PlanningStructure:
else: else:
warning = 0 warning = 0
# generate activity_info # generate activity_info
activity.addBlocs(main_axis_start=0, main_axis_stop=self.main_axis.size, secondary_axis_start=self.secondary_axis.start, secondary_axis_stop=self.secondary_axis.stop,planning=self, warning=warning, error_block_list=error_block_list, error_info_dict=error_info_dict) status = activity.addBlocs(main_axis_start=0,
main_axis_stop=self.main_axis.size,
secondary_axis_start=self.secondary_axis.start,
secondary_axis_stop=self.secondary_axis.stop,
planning=self, warning=warning,
error_block_list=error_block_list,
error_info_dict=error_info_dict)
if status !=1: return status
if axis_group_object.property_dict['stat'] == 1: if axis_group_object.property_dict['stat'] == 1:
# case stat group_object, need to update block size to display # case stat group_object, need to update block size to display
# stats informations # stats informations
axis_group_object.updateStatBlocks() status = axis_group_object.updateStatBlocks()
if status !=1: return status
# no problem during process, returning 'true' flag
return 1
class Activity: class Activity:
...@@ -2078,7 +2201,11 @@ class Activity: ...@@ -2078,7 +2201,11 @@ class Activity:
structure is used for rebuilding tasks from bloc positions when structure is used for rebuilding tasks from bloc positions when
validating the Planning. validating the Planning.
""" """
def __init__ (self,name=None, title=None, object=None, types=None, color=None, link=None, height=None, secondary_axis_begin=None, secondary_axis_end=None, secondary_axis_start=None, secondary_axis_stop=None, primary_axis_block=None, info=None, render_format='YX', property_dict={} ): def __init__ (self,name=None, title=None, object=None, types=None,
color=None, link=None, height=None, secondary_axis_begin=None,
secondary_axis_end=None, secondary_axis_start=None,
secondary_axis_stop=None, primary_axis_block=None, info=None,
render_format='YX', property_dict={} ):
self.name = name # internal activity_name self.name = name # internal activity_name
self.id = self.name self.id = self.name
self.title = title # displayed activity_name self.title = title # displayed activity_name
...@@ -2113,28 +2240,37 @@ class Activity: ...@@ -2113,28 +2240,37 @@ class Activity:
- 1 if partially ( need to cut the activity bounds to make it fit) - 1 if partially ( need to cut the activity bounds to make it fit)
- 2 definitely - 2 definitely
""" """
if self.secondary_axis_begin > bound_end or self.secondary_axis_end < bound_begin: if (self.secondary_axis_begin > bound_end) or \
(self.secondary_axis_end < bound_begin):
return 0 return 0
elif self.secondary_axis_begin > bound_begin and self.secondary_axis_end < bound_end: elif (self.secondary_axis_begin > bound_begin) and \
(self.secondary_axis_end < bound_end):
return 1 return 1
else: else:
return 2 return 2
def addBlocs(self, main_axis_start=None, main_axis_stop=None, secondary_axis_start=None, secondary_axis_stop=None,planning=None, warning=0, error_block_list=[], error_info_dict={}):
def addBlocs(self, main_axis_start=None, main_axis_stop=None,
secondary_axis_start=None,
secondary_axis_stop=None,planning=None, warning=0,
error_block_list=[], error_info_dict={}):
""" """
define list of (begin & stop) values for blocs representing the actual define list of (begin & stop) values for blocs representing the actual
activity (can have several blocs if necessary). activity (can have several blocs if necessary).
""" """
# recover list of bounds # recover list of bounds
if self.secondary_axis_start != None or self.secondary_axis_stop != None: if self.secondary_axis_start != None or self.secondary_axis_stop != None:
#split_method_name = field.get_value('split_method',None)
#split_method = getattr(self.object,split_method_name, None)
#if split_method != None:
secondary_block_bounds = self.splitActivity() secondary_block_bounds = self.splitActivity()
#split_method_name = field.get_value('split_method',None) #secondary_block_bounds = split_method(self.secondary_axis_start,
#split_method = getattr(self.object,split_method_name, None) # self.secondary_axis_stop)
#if split_method != None:
# secondary_block_bounds = split_method(self.secondary_axis_start, self.secondary_axis_stop)
else: else:
secondary_block_bounds = [[self.secondary_axis_start,self.secondary_axis_stop,1]] secondary_block_bounds = \
[[self.secondary_axis_start,self.secondary_axis_stop,1]]
block_number = 0 block_number = 0
# iterating resulting list # iterating resulting list
...@@ -2152,11 +2288,8 @@ class Activity: ...@@ -2152,11 +2288,8 @@ class Activity:
error = 0 error = 0
error_text='' error_text=''
# zone property is used to check if block is a representative block or a # zone property is used to check if block is an active (main activity
# display block. This value is associaded to each block returned through # block) block or a passive one (just a display block)
# the splitActivity function.
# representative => standard block representing an active part of the task
# display => block representing a passive part of the task (week end, etc.)
if zone == 1: if zone == 1:
# active # active
block_color = self.color block_color = self.color
...@@ -2166,8 +2299,12 @@ class Activity: ...@@ -2166,8 +2299,12 @@ class Activity:
block_color = '#D1E8FF' block_color = '#D1E8FF'
block_link = '' block_link = ''
new_block = Bloc(name= block_name,color=block_color,link=block_link, number = block_number, render_format=self.render_format, parent_activity=self, warning=warning, error=error, error_text=error_text,zone=zone, property_dict = self.property_dict) new_block = Bloc(name= block_name,color=block_color,link=block_link,
number = block_number,
render_format=self.render_format, parent_activity=self,
warning=warning, error=error,
error_text=error_text,zone=zone,
property_dict=self.property_dict)
new_block.buildInfoDict(info_dict = self.info) new_block.buildInfoDict(info_dict = self.info)
...@@ -2182,24 +2319,36 @@ class Activity: ...@@ -2182,24 +2319,36 @@ class Activity:
new_block.position_secondary.absolute_end = secondary_axis_stop new_block.position_secondary.absolute_end = secondary_axis_stop
new_block.position_secondary.absolute_range = stop - start new_block.position_secondary.absolute_range = stop - start
# updating main_axis block position # updating main_axis block position
new_block.position_main.absolute_begin = self.parent_axis_element.absolute_number - 1 new_block.position_main.absolute_begin = \
new_block.position_main.absolute_end = self.parent_axis_element.absolute_number self.parent_axis_element.absolute_number - 1
new_block.position_main.absolute_range = new_block.position_main.absolute_end - new_block.position_main.absolute_begin new_block.position_main.absolute_end = \
self.parent_axis_element.absolute_number
new_block.position_main.absolute_range = (
new_block.position_main.absolute_end -
new_block.position_main.absolute_begin)
# now absolute positions are updated, and the axis values are known # now absolute positions are updated, and the axis values are known
# (as parameters), processing relative values # (as parameters), processing relative values
new_block.position_secondary.relative_begin = \ new_block.position_secondary.relative_begin = (
float(new_block.position_secondary.absolute_begin - secondary_axis_start) / float(secondary_axis_stop - secondary_axis_start) float(new_block.position_secondary.absolute_begin -
new_block.position_secondary.relative_end = \ secondary_axis_start) / float(secondary_axis_stop -
float(new_block.position_secondary.absolute_end - secondary_axis_start) / float(secondary_axis_stop - secondary_axis_start) secondary_axis_start))
new_block.position_secondary.relative_range = \ new_block.position_secondary.relative_end = (
new_block.position_secondary.relative_end - new_block.position_secondary.relative_begin float(new_block.position_secondary.absolute_end -
new_block.position_main.relative_begin = \ secondary_axis_start) / float(secondary_axis_stop -
float(new_block.position_main.absolute_begin - main_axis_start) / float(main_axis_stop - main_axis_start) secondary_axis_start))
new_block.position_main.relative_end = \ new_block.position_secondary.relative_range = (
float(new_block.position_main.absolute_end - main_axis_start) / float(main_axis_stop - main_axis_start) new_block.position_secondary.relative_end -
new_block.position_main.relative_range = \ new_block.position_secondary.relative_begin)
new_block.position_main.relative_end - new_block.position_main.relative_begin new_block.position_main.relative_begin = (
float(new_block.position_main.absolute_begin - main_axis_start) /
float(main_axis_stop - main_axis_start))
new_block.position_main.relative_end = (
float(new_block.position_main.absolute_end - main_axis_start) /
float(main_axis_stop - main_axis_start))
new_block.position_main.relative_range = (
new_block.position_main.relative_end -
new_block.position_main.relative_begin)
try: try:
self.block_list.append(new_block) self.block_list.append(new_block)
...@@ -2215,6 +2364,8 @@ class Activity: ...@@ -2215,6 +2364,8 @@ class Activity:
planning.content = [] planning.content = []
planning.content.append(new_block) planning.content.append(new_block)
return 1
def splitActivity(self): def splitActivity(self):
""" """
Used for splitting an activity in multiple bloc. Used for splitting an activity in multiple bloc.
...@@ -2228,9 +2379,6 @@ class Activity: ...@@ -2228,9 +2379,6 @@ class Activity:
# XXX not implemented yet # XXX not implemented yet
return [(self.secondary_axis_start,self.secondary_axis_stop,1)] return [(self.secondary_axis_start,self.secondary_axis_stop,1)]
#XXX current script cuts activities into several blocks representing the worked days
returned_list = [] returned_list = []
...@@ -2284,16 +2432,13 @@ class Activity: ...@@ -2284,16 +2432,13 @@ class Activity:
class Bloc: class Bloc:
""" """
structure that will be rendered as a bloc, a task element. structure that will be rendered as a bloc, a task element.
Blocs are referenced in the Activity they belong to (logical structure), Blocs are referenced in the Activity they belong to (logical structure), but
but are also referenced in their relative AxisElement (to be able to are also referenced in their relative AxisElement (to be able to calculate
calculate the number of lines required for rendering when having the number of lines required for rendering when having multi-tasking in
multi-tasking in parallel). parallel).
Contains Bloc Structure for position informations. Contains Bloc Structure for position informations.
""" """
...@@ -2312,7 +2457,7 @@ class Bloc: ...@@ -2312,7 +2457,7 @@ class Bloc:
self.link = link # on clic link self.link = link # on clic link
self.number = number self.number = number
self.title='' self.title=''
self.zone = zone # 1 = usefull area : 0 = useless one => splitting activities self.zone = zone # 1 = usefull area : 0 = useless one
self.parent_activity = parent_activity self.parent_activity = parent_activity
self.constraints = constraints self.constraints = constraints
# setting warning and error flags in case parent_activity or block itself # setting warning and error flags in case parent_activity or block itself
...@@ -2325,7 +2470,8 @@ class Bloc: ...@@ -2325,7 +2470,8 @@ class Bloc:
# integer pointing to the AxisElement containing the bloc (multitasking) # integer pointing to the AxisElement containing the bloc (multitasking)
#self.container_axis_element = container_AxisElement #self.container_axis_element = container_AxisElement
self.position_main = Position() self.position_main = Position()
self.position_secondary = Position(absolute_begin=secondary_start,absolute_end=secondary_stop) self.position_secondary = \
Position(absolute_begin=secondary_start,absolute_end=secondary_stop)
if render_format == 'YX': if render_format == 'YX':
self.position_y = self.position_main self.position_y = self.position_main
self.position_x = self.position_secondary self.position_x = self.position_secondary
...@@ -2337,9 +2483,9 @@ class Bloc: ...@@ -2337,9 +2483,9 @@ class Bloc:
def buildInfoDict (self, info_dict=[]): def buildInfoDict (self, info_dict=[]):
""" """
create Info objects to display text & images, then link them to the current object create Info objects to display text & images, then link them to the
current object
""" """
#XXX /4
# updating title # updating title
if self.property_dict['stat'] == 1: if self.property_dict['stat'] == 1:
...@@ -2348,11 +2494,16 @@ class Bloc: ...@@ -2348,11 +2494,16 @@ class Bloc:
else: else:
self.info = {} self.info = {}
title_list = [] title_list = []
title_list.append(self.buildInfo(info_dict=info_dict, area='info_topleft')) title_list.append(
title_list.append(self.buildInfo(info_dict=info_dict, area='info_topright')) self.buildInfo(info_dict=info_dict, area='info_topleft'))
title_list.append(self.buildInfo(info_dict=info_dict, area='info_center')) title_list.append(
title_list.append(self.buildInfo(info_dict=info_dict, area='info_botleft')) self.buildInfo(info_dict=info_dict, area='info_topright'))
title_list.append(self.buildInfo(info_dict=info_dict, area='info_botright')) title_list.append(
self.buildInfo(info_dict=info_dict, area='info_center'))
title_list.append(
self.buildInfo(info_dict=info_dict, area='info_botleft'))
title_list.append(
self.buildInfo(info_dict=info_dict, area='info_botright'))
self.title = " | ".join(title_list) self.title = " | ".join(title_list)
...@@ -2379,9 +2530,9 @@ class Position: ...@@ -2379,9 +2530,9 @@ class Position:
with lower and upper bound. with lower and upper bound.
""" """
def __init__ (self, absolute_begin=None, def __init__ (self, absolute_begin=None, absolute_end=None,
absolute_end=None, absolute_range=None, absolute_range=None, relative_begin=None, relative_end=None,
relative_begin=None, relative_end=None, relative_range=None): relative_range=None):
# absolute size takes the bloc size in the original unit for the axis # absolute size takes the bloc size in the original unit for the axis
self.absolute_begin = absolute_begin self.absolute_begin = absolute_begin
self.absolute_end = absolute_end self.absolute_end = absolute_end
...@@ -2401,7 +2552,8 @@ class Axis: ...@@ -2401,7 +2552,8 @@ class Axis:
In case of listed axis, holds AxisGroup Structure. In case of listed axis, holds AxisGroup Structure.
""" """
def __init__(self, title=None, unit=None, types=None, axis_order=None, name=None, axis_group=None): def __init__(self, title=None, unit=None, types=None, axis_order=None,
name=None, axis_group=None):
self.title = title # axis title self.title = title # axis title
self.unit = unit # unit kind (time, nb... person, task, etc.) self.unit = unit # unit kind (time, nb... person, task, etc.)
self.types = types # continuous / listed (incl. ReportTree) self.types = types # continuous / listed (incl. ReportTree)
...@@ -2432,13 +2584,17 @@ class AxisGroup: ...@@ -2432,13 +2584,17 @@ class AxisGroup:
def __init__ (self, name='', title='', object = None, def __init__ (self, name='', title='', object = None,
axis_group_list=None, axis_group_number=0, axis_group_list=None, axis_group_number=0,
axis_element_list=None, axis_element_number=0, delimiter_type = 0, is_open=0, is_pure_summary=1,depth=0, url=None, axis_element_already_insered= 0, secondary_axis_start=None, secondary_axis_stop=None, property_dict={}): axis_element_list=None, axis_element_number=0,
delimiter_type=0, is_open=0, is_pure_summary=1,depth=0,
url=None, axis_element_already_insered= 0,
secondary_axis_start=None, secondary_axis_stop=None,
property_dict={}):
self.name = name self.name = name
self.title = title self.title = title
self.link = None # link to fold or unfold current report in report-tree mode self.link = None # link to fold or unfold report in report-tree mode
self.info_title = Info(info=self.title, link=self.link, title=self.title) self.info_title = Info(info=self.title, link=self.link, title=self.title)
self.tooltip = '' # tooltip used when cursor pass over the group self.tooltip = '' # tooltip used when cursor pass over the group
self.object = object # physical object related to the current group (used to validate modifications) self.object = object # ZODB object used to validate modifications
self.axis_group_list = axis_group_list # ReportTree self.axis_group_list = axis_group_list # ReportTree
self.axis_group_number = axis_group_number self.axis_group_number = axis_group_number
self.axis_element_list = axis_element_list # Multitasking self.axis_element_list = axis_element_list # Multitasking
...@@ -2453,7 +2609,7 @@ class AxisGroup: ...@@ -2453,7 +2609,7 @@ class AxisGroup:
self.is_open = is_open self.is_open = is_open
self.is_pure_summary = is_pure_summary self.is_pure_summary = is_pure_summary
self.depth = depth self.depth = depth
self.url = url # url of the object corresponding to the current axis_group (person, projetc line, etc.) self.url = url # url to the object
self.position_main = Position() self.position_main = Position()
self.position_secondary = Position() self.position_secondary = Position()
...@@ -2479,11 +2635,15 @@ class AxisGroup: ...@@ -2479,11 +2635,15 @@ class AxisGroup:
if self.is_open: if self.is_open:
# current report is unfold, action 'fold' # current report is unfold, action 'fold'
self.info_title.link = 'portal_selections/foldReport?report_url=' + self.url + '&form_id='+ form_id + '&list_selection_name=' + selection_name self.info_title.link = 'portal_selections/foldReport?report_url=' + \
'%s&form_id=%s&list_selection_name=%s' %(
self.url, form_id, selection_name)
self.info_title.info = '[-] ' + self.info_title.info self.info_title.info = '[-] ' + self.info_title.info
else: else:
# current report is fold, action 'unfold' # current report is fold, action 'unfold'
self.info_title.link = 'portal_selections/unfoldReport?report_url=' + self.url + '&form_id='+ form_id + '&list_selection_name=' + selection_name self.info_title.link = 'portal_selections/unfoldReport?report_url=' + \
'%s&form_id=%s&list_selection_name=%s' %(
self.url, form_id, selection_name)
self.info_title.info = '[+] ' + self.info_title.info self.info_title.info = '[+] ' + self.info_title.info
#for i in range(self.depth): #for i in range(self.depth):
...@@ -2511,7 +2671,8 @@ class AxisGroup: ...@@ -2511,7 +2671,8 @@ class AxisGroup:
# iterating through them to check if one of them crosses the new one # iterating through them to check if one of them crosses the new one
for activity_statement in axis_element.activity_list: for activity_statement in axis_element.activity_list:
if activity_statement.isValidPosition(activity.secondary_axis_begin, activity.secondary_axis_end) != 0: if activity_statement.isValidPosition(activity.secondary_axis_begin,
activity.secondary_axis_end) != 0:
# isValidPosition returned 1 or 2, this means the activity already # isValidPosition returned 1 or 2, this means the activity already
# present does prevent from adding the new activity as there is # present does prevent from adding the new activity as there is
# coverage on the current axis_element. # coverage on the current axis_element.
...@@ -2529,16 +2690,21 @@ class AxisGroup: ...@@ -2529,16 +2690,21 @@ class AxisGroup:
# updating activity properties # updating activity properties
activity.parent_axis_element = axis_element activity.parent_axis_element = axis_element
# no need to check the next axis_elements to know if they can hold the # no need to check the next axis_elements to know if they can hold
# new activity as it is already added to an axis_element # the new activity as it is already added to an axis_element
break break
if not added: if not added:
# all axis_elements of the current group have been tested and no one can # all axis_elements of the current group have been tested and no one
# contain the new activity. # can contain the new activity.
self.axis_element_number += 1 self.axis_element_number += 1
# Need to create a new axis_element to hold the new activity # Need to create a new axis_element to hold the new activity
new_axis_element = AxisElement(name='Group_' + str(self.axis_group_number) + '_AxisElement_' + str(self.axis_element_number), relative_number=self.axis_element_number, absolute_number=axis_element_already_insered + self.axis_element_number) new_axis_element=AxisElement(name='Group_%s_AxisElement_%s'%
(str(self.axis_group_number),
str(self.axis_element_number)),
relative_number=self.axis_element_number,
absolute_number=self.axis_element_number+
axis_element_already_insered)
# add new activity to this brand new axis_element # add new activity to this brand new axis_element
new_axis_element.activity_list = [] new_axis_element.activity_list = []
...@@ -2553,7 +2719,14 @@ class AxisGroup: ...@@ -2553,7 +2719,14 @@ class AxisGroup:
# in case axis_element_list is Empty (first activity to the group) # in case axis_element_list is Empty (first activity to the group)
# Need to create a new axis_element to hold the new activity # Need to create a new axis_element to hold the new activity
self.axis_element_number += 1 self.axis_element_number += 1
new_axis_element = AxisElement(name='Group_' + str(self.axis_group_number) + '_AxisElement_1', relative_number= self.axis_element_number, absolute_number = axis_element_already_insered + self.axis_element_number, parent_axis_group=self) new_axis_element = AxisElement(name='Group_%s_AxisElement_1' %
str(self.axis_group_number),
relative_number=\
self.axis_element_number,
absolute_number =\
axis_element_already_insered +
self.axis_element_number,
parent_axis_group=self)
# add new activity to this brand new axis_element # add new activity to this brand new axis_element
new_axis_element.activity_list = [] new_axis_element.activity_list = []
...@@ -2567,14 +2740,21 @@ class AxisGroup: ...@@ -2567,14 +2740,21 @@ class AxisGroup:
self.axis_element_list.append(new_axis_element) self.axis_element_list.append(new_axis_element)
def addStatActivities(self, basic_activity_list=None, axis_group_number=0, axis_element_already_present= 0, render_format=None, primary_axis_block=None, property_dict={}): def addStatActivities(self, basic_activity_list=None, axis_group_number=0,
axis_element_already_present= 0, render_format=None,
primary_axis_block=None, property_dict={}):
""" """
Permits to add stat block to the current AxisGroup. In this way use the Permits to add stat block to the current AxisGroup. In this way use the
single AxisElement present to fit the blocks single AxisElement present to fit the blocks
""" """
# first adding axis_element to the current group # first adding axis_element to the current group
self.axis_element_number += 1 self.axis_element_number += 1
new_axis_element=AxisElement(name='Group_' + str(self.axis_group_number) + '_AxisElement_1', relative_number=self.axis_element_number, absolute_number=axis_element_already_present + self.axis_element_number, parent_axis_group=self) new_axis_element=AxisElement(name='Group_%s_AxisElement_1' %
str(self.axis_group_number),
relative_number=self.axis_element_number,
absolute_number=axis_element_already_present+
self.axis_element_number,
parent_axis_group=self)
new_axis_element.activity_list = [] new_axis_element.activity_list = []
self.axis_element_list = [] self.axis_element_list = []
...@@ -2585,16 +2765,21 @@ class AxisGroup: ...@@ -2585,16 +2765,21 @@ class AxisGroup:
for basic_activity_object in basic_activity_list: for basic_activity_object in basic_activity_list:
# defining Activity from basic_activity_object # defining Activity from basic_activity_object
activity = Activity(name= 'Group_%s_Activity_%s' %(str(axis_group_number), activity = Activity(name= 'Group_%s_Activity_%s'
str(activity_number)), %(str(axis_group_number),
str(activity_number)),
title=basic_activity_object.title, title=basic_activity_object.title,
object=basic_activity_object.object, object=basic_activity_object.object,
color=basic_activity_object.color, color=basic_activity_object.color,
link=basic_activity_object.url, link=basic_activity_object.url,
secondary_axis_begin=basic_activity_object.absolute_begin, secondary_axis_begin=\
secondary_axis_end=basic_activity_object.absolute_end, basic_activity_object.absolute_begin,
secondary_axis_start=basic_activity_object.absolute_start, secondary_axis_end=\
secondary_axis_stop=basic_activity_object.absolute_stop, basic_activity_object.absolute_end,
secondary_axis_start=\
basic_activity_object.absolute_start,
secondary_axis_stop=\
basic_activity_object.absolute_stop,
height=basic_activity_object.height, height=basic_activity_object.height,
primary_axis_block=primary_axis_block, primary_axis_block=primary_axis_block,
info=basic_activity_object.info_dict, info=basic_activity_object.info_dict,
...@@ -2642,7 +2827,7 @@ class AxisGroup: ...@@ -2642,7 +2827,7 @@ class AxisGroup:
# saving new values # saving new values
block.position_main.relative_begin = final_begin block.position_main.relative_begin = final_begin
block.position_main.relative_range = final_range block.position_main.relative_range = final_range
return 1
class AxisElement: class AxisElement:
...@@ -2655,9 +2840,10 @@ class AxisElement: ...@@ -2655,9 +2840,10 @@ class AxisElement:
existing AxisElement or if it is needed to create a new AxisElement in existing AxisElement or if it is needed to create a new AxisElement in
the AxisGroup to hold it. the AxisGroup to hold it.
""" """
def __init__ (self,name='', relative_number=0, absolute_number=0, activity_list=None, parent_axis_group = None): def __init__ (self,name='', relative_number=0, absolute_number=0,
activity_list=None, parent_axis_group = None):
self.name = name self.name = name
self.relative_number = relative_number # personal AxisElement id in the AxisGroup self.relative_number = relative_number # relative number / AxisGroup
self.absolute_number = absolute_number # id in the current rendering self.absolute_number = absolute_number # id in the current rendering
self.activity_list = activity_list self.activity_list = activity_list
# dict containing all class properties with their values # dict containing all class properties with their values
...@@ -2667,11 +2853,10 @@ class AxisElement: ...@@ -2667,11 +2853,10 @@ class AxisElement:
class Info: class Info:
""" """
Class holding all informations to display an info text div inside of a block or Class holding all informations to display an info text div inside of a block
AxisGroup or whatever or AxisGroup or whatever
""" """
security = ClassSecurityInfo() security = ClassSecurityInfo()
def __init__(self, info=None, link=None, title=None): def __init__(self, info=None, link=None, title=None):
self.info = info self.info = info
self.link = link self.link = link
...@@ -2705,6 +2890,8 @@ class PlanningBox(ZMIField): ...@@ -2705,6 +2890,8 @@ class PlanningBox(ZMIField):
return self.widget.render_css(self,'',value,REQUEST) return self.widget.render_css(self,'',value,REQUEST)
InitializeClass(PlanningBoxWidget)
allow_class(PlanningBoxWidget)
InitializeClass(BasicStructure) InitializeClass(BasicStructure)
allow_class(BasicStructure) allow_class(BasicStructure)
InitializeClass(BasicGroup) InitializeClass(BasicGroup)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment