Source code for camelot.view.wizard.update_value

#  ============================================================================
#
#  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
#
#  ============================================================================

"""A wizard to update a field on a collection of objects"""

import sqlalchemy.schema

from PyQt4 import QtGui, QtCore

from camelot.view.controls.editors import ChoicesEditor
from camelot.view.controls import delegates
from camelot.core.utils import ugettext_lazy as _
from camelot.view.model_thread import post
from camelot.view.proxy import ValueLoading
from camelot.view.wizard.pages.update_entities_page import UpdateEntitiesPage

[docs]class ReplaceContentsData(object): def __init__(self): self.field = None self.value = None
[docs]class SelectValuePage(QtGui.QWizardPage): """Page to select a value to update""" title = _('Replace field contents') sub_title = _('Select the field to update and enter its new value') def __init__(self, parent, admin, data): super(SelectValuePage, self).__init__(parent) self.setTitle( unicode(self.title) ) self.setSubTitle( unicode(self.sub_title) ) editor = ChoicesEditor( parent=self ) editor.setObjectName( 'field_choice' ) layout = QtGui.QVBoxLayout() layout.addWidget( editor ) self.setLayout( layout ) self._fields = {} self._data = data editor.currentIndexChanged.connect( self.field_changed ) if admin: post( admin.get_all_fields_and_attributes, self.set_fields )
[docs] def set_fields(self, fields): self._fields = fields def filter(attributes): if not attributes['editable']: return False if attributes['delegate'] in (delegates.One2ManyDelegate, delegates.ManyToManyDelegate): return False return True choices = [(field, attributes['name']) for field, attributes in fields.items() if filter(attributes)] editor = self.findChild( QtGui.QWidget, 'field_choice' ) if editor != None: editor.set_choices(choices) editor.set_value((choices+[(None,None)])[1][0]) self.field_changed(0)
[docs] def value_changed(self, value_editor=None): if not value_editor: value_editor = self.findChild( QtGui.QWidget, 'value_editor' ) if value_editor != None: delegate = self._fields[self._data.field]['delegate'] value = value_editor.get_value() # make sure a value is always callable if issubclass(delegate, delegates.Many2OneDelegate): value_getter = value else: value_getter = lambda:value self._data.value = value_getter
@QtCore.pyqtSlot(int)
[docs] def field_changed(self, index): selected_field = ValueLoading editor = self.findChild( QtGui.QWidget, 'field_choice' ) value_editor = self.findChild( QtGui.QWidget, 'value_editor' ) if editor != None: selected_field = editor.get_value() if value_editor != None: value_editor.deleteLater() if selected_field != ValueLoading: self._data.field = selected_field self._data.value = None field_attributes = self._fields[selected_field] static_field_attributes = dict( (k,v) for k,v in field_attributes.items() if not callable(v) ) delegate = field_attributes['delegate']( parent = self, **static_field_attributes) option = QtGui.QStyleOptionViewItem() option.version = 5 value_editor = delegate.createEditor( self, option, None ) value_editor.setObjectName( 'value_editor' ) value_editor.set_field_attributes( **static_field_attributes ) self.layout().addWidget( value_editor ) value_editor.editingFinished.connect( self.value_changed ) # try to set sensible defaults for value if isinstance(delegate, delegates.Many2OneDelegate): value_editor.set_value(lambda:None) else: default = static_field_attributes.get('default', None) choices = static_field_attributes.get('choices', None) if default != None and not isinstance(default, sqlalchemy.schema.ColumnDefault): value_editor.set_value( default ) elif choices and len(choices): value_editor.set_value( choices[0][0] ) else: value_editor.set_value( None ) # force the value editor, since the previous one is still around self.value_changed( value_editor )
[docs]class ReplaceContentsPage(UpdateEntitiesPage): title = _('Replace field contents') def __init__(self, parent, collection_getter, data): super(ReplaceContentsPage, self).__init__(parent=parent, collection_getter=collection_getter) self._data = data
[docs] def update_entity(self, obj): value = self._data.value() setattr(obj, self._data.field, value)
[docs]class UpdateValueWizard(QtGui.QWizard): """This wizard presents the user with a selection of the possible fields to update and a new value. Then this field is changed for all objects in a given collection""" select_value_page = SelectValuePage window_title = _('Replace') def __init__(self, parent=None, selection_getter=None, admin=None): """:param model: a collection proxy on which to replace the field contents""" super(UpdateValueWizard, self).__init__(parent) self.setWindowTitle( unicode(self.window_title) ) data = ReplaceContentsData() assert selection_getter self.addPage(SelectValuePage(parent=self, admin=admin, data=data)) self.addPage(ReplaceContentsPage(parent=self, collection_getter=selection_getter, data=data))

Comments
blog comments powered by Disqus