class DateEntry(Gtk.Box): """I am an entry which you can input a date on. In addition to an Gtk.Entry I also contain a button with an arrow you can click to get popup window with a Gtk.Calendar for which you can use to select the date """ gsignal('changed') gsignal('activate') def __init__(self): super(DateEntry, self).__init__(orientation=Gtk.Orientation.HORIZONTAL) self._popping_down = False self._old_date = None self._block_changed = False # This will force both the entry and the button have the same height self._sizegroup = Gtk.SizeGroup.new(Gtk.SizeGroupMode.VERTICAL) # bootstrap problems, kiwi.ui.widgets.entry imports dateentry # we need to use a proxy entry because we want the mask from kiwi.ui.widgets.entry import ProxyEntry self.entry = ProxyEntry() # Set datatype before connecting to change event, to not get when the # mask is set self.entry.set_property('data-type', datetime.date) self.entry.connect('changed', self._on_entry__changed) self.entry.connect('activate', self._on_entry__activate) mask = self.entry.get_mask() if mask: self.entry.set_width_chars(len(mask)) self.pack_start(self.entry, True, True, 0) self.entry.set_valign(Gtk.Align.CENTER) self._sizegroup.add_widget(self.entry) self.entry.show() self._button = Gtk.ToggleButton() self._button.set_valign(Gtk.Align.CENTER) self._button.connect('scroll-event', self._on_entry__scroll_event) self._button.connect('toggled', self._on_button__toggled) self._button.set_focus_on_click(False) self.pack_start(self._button, False, False, 0) self._sizegroup.add_widget(self._button) self._button.show() arrow = Gtk.Arrow(Gtk.ArrowType.DOWN, Gtk.ShadowType.NONE) self._button.add(arrow) arrow.show() self._popup = _DateEntryPopup(self) self._popup.connect('date-selected', self._on_popup__date_selected) self._popup.connect('hide', self._on_popup__hide) self._popup.set_size_request(-1, 24) self.set_valign(Gtk.Align.CENTER) # Virtual methods def do_grab_focus(self): self.entry.grab_focus() # Callbacks def _on_entry__changed(self, entry): try: date = self.get_date() except ValidationError: date = None self._changed(date) def _on_entry__activate(self, entry): self.emit('activate') def _on_entry__scroll_event(self, entry, event): if event.direction == Gdk.ScrollDirection.UP: days = 1 elif event.direction == Gdk.ScrollDirection.DOWN: days = -1 else: return try: date = self.get_date() except ValidationError: date = None if not date: newdate = datetime.date.today() else: newdate = date + datetime.timedelta(days=days) self.set_date(newdate) def _on_button__toggled(self, button): if self._popping_down: return try: date = self.get_date() except ValidationError: date = None self._popup.popup(date) def _on_popup__hide(self, popup): self._popping_down = True self._button.set_active(False) self._popping_down = False def _on_popup__date_selected(self, popup, date): self.set_date(date) popup.popdown() self.entry.grab_focus() self.entry.set_position(len(self.entry.get_text())) self._changed(date) def _changed(self, date): if self._block_changed: return if self._old_date != date: self.emit('changed') self._old_date = date # Public API def set_date(self, date): """Sets the date. :param date: date to set :type date: a datetime.date instance or None """ if not isinstance(date, datetime.date) and date not in [ None, ValueUnset ]: raise TypeError( "date must be a datetime.date instance or None, not %r" % (date, )) if date in [None, ValueUnset]: value = '' else: value = date_converter.as_string(date) # We're block the changed call and doing it manually because # set_text() triggers a delete-text and then an insert-text, # both which are emitting an entry::changed signal self._block_changed = True self.entry.set_text(value) self._block_changed = False self._changed(date) def get_date(self): """Get the selected date :returns: the date. :rtype: datetime.date or None """ try: date = self.entry.read() except ValidationError: date = None if date == ValueUnset: date = None return date
class DateEntry(gtk.HBox): """I am an entry which you can input a date on. In addition to an gtk.Entry I also contain a button with an arrow you can click to get popup window with a gtk.Calendar for which you can use to select the date """ gsignal('changed') gsignal('activate') def __init__(self): gtk.HBox.__init__(self) self._popping_down = False self._old_date = None # bootstrap problems, kiwi.ui.widgets.entry imports dateentry # we need to use a proxy entry because we want the mask from kiwi.ui.widgets.entry import ProxyEntry self.entry = ProxyEntry() self.entry.connect('changed', self._on_entry__changed) self.entry.connect('activate', self._on_entry__activate) self.entry.set_property('data-type', datetime.date) mask = self.entry.get_mask() if mask: self.entry.set_width_chars(len(mask)) self.pack_start(self.entry, False, False) self.entry.show() self._button = gtk.ToggleButton() self._button.connect('scroll-event', self._on_entry__scroll_event) self._button.connect('toggled', self._on_button__toggled) self._button.set_focus_on_click(False) self.pack_start(self._button, False, False) self._button.show() arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE) self._button.add(arrow) arrow.show() self._popup = _DateEntryPopup(self) self._popup.connect('date-selected', self._on_popup__date_selected) self._popup.connect('hide', self._on_popup__hide) self._popup.set_size_request(-1, 24) # Virtual methods def do_grab_focus(self): self.entry.grab_focus() # Callbacks def _on_entry__changed(self, entry): try: date = self.get_date() except ValidationError: date = None self._changed(date) def _on_entry__activate(self, entry): self.emit('activate') def _on_entry__scroll_event(self, entry, event): if event.direction == gdk.SCROLL_UP: days = 1 elif event.direction == gdk.SCROLL_DOWN: days = -1 else: return try: date = self.get_date() except ValidationError: date = None if not date: newdate = datetime.date.today() else: newdate = date + datetime.timedelta(days=days) self.set_date(newdate) def _on_button__toggled(self, button): if self._popping_down: return try: date = self.get_date() except ValidationError: date = None self._popup.popup(date) def _on_popup__hide(self, popup): self._popping_down = True self._button.set_active(False) self._popping_down = False def _on_popup__date_selected(self, popup, date): self.set_date(date) popup.popdown() self.entry.grab_focus() self.entry.set_position(len(self.entry.get_text())) self._changed(date) def _changed(self, date): if self._old_date != date: self.emit('changed') self._old_date = date # Public API def set_date(self, date): """Sets the date. @param date: date to set @type date: a datetime.date instance or None """ if not isinstance(date, datetime.date) and date is not None: raise TypeError( "date must be a datetime.date instance or None, not %r" % ( date,)) if date is None: value = '' else: value = date_converter.as_string(date) self.entry.set_text(value) def get_date(self): """Get the selected date @returns: the date. @rtype: datetime.date or None """ try: date = self.entry.read() except ValidationError: date = None if date == ValueUnset: date = None return date
class DateEntry(Gtk.Box): """I am an entry which you can input a date on. In addition to an Gtk.Entry I also contain a button with an arrow you can click to get popup window with a Gtk.Calendar for which you can use to select the date """ gsignal('changed') gsignal('activate') def __init__(self): super(DateEntry, self).__init__(orientation=Gtk.Orientation.HORIZONTAL) self.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED) self._popping_down = False self._old_date = None self._block_changed = False # This will force both the entry and the button have the same height self._sizegroup = Gtk.SizeGroup.new(Gtk.SizeGroupMode.VERTICAL) # bootstrap problems, kiwi.ui.widgets.entry imports dateentry # we need to use a proxy entry because we want the mask from kiwi.ui.widgets.entry import ProxyEntry self.entry = ProxyEntry() # Set datatype before connecting to change event, to not get when the # mask is set self.entry.set_property('data-type', datetime.date) self.entry.connect('changed', self._on_entry__changed) self.entry.connect('activate', self._on_entry__activate) mask = self.entry.get_mask() if mask: self.entry.set_width_chars(len(mask)) self.pack_start(self.entry, True, True, 0) self.entry.set_valign(Gtk.Align.CENTER) self._sizegroup.add_widget(self.entry) self.entry.show() self._button = Gtk.ToggleButton() self._button.set_valign(Gtk.Align.CENTER) self._button.connect('scroll-event', self._on_entry__scroll_event) self._button.connect('toggled', self._on_button__toggled) self._button.set_focus_on_click(False) self.pack_start(self._button, False, False, 0) self._sizegroup.add_widget(self._button) self._button.show() arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.DOWN, shadow_type=Gtk.ShadowType.NONE) self._button.add(arrow) arrow.show() self._popup = _DateEntryPopup(self) self._popup.connect('date-selected', self._on_popup__date_selected) self._popup.connect('hide', self._on_popup__hide) self._popup.set_size_request(-1, 24) self.set_valign(Gtk.Align.CENTER) # Virtual methods def do_grab_focus(self): self.entry.grab_focus() # Callbacks def _on_entry__changed(self, entry): try: date = self.get_date() except ValidationError: date = None self._changed(date) def _on_entry__activate(self, entry): self.emit('activate') def _on_entry__scroll_event(self, entry, event): if event.direction == Gdk.ScrollDirection.UP: days = 1 elif event.direction == Gdk.ScrollDirection.DOWN: days = -1 else: return try: date = self.get_date() except ValidationError: date = None if not date: newdate = datetime.date.today() else: newdate = date + datetime.timedelta(days=days) self.set_date(newdate) def _on_button__toggled(self, button): if self._popping_down: return try: date = self.get_date() except ValidationError: date = None self._popup.popup(date) def _on_popup__hide(self, popup): self._popping_down = True self._button.set_active(False) self._popping_down = False def _on_popup__date_selected(self, popup, date): self.set_date(date) popup.popdown() self.entry.grab_focus() self.entry.set_position(len(self.entry.get_text())) self._changed(date) def _changed(self, date): if self._block_changed: return if self._old_date != date: self.emit('changed') self._old_date = date # Public API def set_date(self, date): """Sets the date. :param date: date to set :type date: a datetime.date instance or None """ if not isinstance(date, datetime.date) and date not in [None, ValueUnset]: raise TypeError( "date must be a datetime.date instance or None, not %r" % ( date,)) if date in [None, ValueUnset]: value = '' else: value = date_converter.as_string(date) # We're block the changed call and doing it manually because # set_text() triggers a delete-text and then an insert-text, # both which are emitting an entry::changed signal self._block_changed = True self.entry.set_text(value) self._block_changed = False self._changed(date) def get_date(self): """Get the selected date :returns: the date. :rtype: datetime.date or None """ try: date = self.entry.read() except ValidationError: date = None if date == ValueUnset: date = None return date
class DateEntry(gtk.HBox): """I am an entry which you can input a date on. In addition to an gtk.Entry I also contain a button with an arrow you can click to get popup window with a gtk.Calendar for which you can use to select the date """ gsignal('changed') gsignal('activate') def __init__(self): gtk.HBox.__init__(self) self._popping_down = False self._old_date = None # bootstrap problems, kiwi.ui.widgets.entry imports dateentry # we need to use a proxy entry because we want the mask from kiwi.ui.widgets.entry import ProxyEntry self.entry = ProxyEntry() self.entry.connect('changed', self._on_entry__changed) self.entry.connect('activate', self._on_entry__activate) self.entry.set_property('data-type', datetime.date) mask = self.entry.get_mask() if mask: self.entry.set_width_chars(len(mask)) self.pack_start(self.entry, False, False) self.entry.show() self._button = gtk.ToggleButton() self._button.connect('scroll-event', self._on_entry__scroll_event) self._button.connect('toggled', self._on_button__toggled) self._button.set_focus_on_click(False) self.pack_start(self._button, False, False) self._button.show() arrow = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_NONE) self._button.add(arrow) arrow.show() self._popup = _DateEntryPopup(self) self._popup.connect('date-selected', self._on_popup__date_selected) self._popup.connect('hide', self._on_popup__hide) self._popup.set_size_request(-1, 24) # Virtual methods def do_grab_focus(self): self.entry.grab_focus() # Callbacks def _on_entry__changed(self, entry): try: date = self.get_date() except ValidationError: date = None self._changed(date) def _on_entry__activate(self, entry): self.emit('activate') def _on_entry__scroll_event(self, entry, event): if event.direction == gdk.SCROLL_UP: days = 1 elif event.direction == gdk.SCROLL_DOWN: days = -1 else: return try: date = self.get_date() except ValidationError: date = None if not date: newdate = datetime.date.today() else: newdate = date + datetime.timedelta(days=days) self.set_date(newdate) def _on_button__toggled(self, button): if self._popping_down: return try: date = self.get_date() except ValidationError: date = None self._popup.popup(date) def _on_popup__hide(self, popup): self._popping_down = True self._button.set_active(False) self._popping_down = False def _on_popup__date_selected(self, popup, date): self.set_date(date) popup.popdown() self.entry.grab_focus() self.entry.set_position(len(self.entry.get_text())) self._changed(date) def _changed(self, date): if self._old_date != date: self.emit('changed') self._old_date = date # Public API def set_date(self, date): """Sets the date. @param date: date to set @type date: a datetime.date instance or None """ if not isinstance(date, datetime.date) and date is not None: raise TypeError( "date must be a datetime.date instance or None, not %r" % (date, )) if date is None: value = '' else: value = date_converter.as_string(date) self.entry.set_text(value) def get_date(self): """Get the selected date @returns: the date. @rtype: datetime.date or None """ try: date = self.entry.read() except ValidationError: date = None if date == ValueUnset: date = None return date