def __init__(self, model, view): ''' :param model: should be an instance of class Family :param view: should be an instance of FamilyEditorView ''' super(FamilyEditorPresenter, self).__init__(model, view) self.session = object_session(model) # initialize widgets self.init_enum_combo('fam_qualifier_combo', 'qualifier') self.synonyms_presenter = SynonymsPresenter(self) self.refresh_view() # put model values in view # connect signals self.assign_simple_handler('fam_family_entry', 'family', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('fam_qualifier_combo', 'qualifier', editor.UnicodeOrEmptyValidator()) notes_parent = self.view.widgets.notes_parent_box notes_parent.foreach(notes_parent.remove) self.notes_presenter = \ editor.NotesPresenter(self, 'notes', notes_parent) if self.model not in self.session.new: self.view.widgets.fam_ok_and_add_button.set_sensitive(True) # for each widget register a signal handler to be notified when the # value in the widget changes, that way we can do things like sensitize # the ok button self._dirty = False
def __init__(self, model, view): super(SourceDetailEditorPresenter, self).__init__(model, view) self.refresh_view() validator = editor.UnicodeOrNoneValidator() for widget, field in self.widget_to_field_map.iteritems(): self.assign_simple_handler(widget, field, validator) self._dirty = False
def __init__(self, parent, model, view, session): ''' :param model: an instance of class Propagation :param view: an instance of PropagationEditorView ''' super(SeedPresenter, self).__init__(model, view) self._dirty = False self.parent_ref = weakref.ref(parent) self.session = session self.propagation = self.model if not self.propagation._seed: self.propagation._seed = PropSeed() self.model = self.model._seed # TODO: if % germinated is not entered and nseeds and # # germinated are then automatically calculate the % germinated widgets = self.view.widgets distinct = lambda c: utils.get_distinct_values(c, self.session) # TODO: should also setup a completion on the entry utils.setup_text_combobox(self.view.widgets.seed_media_comboentry, distinct(PropSeed.media)) utils.setup_text_combobox(self.view.widgets.seed_container_comboentry, distinct(PropSeed.container)) utils.setup_text_combobox(self.view.widgets.seed_location_comboentry, distinct(PropSeed.location)) self.refresh_view() self.assign_simple_handler('seed_pretreatment_textview', 'pretreatment', editor.UnicodeOrNoneValidator()) # TODO: this should validate to an integer self.assign_simple_handler('seed_nseeds_entry', 'nseeds', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_sown_entry', 'date_sown', editor.DateValidator()) utils.setup_date_button(self.view, 'seed_sown_entry', 'seed_sown_button') self.assign_simple_handler('seed_container_comboentry', 'container', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_media_comboentry', 'media', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_location_comboentry', 'location', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_mvdfrom_entry', 'moved_from', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_mvdto_entry', 'moved_to', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('seed_germdate_entry', 'germ_date', editor.DateValidator()) utils.setup_date_button(self.view, 'seed_germdate_entry', 'seed_germdate_button') self.assign_simple_handler('seed_ngerm_entry', 'nseedlings') self.assign_simple_handler('seed_pctgerm_entry', 'germ_pct') self.assign_simple_handler('seed_date_planted_entry', 'date_planted', editor.DateValidator()) utils.setup_date_button(self.view, 'seed_date_planted_entry', 'seed_date_planted_button')
def __init__(self, model, view): ''' :param model: an instance of class Propagation :param view: an instance of PropagationEditorView ''' super(PropagationPresenter, self).__init__(model, view) self.session = object_session(model) # initialize the propagation type combo and set the initial value self.view.connect('prop_type_combo', 'changed', self.on_prop_type_changed) if self.model.prop_type: self.view.widget_set_value('prop_type_combo', self.model.prop_type) self._cutting_presenter = CuttingPresenter(self, self.model, self.view, self.session) self._seed_presenter = SeedPresenter(self, self.model, self.view, self.session) if not self.model.prop_type: view.widgets.prop_details_box.props.visible = False if self.model.date: format = prefs.prefs[prefs.date_format_pref] date = self.model.date.strftime(format) self.view.widget_set_value(self.view.widgets.prop_date_entry, date) else: self.view.widget_set_value(self.view.widgets.prop_date_entry, utils.today_str()) self.view.widget_set_value(self.view.widgets.notes_textview, self.model.notes) self._dirty = False utils.setup_date_button(self.view, 'prop_date_entry', 'prop_date_button') self.assign_simple_handler('prop_date_entry', 'date', editor.DateValidator()) self.assign_simple_handler('notes_textview', 'notes', editor.UnicodeOrNoneValidator()) def on_expanded(*args): if self.model.prop_type == u'Other': # i don't really understand why setting the expanded # property to false here cause the notes_expander to # always stay expanded but it works self.view.widgets.notes_expander.props.expanded = False self.view.connect('notes_expander', 'activate', on_expanded)
def __init__(self, parent, model, view, session): ''' :param model: an instance of class Propagation :param view: an instance of PropagationEditorView ''' super(CuttingPresenter, self).__init__(model, view) self.parent_ref = weakref.ref(parent) self.session = session self._dirty = False # make the model for the presenter a PropCutting instead of a # Propagation self.propagation = self.model if not self.propagation._cutting: self.propagation._cutting = PropCutting() self.model = self.model._cutting init_combo = self.view.init_translatable_combo init_combo('cutting_type_combo', cutting_type_values, editor.UnicodeOrNoneValidator()) init_combo('cutting_length_unit_combo', length_unit_values) init_combo('cutting_tip_combo', tip_values) init_combo('cutting_leaves_combo', leaves_values) init_combo('cutting_buds_combo', flower_buds_values) init_combo('cutting_wound_combo', wound_values) init_combo('cutting_heat_unit_combo', bottom_heat_unit_values) widgets = self.view.widgets distinct = lambda c: utils.get_distinct_values(c, self.session) utils.setup_text_combobox(widgets.cutting_hormone_comboentry, distinct(PropCutting.hormone)) utils.setup_text_combobox(widgets.cutting_cover_comboentry, distinct(PropCutting.cover)) utils.setup_text_combobox(widgets.cutting_fungal_comboentry, distinct(PropCutting.fungicide)) utils.setup_text_combobox(widgets.cutting_location_comboentry, distinct(PropCutting.location)) utils.setup_text_combobox(widgets.cutting_container_comboentry, distinct(PropCutting.container)) utils.setup_text_combobox(widgets.cutting_media_comboentry, distinct(PropCutting.media)) # set default units units = prefs.prefs[prefs.units_pref] if units == u'imperial': self.model.length_unit = u'in' self.model.bottom_heat_unit = u'F' else: self.model.length_unit = u'mm' self.model.bottom_heat_unit = u'C' self.refresh_view() self.assign_simple_handler('cutting_type_combo', 'cutting_type') self.assign_simple_handler('cutting_length_entry', 'length') self.assign_simple_handler('cutting_length_unit_combo', 'length_unit') self.assign_simple_handler('cutting_tip_combo', 'tip') self.assign_simple_handler('cutting_leaves_combo', 'leaves') self.assign_simple_handler('cutting_lvs_reduced_entry', 'leaves_reduced_pct') self.assign_simple_handler('cutting_media_comboentry', 'media', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_container_comboentry', 'container', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_buds_combo', 'flower_buds') self.assign_simple_handler('cutting_wound_combo', 'wound') self.assign_simple_handler('cutting_fungal_comboentry', 'fungicide', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_hormone_comboentry', 'hormone', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_location_comboentry', 'location', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_cover_comboentry', 'cover', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('cutting_heat_entry', 'bottom_heat_temp') self.assign_simple_handler('cutting_heat_unit_combo', 'bottom_heat_unit') self.assign_simple_handler('cutting_rooted_pct_entry', 'rooted_pct') model = gtk.ListStore(object) self.view.widgets.rooted_treeview.set_model(model) def _rooted_data_func(column, cell, model, treeiter, prop): v = model[treeiter][0] cell.set_property('text', getattr(v, prop)) cell = self.view.widgets.rooted_date_cell cell.props.editable = True self.view.connect(cell, 'edited', self.on_rooted_cell_edited, 'date') self.view.widgets.rooted_date_column.\ set_cell_data_func(cell, _rooted_data_func, 'date') cell = self.view.widgets.rooted_quantity_cell cell.props.editable = True self.view.connect(cell, 'edited', self.on_rooted_cell_edited, 'quantity') self.view.widgets.rooted_quantity_column.\ set_cell_data_func(cell, _rooted_data_func, 'quantity') self.view.connect('rooted_add_button', "clicked", self.on_rooted_add_clicked) self.view.connect('rooted_remove_button', "clicked", self.on_rooted_remove_clicked)
def on_match(completion, model, iter, data=None): value = model[iter][0] validator = editor.UnicodeOrNoneValidator() self.set_model_attr('gps_data', value, validator) completion.get_entry().set_text(value)
def __init__(self, parent, model, view, session): super(CollectionPresenter, self).__init__(model, view) self.parent_ref = weakref.ref(parent) self.session = session self.refresh_view() self.assign_simple_handler('collector_entry', 'collector', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('locale_entry', 'locale', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('collid_entry', 'collectors_code', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('geoacc_entry', 'geo_accy', editor.IntOrNoneStringValidator()) self.assign_simple_handler('alt_entry', 'elevation', editor.FloatOrNoneStringValidator()) self.assign_simple_handler('altacc_entry', 'elevation_accy', editor.FloatOrNoneStringValidator()) self.assign_simple_handler('habitat_textview', 'habitat', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('coll_notes_textview', 'notes', editor.UnicodeOrNoneValidator()) # the list of completions are added in AccessionEditorView.__init__ def on_match(completion, model, iter, data=None): value = model[iter][0] validator = editor.UnicodeOrNoneValidator() self.set_model_attr('gps_data', value, validator) completion.get_entry().set_text(value) completion = self.view.widgets.datum_entry.get_completion() self.view.connect(completion, 'match-selected', on_match) self.assign_simple_handler('datum_entry', 'gps_datum', editor.UnicodeOrNoneValidator()) self.view.connect('lat_entry', 'changed', self.on_lat_entry_changed) self.view.connect('lon_entry', 'changed', self.on_lon_entry_changed) self.view.connect('coll_date_entry', 'changed', self.on_date_entry_changed) utils.setup_date_button(view, 'coll_date_entry', 'coll_date_button') # don't need to connection to south/west since they are in the same # groups as north/east self.north_toggle_signal_id = \ self.view.connect('north_radio', 'toggled', self.on_north_south_radio_toggled) self.east_toggle_signal_id = \ self.view.connect('east_radio', 'toggled', self.on_east_west_radio_toggled) self.view.widgets.add_region_button.set_sensitive(False) def on_add_button_pressed(button, event): self.geo_menu.popup(None, None, None, event.button, event.time) self.view.connect('add_region_button', 'button-press-event', on_add_button_pressed) def _init_geo(): add_button = self.view.widgets.add_region_button self.geo_menu = GeographyMenu(self.set_region) self.geo_menu.attach_to_widget(add_button, None) add_button.set_sensitive(True) gobject.idle_add(_init_geo) self._dirty = False
def __init__(self, model, view): super(SpeciesEditorPresenter, self).__init__(model, view) self.session = object_session(model) self._dirty = False self.omonym_box = None self.init_fullname_widgets() self.vern_presenter = VernacularNamePresenter(self) self.synonyms_presenter = SynonymsPresenter(self) self.dist_presenter = DistributionPresenter(self) self.infrasp_presenter = InfraspPresenter(self) notes_parent = self.view.widgets.notes_parent_box notes_parent.foreach(notes_parent.remove) self.notes_presenter = editor.NotesPresenter(self, 'notes', notes_parent) pictures_parent = self.view.widgets.pictures_parent_box pictures_parent.foreach(pictures_parent.remove) self.pictures_presenter = editor.PicturesPresenter( self, 'notes', pictures_parent) self.init_enum_combo('sp_spqual_combo', 'sp_qual') def cell_data_func(column, cell, model, treeiter, data=None): cell.props.text = utils.utf8(model[treeiter][0]) combo = self.view.widgets.sp_habit_comboentry model = gtk.ListStore(str, object) map(lambda p: model.append(p), [(str(h), h) for h in self.session.query(Habit)]) utils.setup_text_combobox(combo, model) def on_focus_out(entry, event): # check if the combo has a problem then check if the value # in the entry matches one of the habit codes and if so # then change the value to the habit code = entry.props.text try: utils.set_combo_from_value( combo, code.lower(), cmp=lambda r, v: str(r[1].code).lower() == v) except ValueError: pass combo.child.connect('focus-out-event', on_focus_out) # set the model values in the widgets self.refresh_view() # connect habit comboentry widget and child entry self.view.connect('sp_habit_comboentry', 'changed', self.on_habit_comboentry_changed) # connect signals def gen_get_completions(text): clause = utils.ilike(Genus.genus, '%s%%' % unicode(text)) return self.session.query(Genus).filter(clause).\ order_by(Genus.genus) # called when a genus is selected from the genus completions def on_select(value): #debug('on select: %s' % value) for kid in self.view.widgets.message_box_parent.get_children(): self.view.widgets.remove_parent(kid) self.set_model_attr('genus', value) if value: ## is value considered a synonym? syn = self.session.query(GenusSynonym).filter( GenusSynonym.synonym_id == value.id).first() if not value or not syn: ## no value or value is not a synonym: fine return ## value is a synonym: user alert needed msg = _('The genus <b>%(synonym)s</b> is a synonym of ' '<b>%(genus)s</b>.\n\nWould you like to choose ' '<b>%(genus)s</b> instead?' % { 'synonym': syn.synonym, 'genus': syn.genus }) box = None def on_response(button, response): self.view.remove_box(box) if response: self.view.widgets.sp_genus_entry.\ set_text(utils.utf8(syn.genus)) self.set_model_attr('genus', syn.genus) else: self.set_model_attr('genus', value) box = self.view.add_message_box(utils.MESSAGE_BOX_YESNO) box.message = msg box.on_response = on_response box.show() self.view.add_box(box) self.assign_completions_handler( 'sp_genus_entry', # 'genus', gen_get_completions, on_select=on_select) self.assign_simple_handler('sp_cvgroup_entry', 'cv_group', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('sp_spqual_combo', 'sp_qual', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('sp_label_dist_entry', 'label_distribution', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('sp_awards_entry', 'awards', editor.UnicodeOrNoneValidator()) try: import bauble.plugins.garden bauble.plugins.garden # fake its usage if self.model not in self.model.new: self.view.widgets.sp_ok_and_add_button.set_sensitive(True) except Exception: pass
def __init__(self, model, view): ''' @model: should be an instance of class Genus @view: should be an instance of GenusEditorView ''' super(GenusEditorPresenter, self).__init__(model, view) self.session = object_session(model) # initialize widgets self.synonyms_presenter = SynonymsPresenter(self) self.refresh_view() # put model values in view # connect signals def fam_get_completions(text): query = self.session.query(Family) return query.filter(Family.family.like('%s%%' % text)).\ order_by(Family.family) def on_select(value): for kid in self.view.widgets.message_box_parent.get_children(): self.view.widgets.remove_parent(kid) self.set_model_attr('family', value) if not value: return syn = self.session.query(FamilySynonym).filter( FamilySynonym.synonym_id == value.id).first() if not syn: self.set_model_attr('family', value) return msg = _('The family <b>%(synonym)s</b> is a synonym of ' '<b>%(family)s</b>.\n\nWould you like to choose ' '<b>%(family)s</b> instead?' % { 'synonym': syn.synonym, 'family': syn.family }) box = None def on_response(button, response): self.view.widgets.remove_parent(box) box.destroy() if response: # populate the completions model on the entry so # when we set the text it will match the # completion and set the value completion = self.view.widgets.gen_family_entry.\ get_completion() utils.clear_model(completion) model = gtk.ListStore(object) model.append([syn.family]) completion.set_model(model) self.view.widgets.gen_family_entry.\ set_text(utils.utf8(syn.family)) # the family value should be set properly when the # text is set on the entry but it doesn't hurt to # duplicate it here self.set_model_attr('family', syn.family) box = self.view.add_message_box(utils.MESSAGE_BOX_YESNO) box.message = msg box.on_response = on_response box.show() self.assign_completions_handler('gen_family_entry', fam_get_completions, on_select=on_select) self.assign_simple_handler('gen_genus_entry', 'genus', editor.UnicodeOrNoneValidator()) self.assign_simple_handler('gen_author_entry', 'author', editor.UnicodeOrNoneValidator()) notes_parent = self.view.widgets.notes_parent_box notes_parent.foreach(notes_parent.remove) self.notes_presenter = \ editor.NotesPresenter(self, 'notes', notes_parent) if self.model not in self.session.new: self.view.widgets.gen_ok_and_add_button.set_sensitive(True) self._dirty = False