# ============================================================================
#
# Copyright (C) 2007-2013 Conceptive Engineering bvba. All rights reserved.
# www.conceptive.be / info@conceptive.be
#
# This file is part of the Camelot Library.
#
# This file may be used under the terms of the GNU General Public
# License version 2.0 as published by the Free Software Foundation
# and appearing in the file license.txt included in the packaging of
# this file. Please review this information to ensure GNU
# General Public Licensing requirements will be met.
#
# If you are unsure which license is appropriate for your use, please
# visit www.python-camelot.com or contact info@conceptive.be
#
# This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
# WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# For use of this library in commercial applications, please contact
# info@conceptive.be
#
# ============================================================================
from PyQt4 import QtGui
from camelot.admin.action.base import Action
from camelot.core.utils import ugettext as _
from camelot.view.art import Icon
from application_action import ( ApplicationActionGuiContext,
ApplicationActionModelContext )
import list_action
[docs]class FormActionModelContext( ApplicationActionModelContext ):
"""On top of the attributes of the
:class:`camelot.admin.action.application_action.ApplicationActionModelContext`,
this context contains :
.. attribute:: current_row
the row in the list that is currently displayed in the form
.. attribute:: collection_count
the number of objects that can be reached in the form.
.. attribute:: selection_count
the number of objects displayed in the form, at most 1.
.. attribute:: session
The session to which the objects in the list belong.
The :attr:`selection_count` attribute allows the
:meth:`model_run` to quickly evaluate the size of the collection without
calling the potetially time consuming method :meth:`get_collection`.
"""
def __init__( self ):
super( FormActionModelContext, self ).__init__()
self._model = None
self.admin = None
self.current_row = None
self.collection_count = 0
self.selection_count = 1
[docs] def get_object( self ):
"""
:return: the object currently displayed in the form, None if no object
is displayed yet
"""
if self.current_row != None:
return self._model._get_object( self.current_row )
[docs] def get_collection( self, yield_per = None ):
"""
:param yield_per: an integer number giving a hint on how many objects
should fetched from the database at the same time.
:return: a generator over the objects in the list
"""
for obj in self._model.get_collection():
yield obj
[docs] def get_selection( self, yield_per = None ):
"""
Method to be compatible with a
:class:`camelot.admin.action.list_action.ListActionModelContext`, this
allows creating a single Action to be used on a form and on list.
:param yield_per: this parameter has no effect, it's here only for
compatibility with :meth:`camelot.admin.action.list_action.ListActionModelContext.get_selection`
:return: a generator that yields the current object displayed in the
form and does not yield anything if no object is displayed yet
in the form.
"""
if self.current_row != None:
yield self._model._get_object( self.current_row )
[docs]class FormActionGuiContext( ApplicationActionGuiContext ):
"""The context for an :class:`Action` on a form. On top of the attributes of the
:class:`camelot.admin.action.application_action.ApplicationActionGuiContext`,
this context contains :
.. attribute:: widget_mapper
the :class:`QtGui.QDataWidgetMapper` class that relates the form
widget to the model.
.. attribute:: view
a :class:`camelot.view.controls.view.AbstractView` class that represents
the view in which the action is triggered.
"""
model_context = FormActionModelContext
def __init__( self ):
super( FormActionGuiContext, self ).__init__()
self.widget_mapper = None
self.view = None
def create_model_context( self ):
context = super( FormActionGuiContext, self ).create_model_context()
context._model = self.widget_mapper.model()
context.collection_count = context._model.rowCount()
context.current_row = self.widget_mapper.currentIndex()
return context
def copy( self, base_class = None ):
new_context = super( FormActionGuiContext, self ).copy( base_class )
new_context.widget_mapper = self.widget_mapper
new_context.view = self.view
return new_context
class ShowHistory( Action ):
icon = Icon('tango/16x16/actions/format-justify-fill.png')
verbose_name = _('History')
tooltip = _('Show recent changes on this form')
def model_run( self, model_context ):
from ..object_admin import ObjectAdmin
from ...view import action_steps
from ...view.controls import delegates
obj = model_context.get_object()
memento = model_context.admin.get_memento()
class ChangeAdmin( ObjectAdmin ):
verbose_name = _('Change')
verbose_name_plural = _('Changes')
list_display = ['at', 'by', 'memento_type', 'changes']
field_attributes = {'at':{'delegate':delegates.DateTimeDelegate},
'memento_type':{'delegate':delegates.ComboBoxDelegate,
'choices':memento.memento_types,
'name':_('Type')} }
def get_related_toolbar_actions( self, toolbar_area, direction ):
return []
if obj != None:
primary_key = model_context.admin.primary_key( obj )
if None not in primary_key:
changes = list( memento.get_changes( model = unicode( model_context.admin.entity.__name__ ),
primary_key = primary_key,
current_attributes = {} ) )
admin = ChangeAdmin( model_context.admin, object )
step = action_steps.ChangeObjects( changes, admin )
step.icon = Icon('tango/16x16/actions/format-justify-fill.png')
step.title = _('Recent changes')
step.subtitle = model_context.admin.get_verbose_identifier( obj )
yield step