Files
federated-calendar/src/gcal-time-selector.c
T
Mohammed Sadiq cf787ea5b2 time-selector: set the right lower bound
There was a typo in function name, which was only setting
the upper bound for 24 hour time format. As the default
lower bound is 0, no issue was known so far.

But in cases like the user switched from 12 hour to 24 hour
format there is a chance for some issues to appear as the lower
bound of 12 Hour format is 1, and it won't be reset to 0 when
the user has switched to 24 hour format.

https://bugzilla.gnome.org/show_bug.cgi?id=781448
2017-04-18 09:32:37 -03:00

346 lines
10 KiB
C

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* gcal-time-selector.c
* Copyright (C) 2015 Erick Pérez Castellanos <erickpc@gnome.org>
* 2014 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
*
* gnome-calendar is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* gnome-calendar is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define G_LOG_DOMAIN "GcalTimeSelector"
#include "gcal-time-selector.h"
#include <glib/gi18n.h>
struct _GcalTimeSelector
{
GtkMenuButton parent;
GtkAdjustment *hour_adjustment;
GtkAdjustment *minute_adjustment;
GtkWidget *time_label;
GtkWidget *hour_spin;
GtkWidget *minute_spin;
GtkWidget *period_combo;
GtkWidget *grid;
GDateTime *time;
gboolean format_24h;
};
enum
{
PROP_0,
PROP_TIME,
LAST_PROP
};
enum
{
AM,
PM
};
static void gcal_time_selector_constructed (GObject *object);
G_DEFINE_TYPE (GcalTimeSelector, gcal_time_selector, GTK_TYPE_MENU_BUTTON);
static void
update_label (GcalTimeSelector *selector)
{
gchar *new_label;
if (selector->format_24h)
{
new_label = g_date_time_format (selector->time, "%H:%M");
}
else
{
gchar *time_str;
gint hour, minute, period;
hour = (gint) gtk_adjustment_get_value (selector->hour_adjustment);
minute = (gint) gtk_adjustment_get_value (selector->minute_adjustment);
period = gtk_combo_box_get_active (GTK_COMBO_BOX (selector->period_combo));
time_str = g_strdup_printf ("%.2d:%.2d", hour, minute);
if (period == AM)
new_label = g_strdup_printf (_("%s AM"), time_str);
else
new_label = g_strdup_printf (_("%s PM"), time_str);
g_free (time_str);
}
gtk_label_set_label (GTK_LABEL (selector->time_label), new_label);
g_clear_pointer (&new_label, g_free);
}
static void
update_time (GcalTimeSelector *selector)
{
GDateTime *now, *new_time;
gint hour, minute;
/* Retrieve current time */
hour = (gint) gtk_adjustment_get_value (selector->hour_adjustment);
minute = (gint) gtk_adjustment_get_value (selector->minute_adjustment);
if (!selector->format_24h)
{
hour = hour % 12;
if (gtk_combo_box_get_active (GTK_COMBO_BOX (selector->period_combo)) == PM)
{
g_signal_handlers_block_by_func (selector->period_combo, update_time, selector);
gtk_combo_box_set_active (GTK_COMBO_BOX (selector->period_combo), hour >= 12);
hour += 12;
g_signal_handlers_unblock_by_func (selector->period_combo, update_time, selector);
}
}
now = g_date_time_new_now_local ();
new_time = 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),
hour, minute, 0);
/* Set the new time */
gcal_time_selector_set_time (selector, new_time);
g_clear_pointer (&new_time, g_date_time_unref);
g_clear_pointer (&now, g_date_time_unref);
}
static gboolean
on_output (GtkWidget *widget,
GcalTimeSelector *selector)
{
GtkAdjustment *adjustment;
gchar *text;
gint value;
adjustment = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));
value = (gint) gtk_adjustment_get_value (adjustment);
text = g_strdup_printf ("%02d", value);
gtk_entry_set_text (GTK_ENTRY (widget), text);
g_free (text);
return TRUE;
}
static void
gcal_time_selector_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GcalTimeSelector *self = (GcalTimeSelector*) object;
switch (prop_id)
{
case PROP_TIME:
g_value_set_boxed (value, self->time);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
gcal_time_selector_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GcalTimeSelector *self = (GcalTimeSelector*) object;
switch (prop_id)
{
case PROP_TIME:
gcal_time_selector_set_time (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
void
gcal_time_selector_set_time_format (GcalTimeSelector *selector,
gboolean format_24h)
{
g_return_if_fail (GCAL_IS_TIME_SELECTOR (selector));
selector->format_24h = format_24h;
gtk_widget_set_visible (selector->period_combo, !format_24h);
if (format_24h)
{
gtk_adjustment_set_lower (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (selector->hour_spin)), 0.0);
gtk_adjustment_set_upper (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (selector->hour_spin)), 23.0);
}
else
{
gtk_adjustment_set_lower (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (selector->hour_spin)), 1.0);
gtk_adjustment_set_upper (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (selector->hour_spin)), 12.0);
}
}
static void
gcal_time_selector_finalize (GObject *object)
{
GcalTimeSelector *self = GCAL_TIME_SELECTOR (object);
g_clear_pointer (&self->time, g_date_time_unref);
G_OBJECT_CLASS (gcal_time_selector_parent_class)->finalize (object);
}
static void
gcal_time_selector_dispose (GObject *object)
{
G_OBJECT_CLASS (gcal_time_selector_parent_class)->dispose (object);
}
static void
gcal_time_selector_class_init (GcalTimeSelectorClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->constructed = gcal_time_selector_constructed;
object_class->dispose = gcal_time_selector_dispose;
object_class->finalize = gcal_time_selector_finalize;
object_class->get_property = gcal_time_selector_get_property;
object_class->set_property = gcal_time_selector_set_property;
/**
* GcalTimeSelector::time:
*
* The current time of the selector.
*/
g_object_class_install_property (object_class,
PROP_TIME,
g_param_spec_boxed ("time",
"Time of the selector",
"The current time of the selector",
G_TYPE_DATE_TIME,
G_PARAM_READWRITE));
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/calendar/time-selector.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, time_label);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, hour_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, hour_spin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, minute_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, minute_spin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, period_combo);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass), GcalTimeSelector, grid);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), on_output);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), update_time);
}
static void
gcal_time_selector_init (GcalTimeSelector *self)
{
self->time = g_date_time_new_now_local ();
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
gcal_time_selector_constructed (GObject *object)
{
GcalTimeSelector *selector = GCAL_TIME_SELECTOR (object);
/* chaining up */
G_OBJECT_CLASS (gcal_time_selector_parent_class)->constructed (object);
gtk_widget_set_direction (selector->grid, GTK_TEXT_DIR_LTR);
}
/* Public API */
GtkWidget*
gcal_time_selector_new (void)
{
return g_object_new (GCAL_TYPE_TIME_SELECTOR, NULL);
}
void
gcal_time_selector_set_time (GcalTimeSelector *selector,
GDateTime *time)
{
g_return_if_fail (GCAL_IS_TIME_SELECTOR (selector));
if (selector->time != time)
{
gint hour, minute;
g_clear_pointer (&selector->time, g_date_time_unref);
selector->time = g_date_time_new_local (g_date_time_get_year (time),
g_date_time_get_month (time),
g_date_time_get_day_of_month (time),
g_date_time_get_hour (time),
g_date_time_get_minute (time),
0);
/* Update the spinners */
g_signal_handlers_block_by_func (selector->hour_adjustment, update_time, selector);
g_signal_handlers_block_by_func (selector->minute_adjustment, update_time, selector);
hour = g_date_time_get_hour (time);
minute = g_date_time_get_minute (time);
if (!selector->format_24h)
{
g_signal_handlers_block_by_func (selector->period_combo, update_time, selector);
gtk_combo_box_set_active (GTK_COMBO_BOX (selector->period_combo), hour >= 12);
hour = hour % 12;
hour = (hour == 0)? 12 : hour;
g_signal_handlers_unblock_by_func (selector->period_combo, update_time, selector);
}
gtk_adjustment_set_value (selector->hour_adjustment, hour);
gtk_adjustment_set_value (selector->minute_adjustment, minute);
update_label (selector);
g_signal_handlers_unblock_by_func (selector->hour_adjustment, update_time, selector);
g_signal_handlers_unblock_by_func (selector->minute_adjustment, update_time, selector);
g_object_notify (G_OBJECT (selector), "time");
}
}
GDateTime*
gcal_time_selector_get_time (GcalTimeSelector *selector)
{
g_return_val_if_fail (GCAL_IS_TIME_SELECTOR (selector), NULL);
return selector->time;
}