Source code for camelot.admin.action.list_action

#  ============================================================================
#
#  Copyright (C) 2007-2011 Conceptive Engineering bvba. All rights reserved.
#  www.conceptive.be / project-camelot@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 project-camelot@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
#  project-camelot@conceptive.be
#
#  ============================================================================

from camelot.admin.action.base import Action
from application_action import ( ApplicationActionGuiContext,
                                 ApplicationActionModelContext )

[docs]class ListActionModelContext( ApplicationActionModelContext ): """On top of the attributes of the :class:`camelot.admin.action.application_action.ApplicationActionModelContext`, this context contains : .. attribute:: selection_count the number of selected rows. .. attribute:: collection_count the number of rows in the list. .. attribute:: selected_rows an ordered list with tuples of selected row ranges. the range is inclusive. .. attribute:: current_row the current row in the list .. attribute:: session The session to which the objects in the list belong. The :attr:`collection_count` and :attr:`selection_count` attributes allow the :meth:`model_run` to quickly evaluate the size of the collection or the selection without calling the potentially time consuming methods :meth:`get_collection` and :meth:`get_selection`. """ def __init__( self ): super( ListActionModelContext, self ).__init__() self._model = None self.admin = None self.current_row = None self.selection_count = 0 self.collection_count = 0 self.selected_rows = [] @property
[docs] def session( self ): return self._model.get_query_getter()().session
[docs] def get_selection( 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 selected """ if self.selection_count == self.collection_count: # if all rows are selected, take a shortcut for obj in self.get_collection( yield_per ): yield obj else: for (first_row, last_row) in self.selected_rows: for row in range( first_row, last_row + 1 ): yield self._model._get_object( 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_object( self ): """ :return: the object displayed in the current row or None """ if self.current_row != None: return self._model._get_object( self.current_row )
[docs]class ListActionGuiContext( ApplicationActionGuiContext ): """The context for an :class:`Action` on a table view. On top of the attributes of the :class:`camelot.admin.action.application_action.ApplicationActionGuiContext`, this context contains : .. attribute:: item_view the :class:`QtGui.QAbstractItemView` class that relates to the table view on which the widget will be placed. """ model_context = ListActionModelContext def __init__( self ): super( ListActionGuiContext, self ).__init__() self.item_view = None
[docs] def create_model_context( self ): context = super( ListActionGuiContext, self ).create_model_context() context._model = self.item_view.model() context.current_row = self.item_view.currentIndex().row() context.collection_count = context._model.rowCount() selection_count = 0 selected_rows = [] selection = self.item_view.selectionModel().selection() for i in range( len( selection ) ): selection_range = selection[i] rows_range = ( selection_range.top(), selection_range.bottom() ) selected_rows.append( rows_range ) selection_count += ( rows_range[1] - rows_range[0] ) + 1 context.selection_count = selection_count context.selected_rows = selected_rows return context
[docs] def copy( self ): new_context = super( ListActionGuiContext, self ).copy() new_context.item_view = self.item_view return new_context
[docs]class CallMethod( Action ): """ Call a method on all objects in a selection, and flush the session. :param verbose_name: the name of the action, as it should appear to the user :param method: the method to call on the objects :param enabled: method to call on objects to verify if the action is enabled, by default the action is always enabled This action can be used either within :attr:`list_actions` or within :attr:`form_actions`. """ def __init__( self, verbose_name, method, enabled=None ): self.verbose_name = verbose_name self.method = method self.enabled = enabled
[docs] def model_run( self, model_context ): from camelot.view.action_steps import ( UpdateProgress, FlushSession, UpdateObject ) step = max( 1, model_context.selection_count / 100 ) for i, obj in enumerate( model_context.get_selection() ): if i%step == 0: yield UpdateProgress( i, model_context.selection_count ) self.method( obj ) # the object might have changed without the need to be flushed # to the database yield UpdateObject( obj ) yield FlushSession( model_context.session )
[docs] def get_state( self, model_context ): state = super( CallMethod, self ).get_state( model_context ) if self.enabled != None: for obj in model_context.get_selection(): if not self.enabled( obj ): state.enabled = False break return state
[docs]class OpenFormView( Action ): """Open a form view for the current row of a list."""
[docs] def gui_run( self, gui_context ): from camelot.view.workspace import show_top_level from camelot.view.proxy.queryproxy import QueryTableProxy model = QueryTableProxy( gui_context.admin, gui_context.item_view.model().get_query_getter(), gui_context.admin.get_fields, max_number_of_rows = 1, cache_collection_proxy = gui_context.item_view.model() ) row = gui_context.item_view.currentIndex().row() formview = gui_context.admin.create_form_view( u'', model, row, parent=None ) # make sure there is no 'pythonw' window title in windows for a # second formview.setWindowTitle( u' ' ) show_top_level( formview, gui_context.item_view )

Comments
blog comments powered by Disqus