Source code for camelot.view.action_steps.select_object

#  ============================================================================
#
#  Copyright (C) 2007-2016 Conceptive Engineering bvba.
#  www.conceptive.be / info@conceptive.be
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are met:
#      * Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#      * Redistributions in binary form must reproduce the above copyright
#        notice, this list of conditions and the following disclaimer in the
#        documentation and/or other materials provided with the distribution.
#      * Neither the name of Conceptive Engineering nor the
#        names of its contributors may be used to endorse or promote products
#        derived from this software without specific prior written permission.
#  
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#  DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
#  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#  ============================================================================

from ...core.qt import Qt, QtWidgets

from camelot.admin.action import ActionStep, Action
from camelot.admin.not_editable_admin import ReadOnlyAdminDecorator
from camelot.core.exception import CancelRequest
from camelot.core.utils import ugettext as _
from camelot.view.art import Icon
from camelot.view.action_runner import hide_progress_dialog
from camelot.view.controls.tableview import TableView

from .item_view import OpenTableView

class SetSelectedObjects(ActionStep):

    def __init__(self, objects):
        self.objects = objects

    def gui_run(self, gui_context):
        dialog = gui_context.view.parent()
        dialog.objects = self.objects
        dialog.accept()

class ConfirmSelection(Action):

    verbose_name = _('OK')
    icon = Icon('tango/16x16/emblems/emblem-symbolic-link.png')

    def model_run(self, model_context):
        yield SetSelectedObjects(list(model_context.get_selection()))

class CancelSelection(Action):

    verbose_name = _('Cancel')

    def gui_run(self, gui_context):
        gui_context.view.parent().reject()

class SelectAdminDecorator(ReadOnlyAdminDecorator):

    list_action = ConfirmSelection()

    def __init__(self, original_admin, show_subclasses):
        super(SelectAdminDecorator, self).__init__(original_admin)
        self.show_subclasses = show_subclasses

    def get_list_actions(self, *a, **kwa):
        return [CancelSelection(), ConfirmSelection()]
    
    
    def get_related_admin(self, cls):
        admin = self._original_admin.get_related_admin(cls)
        # this admin will end up in the model context of the next
        # step
        return admin
    
    def get_subclass_tree(self):
        new_subclasses = []
        if self.show_subclasses == True:
            subclasses = self._original_admin.get_subclass_tree()
            for admin, tree in subclasses:
                new_admin = SelectAdminDecorator(admin, True)
                new_subclasses.append([new_admin, new_admin.get_subclass_tree()])
        return new_subclasses

class SelectDialog(QtWidgets.QDialog):
    
    def __init__(self, gui_context, admin, search_text, proxy, parent = None):
        super( SelectDialog, self ).__init__( parent )
        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins( 0, 0, 0, 0 )
        layout.setSpacing( 0 )
        self.setWindowTitle( _('Select %s') % admin.get_verbose_name() )
        self.setSizeGripEnabled(True)
        table = TableView(gui_context, admin, search_text=search_text,
                          proxy=proxy, parent=self)
        table.setObjectName('table_view')
        layout.addWidget(table)
        self.setLayout( layout )
        self.objects = []
        self.setWindowState(Qt.WindowMaximized)

[docs]class SelectObjects( OpenTableView ): """Select one or more object from a query. The `yield` of this action step return a list of objects. :param admin: a :class:`camelot.admin.object_admin.ObjectAdmin` object :param search_text: a default string on which to search for in the selection dialog :param value: a query or a list of object from which the selection should be made. If none is given, the default query from the admin is taken. """ def __init__(self, admin, search_text=None, value=None): show_subclasses = False if value is None: value = admin.get_query() # only able to construct subclass query whern # the default query is used show_subclasses = True select_admin = SelectAdminDecorator(admin, show_subclasses) super(SelectObjects, self).__init__(select_admin, value) self.search_text = search_text def render(self, gui_context): dialog = SelectDialog(gui_context, self.admin, self.search_text, self.proxy) table_view = dialog.findChild(QtWidgets.QWidget, 'table_view') table_view.set_subclass_tree(self.subclasses) self.update_table_view(table_view) return dialog def gui_run( self, gui_context ): dialog = self.render(gui_context) with hide_progress_dialog(gui_context): if dialog.exec_() == QtWidgets.QDialog.Rejected: raise CancelRequest() return dialog.objects