def __init__(self, objects, admin, parent=None, flags=QtCore.Qt.Window): from camelot.view.controls import editors from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectsDialog, self).__init__("", parent, flags) self.banner_widget().setStyleSheet("background-color: white;") model = CollectionProxy(admin, lambda: objects, admin.get_columns) self.validator = model.get_validator() self.validator.validity_changed_signal.connect(self.update_complete) model.layoutChanged.connect(self.validate_all_rows) table_widget = editors.One2ManyEditor(admin=admin, parent=self, create_inline=True) table_widget.set_value(model) table_widget.setObjectName("table_widget") note = editors.NoteEditor(parent=self) note.set_value(None) note.setObjectName("note") layout = QtGui.QVBoxLayout() layout.addWidget(table_widget) layout.addWidget(note) self.main_widget().setLayout(layout) self.set_default_buttons() ok_button = self.buttons_widget().findChild(QtGui.QPushButton, "accept") ok_button.setEnabled(False) self.validate_all_rows()
def __init__( self, objects, admin, parent = None, flags = QtCore.Qt.Window ): from camelot.view.controls import editors from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectsDialog, self).__init__( '', parent, flags ) self.banner_widget().setStyleSheet('background-color: white;') model = CollectionProxy( admin, lambda:objects, admin.get_columns) self.validator = model.get_validator() self.validator.validity_changed_signal.connect( self.update_complete ) model.layoutChanged.connect( self.validate_all_rows ) table_widget = editors.One2ManyEditor( admin = admin, parent = self, create_inline = True, ) table_widget.set_value( model ) table_widget.setObjectName( 'table_widget' ) note = editors.NoteEditor( parent=self ) note.set_value(None) note.setObjectName( 'note' ) layout = QtGui.QVBoxLayout() layout.addWidget( table_widget ) layout.addWidget( note ) self.main_widget().setLayout( layout ) self.set_default_buttons() ok_button = self.buttons_widget().findChild( QtGui.QPushButton, 'accept' ) ok_button.setEnabled( False ) self.validate_all_rows()
def __init__(self, parent=None): from camelot.view.controls.formview import FormWidget from camelot.view.proxy.collection_proxy import CollectionProxy super(FormPage, self).__init__(parent) assert self.Data self.setTitle(unicode(self.get_title())) self.setSubTitle(unicode(self.get_sub_title())) self.setPixmap(QtGui.QWizard.LogoPixmap, self.get_icon().getQPixmap()) self._data = self.Data() self._complete = False admin = self.get_admin() self._model = CollectionProxy(admin, lambda:[self._data], admin.get_fields) validator = self._model.get_validator() layout = QtGui.QVBoxLayout() form = FormWidget(self, admin) validator.validity_changed_signal.connect( self._validity_changed ) form.set_model(self._model) layout.addWidget(form) self.setLayout(layout) if hasattr(admin, 'form_size'): self.setMinimumSize(admin.form_size[0], admin.form_size[1])
def __init__( self, obj, admin, title=_("Please complete"), subtitle=_("Complete the form and press the OK button"), icon=Icon("tango/22x22/categories/preferences-system.png"), parent=None, flags=QtCore.Qt.Dialog, ): from camelot.view.controls.formview import FormWidget from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectDialog, self).__init__("", parent, flags) self.setWindowTitle(admin.get_verbose_name()) self.set_banner_logo_pixmap(icon.getQPixmap()) self.set_banner_title(unicode(title)) self.set_banner_subtitle(unicode(subtitle)) self.banner_widget().setStyleSheet("background-color: white;") model = CollectionProxy(admin, lambda: [obj], admin.get_fields) validator = model.get_validator() layout = QtGui.QHBoxLayout() layout.setObjectName("form_and_actions_layout") form_widget = FormWidget(parent=self, admin=admin) layout.addWidget(form_widget) validator.validity_changed_signal.connect(self._validity_changed) form_widget.set_model(model) form_widget.setObjectName("form") self.main_widget().setLayout(layout) self.gui_context = FormActionGuiContext() self.gui_context.workspace = self self.gui_context.admin = admin self.gui_context.view = self self.gui_context.widget_mapper = self.findChild(QtGui.QDataWidgetMapper, "widget_mapper") cancel_button = QtGui.QPushButton(ugettext("Cancel")) cancel_button.setObjectName("cancel") ok_button = QtGui.QPushButton(ugettext("OK")) ok_button.setObjectName("ok") ok_button.setEnabled(False) layout = QtGui.QHBoxLayout() layout.setDirection(QtGui.QBoxLayout.RightToLeft) layout.addWidget(ok_button) layout.addWidget(cancel_button) layout.addStretch() self.buttons_widget().setLayout(layout) cancel_button.pressed.connect(self.reject) ok_button.pressed.connect(self.accept) # do inital validation, so the validity changed signal is valid self._validity_changed(0) # set the actions in the actions panel get_actions = admin.get_form_actions post(functools.update_wrapper(functools.partial(get_actions, None), get_actions), self.set_actions)
def __init__( self, objects, admin, parent = None, flags = QtCore.Qt.Window ): from camelot.view.controls import editors from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectsDialog, self).__init__( '', parent, flags ) self.setWindowTitle( admin.get_verbose_name_plural() ) self.set_banner_title( _('Data Preview') ) self.set_banner_subtitle( _('Please review the data below.') ) self.banner_widget().setStyleSheet('background-color: white;') self.set_banner_logo_pixmap( Icon('tango/32x32/mimetypes/x-office-spreadsheet.png').getQPixmap() ) model = CollectionProxy( admin, lambda:objects, admin.get_columns) self.validator = model.get_validator() self.validator.validity_changed_signal.connect( self.update_complete ) model.layoutChanged.connect( self.validate_all_rows ) table_widget = editors.One2ManyEditor( admin = admin, parent = self, create_inline = True, ) table_widget.set_value( model ) table_widget.setObjectName( 'table_widget' ) note = editors.NoteEditor( parent=self ) note.set_value(None) note.setObjectName( 'note' ) layout = QtGui.QVBoxLayout() layout.addWidget( table_widget ) layout.addWidget( note ) self.main_widget().setLayout( layout ) cancel_button = QtGui.QPushButton( ugettext('Cancel') ) ok_button = QtGui.QPushButton( ugettext('OK') ) ok_button.setObjectName( 'ok' ) ok_button.setEnabled( False ) layout = QtGui.QHBoxLayout() layout.setDirection( QtGui.QBoxLayout.RightToLeft ) layout.addWidget( ok_button ) layout.addWidget( cancel_button ) layout.addStretch() self.buttons_widget().setLayout( layout ) cancel_button.pressed.connect( self.reject ) ok_button.pressed.connect( self.accept ) self.validate_all_rows()
def show_field_attributes(self): from camelot.view.proxy.collection_proxy import CollectionProxy admin = self._admin.get_related_entity_admin(Attribute) attributes_collection = CollectionProxy( admin=admin, collection_getter=self.get_attributes, columns_getter=admin.get_columns) class FieldAttributesDialog(QtGui.QDialog): def __init__(self, field_name, parent=None): super(FieldAttributesDialog, self).__init__(parent) self.setWindowTitle(_('Field Attributes')) layout = QtGui.QVBoxLayout() layout.addWidget(QtGui.QLabel(field_name)) editor = One2ManyEditor(admin=admin, editable=False, parent=self) editor.set_value(attributes_collection) editor.setMinimumSize(600, 400) layout.addWidget(editor) self.setLayout(layout) dialog = FieldAttributesDialog(self._field_name, self) dialog.exec_()
def setUp(self): super(CollectionProxyCase, self).setUp() session = Session() self.collection = list(session.query(Person).all()) self.proxy = CollectionProxy( self.person_admin, collection_getter=lambda: self.collection, columns_getter=self.person_admin.get_columns)
def render(self, gui_context): from camelot.view.proxy.queryproxy import QueryTableProxy from camelot.view.proxy.collection_proxy import CollectionProxy from camelot.view.controls.formview import FormView if self.objects is None: related_model = gui_context.item_view.model() # # depending on the type of related model, create a new model # row = gui_context.item_view.currentIndex().row() if isinstance(related_model, QueryTableProxy): # here the query and the cache are passed to the proxy # constructor to prevent an additional query when a # form is opened to look for an object that was in the list model = QueryTableProxy( gui_context.admin, query=related_model.get_query(), max_number_of_rows=1, cache_collection_proxy=related_model, ) else: # no cache or sorting information is transferred model = CollectionProxy( gui_context.admin, max_number_of_rows=1, ) # get the unsorted row row = related_model.map_to_source(row) model.set_value(related_model.get_value()) else: row = self.row model = CollectionProxy(self.admin, max_number_of_rows=10) model.set_value(self.objects) model.set_columns(self._columns) form = FormView(title=self.title, admin=self.admin, model=model, columns=self._columns, form_display=self._form_display, index=row) form.set_actions(self.actions) form.set_toolbar_actions(self.top_toolbar_actions) return form
def __init__( self, obj, admin, title = _('Please complete'), subtitle = _('Complete the form and press the OK button'), icon = Icon('tango/22x22/categories/preferences-system.png'), parent=None, flags=QtCore.Qt.Dialog ): from camelot.view.controls.formview import FormWidget from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectDialog, self).__init__( '', parent, flags ) self.setWindowTitle( admin.get_verbose_name() ) self.set_banner_logo_pixmap( icon.getQPixmap() ) self.set_banner_title( unicode(title) ) self.set_banner_subtitle( unicode(subtitle) ) self.banner_widget().setStyleSheet('background-color: white;') model = CollectionProxy(admin, lambda:[obj], admin.get_fields) validator = model.get_validator() layout = QtGui.QVBoxLayout() form_widget = FormWidget( parent=self, admin=admin ) layout.addWidget( form_widget ) validator.validity_changed_signal.connect( self._validity_changed ) form_widget.set_model( model ) form_widget.setObjectName( 'form' ) self.main_widget().setLayout(layout) cancel_button = QtGui.QPushButton( ugettext('Cancel') ) cancel_button.setObjectName( 'cancel' ) ok_button = QtGui.QPushButton( ugettext('OK') ) ok_button.setObjectName( 'ok' ) ok_button.setEnabled( False ) layout = QtGui.QHBoxLayout() layout.setDirection( QtGui.QBoxLayout.RightToLeft ) layout.addWidget( ok_button ) layout.addWidget( cancel_button ) layout.addStretch() self.buttons_widget().setLayout( layout ) cancel_button.pressed.connect( self.reject ) ok_button.pressed.connect( self.accept ) # do inital validation, so the validity changed signal is valid self._validity_changed( 0 )
def createFormForIndex( self, index ): from camelot.view.workspace import show_top_level from camelot.view.proxy.collection_proxy import CollectionProxy model = CollectionProxy( self.admin, self.model.get_collection, self.admin.get_fields, max_number_of_rows = 1, edits = None ) form = self.admin.create_form_view( u'', model, self.model.map_to_source(index) ) show_top_level( form, self )
def gui_run(self, gui_context): from camelot.view.proxy.collection_proxy import CollectionProxy from camelot.view.workspace import show_top_level def create_collection_getter(objects): return lambda: objects model = CollectionProxy(self.admin, create_collection_getter(self.objects), self.admin.get_fields, max_number_of_rows=10) title = '' formview = self.admin.create_form_view(title, model, 0) show_top_level(formview, gui_context.workspace)
def show_form_view(self, admin_and_title): from camelot.view.workspace import show_top_level admin, title = admin_and_title def create_collection_getter(instance_getter): return lambda: [instance_getter()] from camelot.view.proxy.collection_proxy import CollectionProxy model = CollectionProxy( admin, create_collection_getter(self.entity_instance_getter), admin.get_fields) model.dataChanged.connect(self.dataChanged) form = admin.create_form_view(title, model, 0) # @todo : dirty trick to keep reference #self.__form = form show_top_level(form, self)
def gui_run(self, gui_context): from camelot.view.workspace import show_top_level from camelot.view.proxy.queryproxy import QueryTableProxy from camelot.view.proxy.collection_proxy import CollectionProxy related_model = gui_context.item_view.model() # # depending on the type of related model, create a new model # row = gui_context.item_view.currentIndex().row() if isinstance(related_model, QueryTableProxy): model = QueryTableProxy( gui_context.admin, related_model.get_query_getter(), gui_context.admin.get_fields, max_number_of_rows=1, cache_collection_proxy=related_model, ) else: # no cache or sorting information is transferred model = CollectionProxy( gui_context.admin, related_model.get_collection, gui_context.admin.get_fields, max_number_of_rows=1, ) # get the unsorted row row = related_model.map_to_source(row) formview = gui_context.admin.create_form_view( u' ', model, row, ) # make sure there is no 'pythonw' window title in windows for a # second formview.setWindowTitle(u' ') show_top_level(formview, gui_context.item_view)
def __init__( self, obj, admin, title = _('Please complete'), subtitle = _('Complete the form and press the OK button'), icon = Icon('tango/22x22/categories/preferences-system.png'), parent=None, flags=QtCore.Qt.Dialog ): from camelot.view.controls.formview import FormWidget from camelot.view.proxy.collection_proxy import CollectionProxy super(ChangeObjectDialog, self).__init__( '', parent, flags ) self.setWindowTitle( admin.get_verbose_name() ) self.set_banner_logo_pixmap( icon.getQPixmap() ) self.set_banner_title( unicode(title) ) self.set_banner_subtitle( unicode(subtitle) ) self.banner_widget().setStyleSheet('background-color: white;') model = CollectionProxy(admin, lambda:[obj], admin.get_fields) validator = model.get_validator() layout = QtGui.QHBoxLayout() layout.setObjectName( 'form_and_actions_layout' ) form_widget = FormWidget( parent=self, admin=admin ) layout.addWidget( form_widget ) validator.validity_changed_signal.connect( self._validity_changed ) form_widget.set_model( model ) form_widget.setObjectName( 'form' ) if hasattr(admin, 'form_size') and admin.form_size: form_widget.setMinimumSize(admin.form_size[0], admin.form_size[1]) self.main_widget().setLayout(layout) self.gui_context = FormActionGuiContext() self.gui_context.workspace = self self.gui_context.admin = admin self.gui_context.view = self self.gui_context.widget_mapper = self.findChild( QtGui.QDataWidgetMapper, 'widget_mapper' ) cancel_button = QtGui.QPushButton( ugettext('Cancel') ) cancel_button.setObjectName( 'cancel' ) ok_button = QtGui.QPushButton( ugettext('OK') ) ok_button.setObjectName( 'ok' ) ok_button.setEnabled( False ) layout = QtGui.QHBoxLayout() layout.setDirection( QtGui.QBoxLayout.RightToLeft ) layout.addWidget( ok_button ) layout.addWidget( cancel_button ) layout.addStretch() self.buttons_widget().setLayout( layout ) cancel_button.pressed.connect( self.reject ) ok_button.pressed.connect( self.accept ) admin._apply_form_state( self ) # do inital validation, so the validity changed signal is valid self._validity_changed( 0 ) # set the actions in the actions panel get_actions = admin.get_form_actions post( functools.update_wrapper( functools.partial( get_actions, None ), get_actions ), self.set_actions )
class FormPage(QtGui.QWizardPage): """FormPage is a generic wizard page that displays a form for an object in a wizard page, subclass this class to use it. The class attribute 'Data' should be the class of the object to be used to store the form information. To access the data stored by the wizard form into a data object, use its get_data method. The 'Next' button will only be activated when the form is complete. """ icon = Icon('tango/32x32/mimetypes/x-office-spreadsheet.png') title = None sub_title = None Data = None Admin = None def __init__(self, parent=None): from camelot.view.controls.formview import FormWidget from camelot.view.proxy.collection_proxy import CollectionProxy super(FormPage, self).__init__(parent) assert self.Data self.setTitle(unicode(self.get_title())) self.setSubTitle(unicode(self.get_sub_title())) self.setPixmap(QtGui.QWizard.LogoPixmap, self.get_icon().getQPixmap()) self._data = self.Data() self._complete = False admin = self.get_admin() self._model = CollectionProxy(admin, lambda:[self._data], admin.get_fields) validator = self._model.get_validator() layout = QtGui.QVBoxLayout() form = FormWidget(self, admin) validator.validity_changed_signal.connect( self._validity_changed ) form.set_model(self._model) layout.addWidget(form) self.setLayout(layout) if hasattr(admin, 'form_size'): self.setMinimumSize(admin.form_size[0], admin.form_size[1]) def initializePage(self): # do inital validation, so the validity changed signal is valid self._complete = False self.completeChanged.emit() self._validity_changed(0) @QtCore.pyqtSlot(int) def _validity_changed(self, row): def is_valid(): return self._model.get_validator().isValid(0) post(is_valid, self._change_complete) def _change_complete(self, complete): self._complete = complete self.completeChanged.emit() def isComplete(self): return self._complete def get_admin(self): from camelot.admin.application_admin import get_application_admin app_admin = get_application_admin() if self.Admin: return self.Admin(app_admin, self.Data) return app_admin.get_entity_admin(self.Data) def get_title(self): return self.title or self.get_admin().get_verbose_name() def get_sub_title(self): return self.sub_title or _('Please complete') def get_icon(self): return self.icon def get_data(self): return self._data