date-selector: move to use the new date chooser
After adding the new GcalDateChooser widget, change the current date selector to use it as the internal widget of the popover. The next logical step is turning GcalDateSelector into an entry.
This commit is contained in:
+5
-117
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.3 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<template class="GcalDateSelector" parent="GtkMenuButton">
|
||||
@@ -13,124 +12,13 @@
|
||||
</template>
|
||||
<object class="GtkPopover" id="date_selector_popover">
|
||||
<property name="position">bottom</property>
|
||||
<property name="border_width">12</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<object class="GcalDateChooser" id="date_chooser">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">12</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCalendar" id="calendar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="show_week_numbers">True</property>
|
||||
<signal name="day-selected" handler="calendar_day_selected" object="GcalDateSelector" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="width">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="max_width_chars">4</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="input_purpose">number</property>
|
||||
<signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="max_width_chars">4</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="input_purpose">number</property>
|
||||
<signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
|
||||
<style>
|
||||
<class name="middle-entry"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">4</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="max_width_chars">4</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="input_purpose">number</property>
|
||||
<signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" swapped="no"/>
|
||||
<signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="width">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="show_week_numbers">True</property>
|
||||
<signal name="day-selected" handler="calendar_day_selected" object="GcalDateSelector" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
+20
-309
@@ -17,6 +17,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gcal-date-chooser.h"
|
||||
#include "gcal-date-selector.h"
|
||||
|
||||
#include <locale.h>
|
||||
@@ -24,35 +25,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user