diff --git a/data/ui/date-selector.ui b/data/ui/date-selector.ui index 5db89c53..3375c8a3 100644 --- a/data/ui/date-selector.ui +++ b/data/ui/date-selector.ui @@ -1,5 +1,4 @@ - bottom + 12 - + True - 12 - 6 - - - True - - - - 0 - 0 - - - - - True - - - - 1 - 0 - - - - - True - - - - 2 - 0 - - - - - True - True - True - - - - 0 - 2 - 3 - - - - - True - True - True - - - True - True - 4 - 4 - 0.5 - number - - - - - - - - True - True - 4 - 4 - 0.5 - number - - - - - - - 1 - - - - - True - True - 4 - 4 - 4 - 0.5 - number - - - - - - 2 - - - - - - 0 - 1 - 3 - - + True + True + diff --git a/src/gcal-date-selector.c b/src/gcal-date-selector.c index 96ef5c62..17692144 100644 --- a/src/gcal-date-selector.c +++ b/src/gcal-date-selector.c @@ -17,6 +17,7 @@ * with this program. If not, see . */ +#include "gcal-date-chooser.h" #include "gcal-date-selector.h" #include @@ -24,35 +25,13 @@ #include #include -enum -{ - DAY, - MONTH, - YEAR, - NUM_ENTRIES -}; - struct _GcalDateSelector { GtkMenuButton parent; /* widgets */ + GtkWidget *date_chooser; GtkWidget *date_label; - GtkWidget *calendar; - GtkWidget *grid; - - GtkWidget *entries[NUM_ENTRIES]; - - /* date */ - GDateTime *date; - - /* misc */ - const gchar *mask; - - /* index in the mask starting by 0 */ - guint day_pos; - guint month_pos; - guint year_pos; }; enum @@ -62,136 +41,29 @@ enum LAST_PROP }; -static void calendar_day_selected (GtkCalendar *calendar, - GcalDateSelector *selector); - -static gboolean date_entry_focus_out (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); - -static void entry_activated (GtkEntry *entry, - gpointer user_data); - -static void parse_entries (GcalDateSelector *selector); - -static void text_inserted (GtkEditable *editable, - gchar *new_text, - gint new_text_length, - gint *position, - gpointer user_data); - -static void gcal_date_selector_constructed (GObject *object); - G_DEFINE_TYPE (GcalDateSelector, gcal_date_selector, GTK_TYPE_MENU_BUTTON); static void -calendar_day_selected (GtkCalendar *calendar, - GcalDateSelector *selector) +update_label (GcalDateSelector *self) { - GDateTime *new_date; - guint day, month, year; + GDateTime *date; + gchar *label; - gtk_calendar_get_date (calendar, &year, &month, &day); + date = gcal_date_chooser_get_date (GCAL_DATE_CHOOSER (self->date_chooser)); - new_date = g_date_time_new_local (year, month + 1, day, 0, 0, 0); + /* rebuild the date label */ + label = g_date_time_format (date, "%x"); - /** - * Block signal handler to avoid an infinite - * recursion, exploding the proccess stack. - */ - g_signal_handlers_block_by_func (selector->calendar, calendar_day_selected, selector); - - gcal_date_selector_set_date (selector, new_date); - - g_signal_handlers_unblock_by_func (selector->calendar, calendar_day_selected, selector); - - g_clear_pointer (&new_date, g_date_time_unref); -} - -static gboolean -date_entry_focus_out (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - parse_entries (GCAL_DATE_SELECTOR (user_data)); - return FALSE; + gtk_label_set_label (GTK_LABEL (self->date_label), label); + g_free (label); } static void -entry_activated (GtkEntry *entry, - gpointer user_data) +calendar_day_selected (GcalDateSelector *self) { - parse_entries (GCAL_DATE_SELECTOR (user_data)); -} + update_label (self); -static void -parse_entries (GcalDateSelector *selector) -{ - GDateTime *new_date; - gint day, month, year; - - day = atoi (gtk_entry_get_text (GTK_ENTRY (selector->entries[DAY]))); - month = atoi (gtk_entry_get_text (GTK_ENTRY (selector->entries[MONTH]))); - year = atoi (gtk_entry_get_text (GTK_ENTRY (selector->entries[YEAR]))); - - new_date = g_date_time_new_local (year, month, day, 0, 0, 0); - - /* select the date */ - g_signal_handlers_block_by_func (selector->calendar, calendar_day_selected, selector); - - gcal_date_selector_set_date (selector, new_date); - - g_signal_handlers_unblock_by_func (selector->calendar, calendar_day_selected, selector); - - g_clear_pointer (&new_date, g_date_time_unref); -} - -static void -text_inserted (GtkEditable *editable, - gchar *new_text, - gint new_text_length, - gint *position, - gpointer user_data) -{ - GtkEntryBuffer *buffer; - gchar* new_label; - gint i; - gint current_length, max_length; - gboolean valid; - - valid = TRUE; - buffer = gtk_entry_get_buffer (GTK_ENTRY (editable)); - current_length = gtk_entry_buffer_get_length (buffer); - max_length = gtk_entry_get_max_length (GTK_ENTRY (editable)); - - /* honor max length property */ - if (current_length + new_text_length > max_length) - return; - - /* stop the default implementation */ - g_signal_stop_emission (editable, g_signal_lookup ("insert-text", GTK_TYPE_ENTRY), 0); - - for (i = 0; i < new_text_length; i++) - { - gchar c; - c = *(new_text + i); - - /* trying to insert a non-numeric char */ - if (c < '0' || c > '9') - { - valid = FALSE; - break; - } - } - - if (!valid) - return; - - new_label = g_strdup_printf ("%s%s", gtk_entry_buffer_get_text (buffer), new_text); - gtk_entry_buffer_set_text (buffer, new_label, current_length + new_text_length); - *position = *position + new_text_length; - - g_free (new_label); + g_object_notify (G_OBJECT (self), "date"); } static void @@ -205,7 +77,7 @@ gcal_date_selector_get_property (GObject *object, switch (prop_id) { case PROP_DATE: - g_value_set_boxed (value, self->date); + g_value_set_boxed (value, gcal_date_chooser_get_date (GCAL_DATE_CHOOSER (self->date_chooser))); break; default: @@ -238,7 +110,6 @@ gcal_date_selector_class_init (GcalDateSelectorClass *klass) GObjectClass *object_class; object_class = G_OBJECT_CLASS (klass); - object_class->constructed = gcal_date_selector_constructed; object_class->get_property = gcal_date_selector_get_property; object_class->set_property = gcal_date_selector_set_property; @@ -257,135 +128,19 @@ gcal_date_selector_class_init (GcalDateSelectorClass *klass) gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/calendar/date-selector.ui"); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalDateSelector, date_chooser); gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalDateSelector, date_label); - gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalDateSelector, calendar); - gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalDateSelector, grid); - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), text_inserted); - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), date_entry_focus_out); - gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), entry_activated); gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), calendar_day_selected); } static void gcal_date_selector_init (GcalDateSelector *self) { - GDateTime *now; - gint i, d_index, max; gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); gtk_widget_init_template (GTK_WIDGET (self)); - - now = g_date_time_new_now_local (); - self->date = g_date_time_new_local (g_date_time_get_year (now), - g_date_time_get_month (now), - g_date_time_get_day_of_month (now), - 0, 0, 0); - - /* This string represents day/month/year order for each of the different - * languages. It could possibly be default value, %m/%d/%y placing the month - * before, or any ordering according to the translator's environment. */ - self->mask = g_dpgettext2 ("glib20", "GDateTime", "%m/%d/%y"); - - /** - * Translators: Select the day, month and year indexes. This will - * be used later on to map the date entries to the - * corresponding indexes. I should have added more validations here. - */ - max = strlen (self->mask); - if (max != 8) - { - /* I'll assume an error and bail out with the default values */ - self->day_pos = 0; - self->month_pos = 1; - self->year_pos = 2; - return; - } - - d_index = 0; - - for (i = 0; i < max; i++) - { - gchar c; - - c = *(self->mask + i); - - /* No need to check these common separators */ - if (c == '%' || c == '-' || c == '/' || c == '.') - continue; - - switch (c) - { - /* day */ - case 'a': - case 'A': - case 'd': - case 'e': - case 'j': - case 'u': - case 'w': - self->day_pos = d_index++; - break; - - /* month */ - case 'b': - case 'B': - case 'm': - self->month_pos = d_index++; - break; - - /* year */ - case 'y': - case 'Y': - self->year_pos = d_index++; - break; - } - } -} - -static void -gcal_date_selector_constructed (GObject *object) -{ - GcalDateSelector *self; - - GtkWidget *label, *box; - GList *l, *aux; - - self = GCAL_DATE_SELECTOR (object); - - /* chaining up */ - G_OBJECT_CLASS (gcal_date_selector_parent_class)->constructed (object); - - /* set labels, on the first row */ - label = gtk_grid_get_child_at (GTK_GRID (self->grid), self->day_pos, 0); - gtk_label_set_text (GTK_LABEL (label), _("Day")); - label = gtk_grid_get_child_at (GTK_GRID (self->grid), self->month_pos, 0); - gtk_label_set_text (GTK_LABEL (label), _("Month")); - label = gtk_grid_get_child_at (GTK_GRID (self->grid), self->year_pos, 0); - gtk_label_set_text (GTK_LABEL (label), _("Year")); - - /* retrieve components from UI definition: entries */ - box = gtk_grid_get_child_at (GTK_GRID (self->grid), 0, 1); - aux = gtk_container_get_children (GTK_CONTAINER (box)); - for (l = aux; l != NULL; l = g_list_next (l)) - { - gint position; - gtk_container_child_get (GTK_CONTAINER (box), l->data, "position", &position, NULL); - if (position == self->day_pos) - self->entries[DAY] = l->data; - if (position == self->month_pos) - self->entries[MONTH] = l->data; - if (position == self->year_pos) - self->entries[YEAR] = l->data; - - if (position == self->day_pos || position == self->month_pos) - gtk_entry_set_max_length (GTK_ENTRY (l->data), 2); - } - g_list_free (aux); - - gtk_widget_set_direction (box, GTK_TEXT_DIR_LTR); - gtk_widget_set_direction (self->grid, GTK_TEXT_DIR_LTR); } /* Public API */ @@ -408,55 +163,11 @@ gcal_date_selector_set_date (GcalDateSelector *selector, { g_return_if_fail (GCAL_IS_DATE_SELECTOR (selector)); - if (selector->date != date) - { - gchar *label; + /* set calendar's date */ + gcal_date_chooser_set_date (GCAL_DATE_CHOOSER (selector->date_chooser), date); - g_clear_pointer (&selector->date, g_date_time_unref); - selector->date = g_date_time_new_local (g_date_time_get_year (date), - g_date_time_get_month (date), - g_date_time_get_day_of_month (date), - 0, 0, 0); - - /* set calendar's date */ - g_signal_handlers_block_by_func (selector->calendar, calendar_day_selected, selector); - - g_object_set (selector->calendar, - "day", g_date_time_get_day_of_month (date), - "month", g_date_time_get_month (date) - 1, - "year", g_date_time_get_year (date), - NULL); - - g_signal_handlers_unblock_by_func (selector->calendar, calendar_day_selected, selector); - - /* rebuild the date label */ - label = g_date_time_format (date, selector->mask); - - gtk_label_set_label (GTK_LABEL (selector->date_label), label); - g_free (label); - - /* set date entries' text */ - /* day entry */ - label = g_date_time_format (date, "%d"); - - gtk_entry_set_text (GTK_ENTRY (selector->entries[DAY]), label); - g_free (label); - - /* month entry */ - label = g_date_time_format (date, "%m"); - - gtk_entry_set_text (GTK_ENTRY (selector->entries[MONTH]), label); - g_free (label); - - /* year entry */ - label = g_date_time_format (date, "%Y"); - - gtk_entry_set_text (GTK_ENTRY (selector->entries[YEAR]), label); - g_free (label); - - /* emit the MODIFIED signal */ - g_object_notify (G_OBJECT (selector), "date"); - } + /* emit the MODIFIED signal */ + g_object_notify (G_OBJECT (selector), "date"); } /** @@ -472,5 +183,5 @@ gcal_date_selector_get_date (GcalDateSelector *selector) { g_return_val_if_fail (GCAL_IS_DATE_SELECTOR (selector), NULL); - return selector->date; + return gcal_date_chooser_get_date (GCAL_DATE_CHOOSER (selector->date_chooser)); }