Commit 2ac4dc85 authored by Yusuke Muraoka's avatar Yusuke Muraoka

ERP5Report is splitted to normal ERP5Form and ReportBox

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@28671 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 085c3b2f
...@@ -671,6 +671,7 @@ class ProxyField(ZMIField): ...@@ -671,6 +671,7 @@ class ProxyField(ZMIField):
# defined by a TALES # defined by a TALES
if self._p_oid is None or self.tales['field_id'] or self.tales['form_id']: if self._p_oid is None or self.tales['field_id'] or self.tales['form_id']:
return self._get_value(id, **kw) return self._get_value(id, **kw)
# XXX: Are these disabled?
proxy_field = self.getTemplateField(cache=False) proxy_field = self.getTemplateField(cache=False)
if proxy_field is not None: if proxy_field is not None:
return proxy_field.get_value(id, **kw) return proxy_field.get_value(id, **kw)
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
from Globals import InitializeClass, DTMLFile, get_request from Globals import InitializeClass, DTMLFile, get_request
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Acquisition import aq_base
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
from Products.Formulator.DummyField import fields from Products.Formulator.DummyField import fields
from Products.Formulator.Form import ZMIForm from Products.Formulator.Form import ZMIForm
...@@ -123,6 +124,7 @@ class ERP5Report(ERP5Form): ...@@ -123,6 +124,7 @@ class ERP5Report(ERP5Form):
# Proxy method to PageTemplate # Proxy method to PageTemplate
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
warn("ERP5Report to be obsolete, please use ReportBox and normal ERP5Form instead.", DeprecationWarning)
if not self.report_method: if not self.report_method:
raise KeyError, 'report method is not set on the report' raise KeyError, 'report method is not set on the report'
...@@ -205,7 +207,8 @@ class ReportSection: ...@@ -205,7 +207,8 @@ class ReportSection:
selection_stats=None, selection_stats=None,
selection_sort_order=None, selection_sort_order=None,
selection_report_path=None, selection_report_path=None,
selection_report_list=None): selection_report_list=None,
temporary_selection=True):
""" """
Initialize the line and set the default values Initialize the line and set the default values
Selected columns must be defined in parameter of listbox.render... Selected columns must be defined in parameter of listbox.render...
...@@ -213,6 +216,8 @@ class ReportSection: ...@@ -213,6 +216,8 @@ class ReportSection:
In ReportTree listbox display mode, you can override : In ReportTree listbox display mode, you can override :
selection_report_path, the root category for this report selection_report_path, the root category for this report
selection_report_list, the list of unfolded categories (defaults to all) selection_report_list, the list of unfolded categories (defaults to all)
If temporary_selection is False, the selection will be written which is specified by selection_name.
""" """
self.path = path self.path = path
...@@ -222,20 +227,18 @@ class ReportSection: ...@@ -222,20 +227,18 @@ class ReportSection:
warn("Don't use translated_title, but title directly", DeprecationWarning) warn("Don't use translated_title, but title directly", DeprecationWarning)
self.translated_title = translated_title self.translated_title = translated_title
self.level = level self.level = level
self.saved_request = {}
self.selection_name = selection_name self.selection_name = selection_name
self.selection_params = selection_params self.selection_params = selection_params
self.listbox_display_mode = listbox_display_mode self.listbox_display_mode = listbox_display_mode
self.selection_columns = selection_columns self.selection_columns = selection_columns
self.selection_stats = selection_stats self.selection_stats = selection_stats
self.selection_sort_order = selection_sort_order self.selection_sort_order = selection_sort_order
self.saved_selections = {}
self.selection_report_path = selection_report_path self.selection_report_path = selection_report_path
self.selection_report_list = selection_report_list self.selection_report_list = selection_report_list
self.saved_request_form = {}
self.param_dict = param_dict or {} self.param_dict = param_dict or {}
self.param_list = param_list or [] self.param_list = param_list or []
self.method_id = method_id self.method_id = method_id
self.temporary_selection = temporary_selection
security.declarePublic('getTitle') security.declarePublic('getTitle')
def getTitle(self): def getTitle(self):
...@@ -266,17 +269,36 @@ class ReportSection: ...@@ -266,17 +269,36 @@ class ReportSection:
def getFormId(self): def getFormId(self):
return self.form_id return self.form_id
_no_parameter_ = [] def pushRequest(self):
self = aq_base(self)
if hasattr(self, '_REQUEST'):
raise ValueError, "can not replace the backupped REQUEST"
self._REQUEST = {'form': {}, 'other': {},}
REQUEST = get_request()
self._REQUEST['form'].update(REQUEST.form)
self._REQUEST['other'].update(REQUEST.other)
REQUEST.form.update(self.param_dict)
def popRequest(self):
self = aq_base(self)
if not hasattr(self, '_REQUEST'):
raise ValueError, "no backupped REQUEST"
REQUEST = get_request()
REQUEST.form.clear()
REQUEST.other.clear()
REQUEST.form.update(self._REQUEST['form'])
REQUEST.other.update(self._REQUEST['other'])
del self._REQUEST
security.declarePublic('pushReport') security.declarePublic('pushReport')
def pushReport(self, context, render_prefix=None): def pushReport(self, context, render_prefix=None):
REQUEST = get_request() self.pushRequest()
for k,v in self.param_dict.items():
self.saved_request[k] = REQUEST.form.get(k, self._no_parameter_)
REQUEST.form[k] = v
REQUEST = get_request()
portal_selections = context.portal_selections portal_selections = context.portal_selections
selection_list = [self.selection_name] selection_list = [self.selection_name]
# when the Form which is specified by form_id, has a listbox, make prefixed_selection_name.
# which is based on specified selection_name in the listbox.
if self.getFormId() and hasattr(context[self.getFormId()], 'listbox') : if self.getFormId() and hasattr(context[self.getFormId()], 'listbox') :
selection_name = context[self.getFormId()].listbox.get_value('selection_name') selection_name = context[self.getFormId()].listbox.get_value('selection_name')
if render_prefix is not None: if render_prefix is not None:
...@@ -285,62 +307,46 @@ class ReportSection: ...@@ -285,62 +307,46 @@ class ReportSection:
selection_list += [selection_name] selection_list += [selection_name]
# save report's selection and orignal form's selection, # save report's selection and orignal form's selection,
#as ListBox will overwrite it #as ListBox will overwrite it
for selection_name in selection_list : for selection_name in filter(lambda x: x is not None, selection_list):
if selection_name is not None : if self.temporary_selection:
if not self.saved_selections.has_key(selection_name) : portal_selections.pushSelection(selection_name)
self.saved_selections[selection_name] = {} else:
if self.selection_report_list is not None: if portal_selections.getSelectionFor(selection_name) is None:
selection = portal_selections.getSelectionFor(selection_name, portal_selections.setSelectionFor(selection_name, Selection())
REQUEST=REQUEST)
if selection is None: if self.selection_report_list is not None:
selection = Selection() selection = portal_selections.getSelectionFor(selection_name,
portal_selections.setSelectionFor(selection_name, selection, REQUEST=REQUEST)
selection.edit(report_list=self.selection_report_list)
if self.selection_report_path is not None:
selection = portal_selections.getSelectionFor(selection_name,
REQUEST=REQUEST)
selection.edit(report_path=self.selection_report_path)
if self.listbox_display_mode is not None:
# XXX Dirty fix, to be able to change the display mode in form_view
REQUEST.list_selection_name = selection_name
portal_selections.setListboxDisplayMode(REQUEST,
self.listbox_display_mode,
selection_name=selection_name)
if self.selection_params is not None:
params = portal_selections.getSelectionParamsFor(selection_name,
REQUEST=REQUEST)
params.update(self.selection_params)
portal_selections.setSelectionParamsFor(selection_name,
params,
REQUEST=REQUEST)
if self.selection_columns is not None:
portal_selections.setSelectionColumns(selection_name,
self.selection_columns,
REQUEST=REQUEST) REQUEST=REQUEST)
self.saved_selections[selection_name]['report_list'] = \ if self.selection_sort_order is not None:
selection.getReportList() portal_selections.setSelectionSortOrder(selection_name,
selection.edit(report_list=self.selection_report_list) self.selection_sort_order,
if self.selection_report_path is not None: REQUEST=REQUEST)
selection = portal_selections.getSelectionFor(selection_name, if self.selection_stats is not None:
REQUEST=REQUEST) portal_selections.setSelectionStats(selection_name,
self.saved_selections[selection_name]['report_path'] = \ self.selection_stats,
selection.getReportPath() REQUEST=REQUEST)
selection.edit(report_path=self.selection_report_path)
if self.listbox_display_mode is not None:
self.saved_selections[selection_name]['display_mode'] = \
portal_selections.getListboxDisplayMode(selection_name,
REQUEST=REQUEST)
# XXX Dirty fix, to be able to change the display mode in form_view
REQUEST.list_selection_name = selection_name
portal_selections.setListboxDisplayMode(
REQUEST, self.listbox_display_mode,
selection_name=selection_name)
if self.selection_params is not None:
params = portal_selections.getSelectionParams(
selection_name, REQUEST=REQUEST)
self.saved_selections[selection_name]['params'] = params.copy()
params.update(self.selection_params)
portal_selections.setSelectionParamsFor(selection_name,
params, REQUEST=REQUEST)
if self.selection_columns is not None:
self.saved_selections[selection_name]['columns'] = \
portal_selections.getSelectionColumns(selection_name,
REQUEST=REQUEST)
portal_selections.setSelectionColumns(selection_name,
self.selection_columns, REQUEST=REQUEST)
if self.selection_sort_order is not None:
self.saved_selections[selection_name]['sort_order'] = \
portal_selections.getSelectionSortOrder(selection_name,
REQUEST=REQUEST)
portal_selections.setSelectionSortOrder(selection_name,
self.selection_sort_order, REQUEST=REQUEST)
if self.selection_stats is not None:
self.saved_selections[selection_name]['stats'] = \
portal_selections.getSelectionStats(selection_name,
REQUEST=REQUEST)
portal_selections.setSelectionStats(selection_name,
self.selection_stats, REQUEST=REQUEST)
self.saved_request_form = REQUEST.form
# When rendering a report section with a listbox, listbox gets parameters # When rendering a report section with a listbox, listbox gets parameters
# from request.form and edits selection with those parameters, so if you # from request.form and edits selection with those parameters, so if you
...@@ -354,68 +360,18 @@ class ReportSection: ...@@ -354,68 +360,18 @@ class ReportSection:
security.declarePublic('popReport') security.declarePublic('popReport')
def popReport(self, context, render_prefix=None): def popReport(self, context, render_prefix=None):
REQUEST = get_request() self.popRequest()
for k,v in self.param_dict.items():
if self.saved_request[k] is self._no_parameter_:
if REQUEST.form.has_key(k):
del REQUEST.form[k]
else:
REQUEST.form[k] = self.saved_request[k]
portal_selections = context.portal_selections portal_selections = context.portal_selections
selection_list = [] selection_list = []
if self.getFormId() and hasattr(context[self.getFormId()], 'listbox') : if self.getFormId() and hasattr(context[self.getFormId()], 'listbox') :
selection_name = context[self.getFormId()].listbox.get_value('selection_name') selection_name = context[self.getFormId()].listbox.get_value('selection_name')
if render_prefix is not None:
del REQUEST.other['prefixed_selection_name']
# Return before cleanup, because there is no interest in cleaning up
# what won't be shared.
return
selection_list += [selection_name] selection_list += [selection_name]
selection_list += [self.selection_name] selection_list += [self.selection_name]
# restore report then form selection if self.temporary_selection:
for selection_name in selection_list: for selection_name in selection_list:
if selection_name is not None: if selection_name is not None:
if self.selection_report_list is not None: portal_selections.popSelection(selection_name)
selection = portal_selections.getSelectionFor(
selection_name, REQUEST=REQUEST)
selection.edit(report_list =
self.saved_selections[selection_name]['report_list'])
if self.selection_report_path is not None:
selection = portal_selections.getSelectionFor(
selection_name, REQUEST=REQUEST)
selection.edit(report_path =
self.saved_selections[selection_name]['report_path'])
if self.listbox_display_mode is not None:
# XXX Dirty fix, to be able to change the display mode in form_view
REQUEST.list_selection_name = selection_name
portal_selections.setListboxDisplayMode(
REQUEST,
self.saved_selections[selection_name]['display_mode'],
selection_name=selection_name)
# first make sure no parameters that have been pushed are kept
portal_selections.setSelectionParamsFor(selection_name,
{}, REQUEST=REQUEST)
if self.selection_params is not None:
# then restore the original params
portal_selections.setSelectionParamsFor(selection_name,
self.saved_selections[selection_name]['params'],
REQUEST=REQUEST)
if self.selection_columns is not None:
portal_selections.setSelectionColumns(selection_name,
self.saved_selections[selection_name]['columns'],
REQUEST=REQUEST)
if self.selection_sort_order is not None:
portal_selections.setSelectionSortOrder(selection_name,
self.saved_selections[selection_name]['sort_order'],
REQUEST=REQUEST)
if self.selection_stats is not None:
portal_selections.setSelectionStats(selection_name,
self.saved_selections[selection_name]['stats'],
REQUEST=REQUEST)
REQUEST.form = self.saved_request_form
InitializeClass(ReportSection) InitializeClass(ReportSection)
allow_class(ReportSection) allow_class(ReportSection)
##############################################################################
#
# Copyright (c) 2009 Nexedi SARL and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from Globals import get_request
from AccessControl.ZopeGuards import guarded_getattr
from Products.Formulator import Widget, Validator
from Products.Formulator.Field import ZMIField
from Products.Formulator.DummyField import fields
class ReportBoxWidget(Widget.Widget):
property_names = list(Widget.Widget.property_names)
property_names.append('report_method')
# XXX this is only needed on bootstrap
default = fields.StringField('default',
title='Default',
description="",
default="",
required=0)
report_method = fields.StringField('report_method',
title='Report Method',
description="",
default="",
required=0)
def render_view(self, field, value, REQUEST=None, key='reportbox', render_prefix=None):
"""
"""
if REQUEST is None:
REQUEST = get_request()
return self.render(field, key, value, REQUEST)
def render(self, field, key, value, REQUEST, render_prefix=None):
"""
"""
form = getattr(field, 'aq_parent', None)
if form is not None:
obj = getattr(form, 'aq_parent', None)
else:
obj = None
if obj is not None:
report_method = guarded_getattr(obj, field['report_method'])
if callable(report_method):
return report_method()
class ReportBoxValidator(Validator.Validator):
def validate(self, field, key, REQUEST):
return True
class ReportBox(ZMIField):
meta_type = "ReportBox"
widget = ReportBoxWidget()
validator = ReportBoxValidator()
...@@ -37,6 +37,7 @@ from Globals import InitializeClass, DTMLFile, PersistentMapping, get_request ...@@ -37,6 +37,7 @@ from Globals import InitializeClass, DTMLFile, PersistentMapping, get_request
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions as ERP5Permissions from Products.ERP5Type import Permissions as ERP5Permissions
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Form import _dtmldir from Products.ERP5Form import _dtmldir
from Selection import Selection, DomainSelection from Selection import Selection, DomainSelection
from ZPublisher.HTTPRequest import FileUpload from ZPublisher.HTTPRequest import FileUpload
...@@ -1320,9 +1321,38 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -1320,9 +1321,38 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
# XXX It would be good to add somthing here # XXX It would be good to add somthing here
# So that 2 anonymous users do not share the same selection # So that 2 anonymous users do not share the same selection
def getTemporarySelectionDict(self):
""" Temporary selections are used in push/pop nested scope,
to prevent from editting for stored selection in the scope.
Typically, it is used for ReportSection."""
tv = getTransactionalVariable(self)
return tv.setdefault('_temporary_selection_dict', {})
def pushSelection(self, selection_name):
selection = self.getSelectionFor(selection_name)
# a temporary selection is kept in transaction.
temp_selection = Selection()
if selection:
temp_selection.__dict__.update(selection.__dict__)
self.getTemporarySelectionDict()\
.setdefault(selection_name, []).append(temp_selection)
def popSelection(self, selection_name):
temporary_selection_dict = self.getTemporarySelectionDict()
if selection_name in temporary_selection_dict and \
temporary_selection_dict[selection_name]:
temporary_selection_dict[selection_name].pop()
def _getSelectionFromContainer(self, selection_name): def _getSelectionFromContainer(self, selection_name):
user_id = self._getUserId() user_id = self._getUserId()
if user_id is None: return None if user_id is None: return None
temporary_selection_dict = self.getTemporarySelectionDict()
if temporary_selection_dict and selection_name in temporary_selection_dict:
if temporary_selection_dict[selection_name]:
# focus the temporary selection in the most narrow scope.
return temporary_selection_dict[selection_name][-1]
if self.isMemcachedUsed(): if self.isMemcachedUsed():
return self._getMemcachedContainer().get('%s-%s' % return self._getMemcachedContainer().get('%s-%s' %
(user_id, selection_name)) (user_id, selection_name))
...@@ -1333,6 +1363,14 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -1333,6 +1363,14 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
def _setSelectionToContainer(self, selection_name, selection): def _setSelectionToContainer(self, selection_name, selection):
user_id = self._getUserId() user_id = self._getUserId()
if user_id is None: return if user_id is None: return
temporary_selection_dict = self.getTemporarySelectionDict()
if temporary_selection_dict and selection_name in temporary_selection_dict:
if temporary_selection_dict[selection_name]:
# focus the temporary selection in the most narrow scope.
temporary_selection_dict[selection_name][-1] = selection
return
if self.isMemcachedUsed(): if self.isMemcachedUsed():
self._getMemcachedContainer().set('%s-%s' % (user_id, selection_name), aq_base(selection)) self._getMemcachedContainer().set('%s-%s' % (user_id, selection_name), aq_base(selection))
else: else:
...@@ -1360,7 +1398,9 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ): ...@@ -1360,7 +1398,9 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
else: else:
user_id = self._getUserId() user_id = self._getUserId()
if user_id is None: return [] if user_id is None: return []
return self._getPersistentContainer(user_id).keys()
tv = getTransactionalVariable(self)
return list(set(self._getPersistentContainer(user_id).keys() + self.getTemporarySelectionDict().keys()))
def _getMemcachedContainer(self): def _getMemcachedContainer(self):
value = getattr(aq_base(self), '_v_selection_data', None) value = getattr(aq_base(self), '_v_selection_data', None)
......
...@@ -40,7 +40,7 @@ document_classes = updateGlobals( this_module, globals(), ...@@ -40,7 +40,7 @@ document_classes = updateGlobals( this_module, globals(),
permissions_module = Permissions) permissions_module = Permissions)
# Define object classes and tools # Define object classes and tools
import Form, FSForm, ListBox, MatrixBox, SelectionTool import Form, FSForm, ListBox, ReportBox, MatrixBox, SelectionTool
import OOoChart, PDFTemplate, Report, PDFForm, ParallelListField import OOoChart, PDFTemplate, Report, PDFForm, ParallelListField
import PlanningBox, POSBox, FormBox, EditorField, ProxyField, DurationField import PlanningBox, POSBox, FormBox, EditorField, ProxyField, DurationField
import RelationField, ImageField, MultiRelationField, MultiLinkField, InputButtonField import RelationField, ImageField, MultiRelationField, MultiLinkField, InputButtonField
...@@ -86,6 +86,8 @@ def initialize( context ): ...@@ -86,6 +86,8 @@ def initialize( context ):
'www/StringField.gif') 'www/StringField.gif')
FieldRegistry.registerField(ListBox.ListBox, FieldRegistry.registerField(ListBox.ListBox,
'www/StringField.gif') 'www/StringField.gif')
FieldRegistry.registerField(ReportBox.ReportBox,
'www/StringField.gif')
FieldRegistry.registerField(PlanningBox.PlanningBox, FieldRegistry.registerField(PlanningBox.PlanningBox,
'www/StringField.gif') 'www/StringField.gif')
FieldRegistry.registerField(MatrixBox.MatrixBox, FieldRegistry.registerField(MatrixBox.MatrixBox,
......
...@@ -625,6 +625,10 @@ class ZMIField( ...@@ -625,6 +625,10 @@ class ZMIField(
return 1 return 1
except ImportError: except ImportError:
return 0 return 0
def getTemplateField(self):
return self
getRecursiveTemplateField = getTemplateField
Globals.InitializeClass(ZMIField) Globals.InitializeClass(ZMIField)
PythonField = ZMIField # NOTE: for backwards compatibility PythonField = ZMIField # NOTE: for backwards compatibility
......
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