Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
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
Esempio n. 4
0
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:
Esempio n. 5
0
 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)
Esempio n. 6
0
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:
Esempio n. 7
0
 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)
Esempio n. 8
0
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