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):
# defined by a TALES
if self._p_oid is None or self.tales['field_id'] or self.tales['form_id']:
return self._get_value(id, **kw)
# XXX: Are these disabled?
proxy_field = self.getTemplateField(cache=False)
if proxy_field is not None:
return proxy_field.get_value(id, **kw)
......
......@@ -28,6 +28,7 @@
from Globals import InitializeClass, DTMLFile, get_request
from AccessControl import ClassSecurityInfo
from Acquisition import aq_base
from Products.PythonScripts.Utility import allow_class
from Products.Formulator.DummyField import fields
from Products.Formulator.Form import ZMIForm
......@@ -123,6 +124,7 @@ class ERP5Report(ERP5Form):
# Proxy method to PageTemplate
def __call__(self, *args, **kwargs):
warn("ERP5Report to be obsolete, please use ReportBox and normal ERP5Form instead.", DeprecationWarning)
if not self.report_method:
raise KeyError, 'report method is not set on the report'
......@@ -205,7 +207,8 @@ class ReportSection:
selection_stats=None,
selection_sort_order=None,
selection_report_path=None,
selection_report_list=None):
selection_report_list=None,
temporary_selection=True):
"""
Initialize the line and set the default values
Selected columns must be defined in parameter of listbox.render...
......@@ -213,6 +216,8 @@ class ReportSection:
In ReportTree listbox display mode, you can override :
selection_report_path, the root category for this report
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
......@@ -222,20 +227,18 @@ class ReportSection:
warn("Don't use translated_title, but title directly", DeprecationWarning)
self.translated_title = translated_title
self.level = level
self.saved_request = {}
self.selection_name = selection_name
self.selection_params = selection_params
self.listbox_display_mode = listbox_display_mode
self.selection_columns = selection_columns
self.selection_stats = selection_stats
self.selection_sort_order = selection_sort_order
self.saved_selections = {}
self.selection_report_path = selection_report_path
self.selection_report_list = selection_report_list
self.saved_request_form = {}
self.param_dict = param_dict or {}
self.param_list = param_list or []
self.method_id = method_id
self.temporary_selection = temporary_selection
security.declarePublic('getTitle')
def getTitle(self):
......@@ -266,17 +269,36 @@ class ReportSection:
def getFormId(self):
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')
def pushReport(self, context, render_prefix=None):
REQUEST = get_request()
for k,v in self.param_dict.items():
self.saved_request[k] = REQUEST.form.get(k, self._no_parameter_)
REQUEST.form[k] = v
self.pushRequest()
REQUEST = get_request()
portal_selections = context.portal_selections
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') :
selection_name = context[self.getFormId()].listbox.get_value('selection_name')
if render_prefix is not None:
......@@ -285,62 +307,46 @@ class ReportSection:
selection_list += [selection_name]
# save report's selection and orignal form's selection,
#as ListBox will overwrite it
for selection_name in selection_list :
if selection_name is not None :
if not self.saved_selections.has_key(selection_name) :
self.saved_selections[selection_name] = {}
for selection_name in filter(lambda x: x is not None, selection_list):
if self.temporary_selection:
portal_selections.pushSelection(selection_name)
else:
if portal_selections.getSelectionFor(selection_name) is None:
portal_selections.setSelectionFor(selection_name, Selection())
if self.selection_report_list is not None:
selection = portal_selections.getSelectionFor(selection_name,
REQUEST=REQUEST)
if selection is None:
selection = Selection()
portal_selections.setSelectionFor(selection_name, selection,
REQUEST=REQUEST)
self.saved_selections[selection_name]['report_list'] = \
selection.getReportList()
selection.edit(report_list=self.selection_report_list)
if self.selection_report_path is not None:
selection = portal_selections.getSelectionFor(selection_name,
REQUEST=REQUEST)
self.saved_selections[selection_name]['report_path'] = \
selection.getReportPath()
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,
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 = 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:
self.saved_selections[selection_name]['columns'] = \
portal_selections.getSelectionColumns(selection_name,
params,
REQUEST=REQUEST)
if self.selection_columns is not None:
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,
self.selection_columns,
REQUEST=REQUEST)
if self.selection_sort_order is not None:
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,
self.selection_sort_order,
REQUEST=REQUEST)
if self.selection_stats is not None:
portal_selections.setSelectionStats(selection_name,
self.selection_stats, REQUEST=REQUEST)
self.saved_request_form = REQUEST.form
self.selection_stats,
REQUEST=REQUEST)
# When rendering a report section with a listbox, listbox gets parameters
# from request.form and edits selection with those parameters, so if you
......@@ -354,68 +360,18 @@ class ReportSection:
security.declarePublic('popReport')
def popReport(self, context, render_prefix=None):
REQUEST = get_request()
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]
self.popRequest()
portal_selections = context.portal_selections
selection_list = []
if self.getFormId() and hasattr(context[self.getFormId()], 'listbox') :
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 += [self.selection_name]
# restore report then form selection
if self.temporary_selection:
for selection_name in selection_list:
if selection_name is not None:
if self.selection_report_list is not None:
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
portal_selections.popSelection(selection_name)
InitializeClass(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
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions as ERP5Permissions
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Form import _dtmldir
from Selection import Selection, DomainSelection
from ZPublisher.HTTPRequest import FileUpload
......@@ -1320,9 +1321,38 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
# XXX It would be good to add somthing here
# 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):
user_id = self._getUserId()
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():
return self._getMemcachedContainer().get('%s-%s' %
(user_id, selection_name))
......@@ -1333,6 +1363,14 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
def _setSelectionToContainer(self, selection_name, selection):
user_id = self._getUserId()
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():
self._getMemcachedContainer().set('%s-%s' % (user_id, selection_name), aq_base(selection))
else:
......@@ -1360,7 +1398,9 @@ class SelectionTool( BaseTool, UniqueObject, SimpleItem ):
else:
user_id = self._getUserId()
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):
value = getattr(aq_base(self), '_v_selection_data', None)
......
......@@ -40,7 +40,7 @@ document_classes = updateGlobals( this_module, globals(),
permissions_module = Permissions)
# 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 PlanningBox, POSBox, FormBox, EditorField, ProxyField, DurationField
import RelationField, ImageField, MultiRelationField, MultiLinkField, InputButtonField
......@@ -86,6 +86,8 @@ def initialize( context ):
'www/StringField.gif')
FieldRegistry.registerField(ListBox.ListBox,
'www/StringField.gif')
FieldRegistry.registerField(ReportBox.ReportBox,
'www/StringField.gif')
FieldRegistry.registerField(PlanningBox.PlanningBox,
'www/StringField.gif')
FieldRegistry.registerField(MatrixBox.MatrixBox,
......
......@@ -626,6 +626,10 @@ class ZMIField(
except ImportError:
return 0
def getTemplateField(self):
return self
getRecursiveTemplateField = getTemplateField
Globals.InitializeClass(ZMIField)
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