def _init_geo(): add_button = self.view.widgets.sp_dist_add_button self.geo_menu = GeographyMenu(self.on_activate_add_menu_item) self.geo_menu.attach_to_widget(add_button, None) add_button.set_sensitive(True)
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)
class DistributionPresenter(editor.GenericEditorPresenter): """ """ def __init__(self, parent): ''' :param parent: the parent SpeciesEditorPresenter ''' super(DistributionPresenter, self).__init__(parent.model, parent.view) self.parent_ref = weakref.ref(parent) self.session = parent.session self._dirty = False self.remove_menu = gtk.Menu() self.remove_menu.attach_to_widget( self.view.widgets.sp_dist_remove_button, None) self.view.connect('sp_dist_add_button', 'button-press-event', self.on_add_button_pressed) self.view.connect('sp_dist_remove_button', 'button-press-event', self.on_remove_button_pressed) self.view.widgets.sp_dist_add_button.set_sensitive(False) def _init_geo(): add_button = self.view.widgets.sp_dist_add_button self.geo_menu = GeographyMenu(self.on_activate_add_menu_item) self.geo_menu.attach_to_widget(add_button, None) add_button.set_sensitive(True) gobject.idle_add(_init_geo) def refresh_view(self): label = self.view.widgets.sp_dist_label s = ', '.join([str(d) for d in self.model.distribution]) label.set_text(s) def on_add_button_pressed(self, button, event): self.geo_menu.popup(None, None, None, event.button, event.time) def on_remove_button_pressed(self, button, event): # clear the menu for c in self.remove_menu.get_children(): self.remove_menu.remove(c) # add distributions to menu for dist in self.model.distribution: item = gtk.MenuItem(str(dist)) self.view.connect(item, 'activate', self.on_activate_remove_menu_item, dist) self.remove_menu.append(item) self.remove_menu.show_all() self.remove_menu.popup(None, None, None, event.button, event.time) def on_activate_add_menu_item(self, widget, geoid=None): from bauble.plugins.plants.species_model import Geography geo = self.session.query(Geography).filter_by(id=geoid).one() # check that this geography isn't already in the distributions if geo in [d.geography for d in self.model.distribution]: # debug('%s already in %s' % (geo, self.model)) return dist = SpeciesDistribution(geography=geo) self.model.distribution.append(dist) # debug([str(d) for d in self.model.distribution]) self._dirty = True self.refresh_view() self.parent_ref().refresh_sensitivity() def on_activate_remove_menu_item(self, widget, dist): self.model.distribution.remove(dist) utils.delete_or_expunge(dist) self.refresh_view() self._dirty = True self.parent_ref().refresh_sensitivity() def is_dirty(self): return self._dirty
class CollectionPresenter(editor.ChildPresenter): """ CollectionPresenter :param parent: an AccessionEditorPresenter :param model: a Collection instance :param view: an AccessionEditorView :param session: a sqlalchemy.orm.session """ widget_to_field_map = { 'collector_entry': 'collector', 'coll_date_entry': 'date', 'collid_entry': 'collectors_code', 'locale_entry': 'locale', 'lat_entry': 'latitude', 'lon_entry': 'longitude', 'geoacc_entry': 'geo_accy', 'alt_entry': 'elevation', 'altacc_entry': 'elevation_accy', 'habitat_textview': 'habitat', 'coll_notes_textview': 'notes', 'datum_entry': 'gps_datum', 'add_region_button': 'region', } # TODO: could make the problems be tuples of an id and description to # be displayed in a dialog or on a label ala eclipse PROBLEM_BAD_LATITUDE = str(random()) PROBLEM_BAD_LONGITUDE = str(random()) PROBLEM_INVALID_DATE = str(random()) PROBLEM_INVALID_LOCALE = str(random()) 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 set_region(self, menu_item, geo_id): geography = self.session.query(Geography).get(geo_id) self.set_model_attr('region', geography) self.set_model_attr('geography_id', geo_id) self.view.widgets.add_region_button.props.label = str(geography) def set_model_attr(self, field, value, validator=None): """ Validates the fields when a field changes. """ super(CollectionPresenter, self).set_model_attr(field, value, validator) self._dirty = True if self.model.locale is None or self.model.locale in ('', u''): self.add_problem(self.PROBLEM_INVALID_LOCALE) else: self.remove_problem(self.PROBLEM_INVALID_LOCALE) if field in ('longitude', 'latitude'): sensitive = self.model.latitude is not None \ and self.model.longitude is not None self.view.widgets.geoacc_entry.set_sensitive(sensitive) self.view.widgets.datum_entry.set_sensitive(sensitive) if field == 'elevation': sensitive = self.model.elevation is not None self.view.widgets.altacc_entry.set_sensitive(sensitive) self.parent_ref().refresh_sensitivity() def start(self): raise Exception('CollectionPresenter cannot be started') def dirty(self): return self._dirty def refresh_view(self): from bauble.plugins.garden.accession import latitude_to_dms, \ longitude_to_dms for widget, field in self.widget_to_field_map.iteritems(): value = getattr(self.model, field) logger.debug('%s, %s, %s' % (widget, field, value)) if value is not None and field == 'date': value = '%s/%s/%s' % (value.day, value.month, '%04d' % value.year) self.view.widget_set_value(widget, value) latitude = self.model.latitude if latitude is not None: dms_string = u'%s %s\u00B0%s\'%s"' % latitude_to_dms(latitude) self.view.widgets.lat_dms_label.set_text(dms_string) if float(latitude) < 0: self.view.widgets.south_radio.set_active(True) else: self.view.widgets.north_radio.set_active(True) else: self.view.widgets.lat_dms_label.set_text('') self.view.widgets.north_radio.set_active(True) longitude = self.model.longitude if longitude is not None: dms_string = u'%s %s\u00B0%s\'%s"' % longitude_to_dms(longitude) self.view.widgets.lon_dms_label.set_text(dms_string) if float(longitude) < 0: self.view.widgets.west_radio.set_active(True) else: self.view.widgets.east_radio.set_active(True) else: self.view.widgets.lon_dms_label.set_text('') self.view.widgets.east_radio.set_active(True) if self.model.elevation is None: self.view.widgets.altacc_entry.set_sensitive(False) if self.model.latitude is None or self.model.longitude is None: self.view.widgets.geoacc_entry.set_sensitive(False) self.view.widgets.datum_entry.set_sensitive(False) def on_date_entry_changed(self, entry, data=None): from bauble.editor import ValidatorError value = None PROBLEM = 'INVALID_DATE' try: value = editor.DateValidator().to_python(entry.props.text) except ValidatorError, e: logger.debug(e) self.parent_ref().add_problem(PROBLEM, entry) else:
class CollectionPresenter(editor.ChildPresenter): """ CollectionPresenter :param parent: an AccessionEditorPresenter :param model: a Collection instance :param view: an AccessionEditorView :param session: a sqlalchemy.orm.session """ widget_to_field_map = { "collector_entry": "collector", "coll_date_entry": "date", "collid_entry": "collectors_code", "locale_entry": "locale", "lat_entry": "latitude", "lon_entry": "longitude", "geoacc_entry": "geo_accy", "alt_entry": "elevation", "altacc_entry": "elevation_accy", "habitat_textview": "habitat", "coll_notes_textview": "notes", "datum_entry": "gps_datum", "add_region_button": "region", } # TODO: could make the problems be tuples of an id and description to # be displayed in a dialog or on a label ala eclipse PROBLEM_BAD_LATITUDE = str(random()) PROBLEM_BAD_LONGITUDE = str(random()) PROBLEM_INVALID_DATE = str(random()) PROBLEM_INVALID_LOCALE = str(random()) 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 set_region(self, menu_item, geo_id): geography = self.session.query(Geography).get(geo_id) self.set_model_attr("region", geography) self.set_model_attr("geography_id", geo_id) self.view.widgets.add_region_button.props.label = str(geography) def set_model_attr(self, field, value, validator=None): """ Validates the fields when a field changes. """ super(CollectionPresenter, self).set_model_attr(field, value, validator) self._dirty = True if self.model.locale is None or self.model.locale in ("", u""): self.add_problem(self.PROBLEM_INVALID_LOCALE) else: self.remove_problem(self.PROBLEM_INVALID_LOCALE) if field in ("longitude", "latitude"): sensitive = self.model.latitude is not None and self.model.longitude is not None self.view.widgets.geoacc_entry.set_sensitive(sensitive) self.view.widgets.datum_entry.set_sensitive(sensitive) if field == "elevation": sensitive = self.model.elevation is not None self.view.widgets.altacc_entry.set_sensitive(sensitive) self.parent_ref().refresh_sensitivity() def start(self): raise Exception("CollectionPresenter cannot be started") def dirty(self): return self._dirty def refresh_view(self): from bauble.plugins.garden.accession import latitude_to_dms, longitude_to_dms for widget, field in self.widget_to_field_map.iteritems(): value = getattr(self.model, field) logger.debug("%s, %s, %s" % (widget, field, value)) if value is not None and field == "date": value = "%s/%s/%s" % (value.day, value.month, "%04d" % value.year) self.view.set_widget_value(widget, value) latitude = self.model.latitude if latitude is not None: dms_string = u"%s %s\u00B0%s'%s\"" % latitude_to_dms(latitude) self.view.widgets.lat_dms_label.set_text(dms_string) if float(latitude) < 0: self.view.widgets.south_radio.set_active(True) else: self.view.widgets.north_radio.set_active(True) else: self.view.widgets.lat_dms_label.set_text("") self.view.widgets.north_radio.set_active(True) longitude = self.model.longitude if longitude is not None: dms_string = u"%s %s\u00B0%s'%s\"" % longitude_to_dms(longitude) self.view.widgets.lon_dms_label.set_text(dms_string) if float(longitude) < 0: self.view.widgets.west_radio.set_active(True) else: self.view.widgets.east_radio.set_active(True) else: self.view.widgets.lon_dms_label.set_text("") self.view.widgets.east_radio.set_active(True) if self.model.elevation is None: self.view.widgets.altacc_entry.set_sensitive(False) if self.model.latitude is None or self.model.longitude is None: self.view.widgets.geoacc_entry.set_sensitive(False) self.view.widgets.datum_entry.set_sensitive(False) def on_date_entry_changed(self, entry, data=None): from bauble.editor import ValidatorError value = None PROBLEM = "INVALID_DATE" try: value = editor.DateValidator().to_python(entry.props.text) except ValidatorError, e: logger.debug(e) self.parent_ref().add_problem(PROBLEM, entry) else: