aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc/e-dateedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/misc/e-dateedit.c')
-rw-r--r--widgets/misc/e-dateedit.c2498
1 files changed, 0 insertions, 2498 deletions
diff --git a/widgets/misc/e-dateedit.c b/widgets/misc/e-dateedit.c
deleted file mode 100644
index fd2676a6b4..0000000000
--- a/widgets/misc/e-dateedit.c
+++ /dev/null
@@ -1,2498 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- * Authors:
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- */
-
-/*
- * EDateEdit - a widget based on GnomeDateEdit to provide a date & optional
- * time field with popups for entering a date.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-dateedit.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <atk/atkrelation.h>
-#include <atk/atkrelationset.h>
-#include <glib/gi18n.h>
-
-#include <libebackend/libebackend.h>
-
-#include <e-util/e-util.h>
-#include "e-calendar.h"
-
-#define E_DATE_EDIT_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), E_TYPE_DATE_EDIT, EDateEditPrivate))
-
-struct _EDateEditPrivate {
- GtkWidget *date_entry;
- GtkWidget *date_button;
-
- GtkWidget *space;
-
- GtkWidget *time_combo;
-
- GtkWidget *cal_popup;
- GtkWidget *calendar;
- GtkWidget *now_button;
- GtkWidget *today_button;
- GtkWidget *none_button; /* This will only be visible if a
- * 'None' date/time is permitted. */
-
- GdkDevice *grabbed_keyboard;
- GdkDevice *grabbed_pointer;
-
- gboolean show_date;
- gboolean show_time;
- gboolean use_24_hour_format;
-
- /* This is TRUE if we want to make the time field insensitive rather
- * than hide it when set_show_time() is called. */
- gboolean make_time_insensitive;
-
- /* This is the range of hours we show in the time popup. */
- gint lower_hour;
- gint upper_hour;
-
- /* This indicates whether the last date committed was invalid.
- * (A date is committed by hitting Return, moving the keyboard focus,
- * or selecting a date in the popup). Note that this only indicates
- * that the date couldn't be parsed. A date set to 'None' is valid
- * here, though e_date_edit_date_is_valid() will return FALSE if an
- * empty date isn't actually permitted. */
- gboolean date_is_valid;
-
- /* This is the last valid date which was set. If the date was set to
- * 'None' or empty, date_set_to_none will be TRUE and the other fields
- * are undefined, so don't use them. */
- gboolean date_set_to_none;
- gint year;
- gint month;
- gint day;
-
- /* This indicates whether the last time committed was invalid.
- * (A time is committed by hitting Return, moving the keyboard focus,
- * or selecting a time in the popup). Note that this only indicates
- * that the time couldn't be parsed. An empty/None time is valid
- * here, though e_date_edit_time_is_valid() will return FALSE if an
- * empty time isn't actually permitted. */
- gboolean time_is_valid;
-
- /* This is the last valid time which was set. If the time was set to
- * 'None' or empty, time_set_to_none will be TRUE and the other fields
- * are undefined, so don't use them. */
- gboolean time_set_to_none;
- gint hour;
- gint minute;
-
- EDateEditGetTimeCallback time_callback;
- gpointer time_callback_data;
- GDestroyNotify time_callback_destroy;
-
- gboolean twodigit_year_can_future;
-
- /* set to TRUE when the date has been changed by typing to the entry */
- gboolean has_been_changed;
-
- gboolean allow_no_date_set;
-};
-
-enum {
- PROP_0,
- PROP_ALLOW_NO_DATE_SET,
- PROP_SHOW_DATE,
- PROP_SHOW_TIME,
- PROP_SHOW_WEEK_NUMBERS,
- PROP_USE_24_HOUR_FORMAT,
- PROP_WEEK_START_DAY,
- PROP_TWODIGIT_YEAR_CAN_FUTURE,
- PROP_SET_NONE
-};
-
-enum {
- CHANGED,
- LAST_SIGNAL
-};
-
-static void create_children (EDateEdit *dedit);
-static gboolean e_date_edit_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling);
-static void e_date_edit_grab_focus (GtkWidget *widget);
-
-static gint on_date_entry_key_press (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit);
-static gint on_date_entry_key_release (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit);
-static void on_date_button_clicked (GtkWidget *widget,
- EDateEdit *dedit);
-static void e_date_edit_show_date_popup (EDateEdit *dedit,
- GdkEvent *event);
-static void position_date_popup (EDateEdit *dedit);
-static void on_date_popup_none_button_clicked (GtkWidget *button,
- EDateEdit *dedit);
-static void on_date_popup_today_button_clicked (GtkWidget *button,
- EDateEdit *dedit);
-static void on_date_popup_now_button_clicked (GtkWidget *button,
- EDateEdit *dedit);
-static gint on_date_popup_delete_event (GtkWidget *widget,
- EDateEdit *dedit);
-static gint on_date_popup_key_press (GtkWidget *widget,
- GdkEventKey *event,
- EDateEdit *dedit);
-static gint on_date_popup_button_press (GtkWidget *widget,
- GdkEvent *button_event,
- gpointer data);
-static void on_date_popup_date_selected (ECalendarItem *calitem,
- EDateEdit *dedit);
-static void hide_date_popup (EDateEdit *dedit);
-static void rebuild_time_popup (EDateEdit *dedit);
-static gboolean field_set_to_none (const gchar *text);
-static gboolean e_date_edit_parse_date (EDateEdit *dedit,
- const gchar *date_text,
- struct tm *date_tm);
-static gboolean e_date_edit_parse_time (EDateEdit *dedit,
- const gchar *time_text,
- struct tm *time_tm);
-static void on_date_edit_time_selected (GtkComboBox *combo,
- EDateEdit *dedit);
-static gint on_time_entry_key_press (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit);
-static gint on_time_entry_key_release (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit);
-static gint on_date_entry_focus_out (GtkEntry *entry,
- GdkEventFocus *event,
- EDateEdit *dedit);
-static gint on_time_entry_focus_out (GtkEntry *entry,
- GdkEventFocus *event,
- EDateEdit *dedit);
-static void e_date_edit_update_date_entry (EDateEdit *dedit);
-static void e_date_edit_update_time_entry (EDateEdit *dedit);
-static void e_date_edit_update_time_combo_state (EDateEdit *dedit);
-static void e_date_edit_check_date_changed (EDateEdit *dedit);
-static void e_date_edit_check_time_changed (EDateEdit *dedit);
-static gboolean e_date_edit_set_date_internal (EDateEdit *dedit,
- gboolean valid,
- gboolean none,
- gint year,
- gint month,
- gint day);
-static gboolean e_date_edit_set_time_internal (EDateEdit *dedit,
- gboolean valid,
- gboolean none,
- gint hour,
- gint minute);
-
-static gint signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE_WITH_CODE (
- EDateEdit,
- e_date_edit,
- GTK_TYPE_HBOX,
- G_IMPLEMENT_INTERFACE (
- E_TYPE_EXTENSIBLE, NULL))
-
-static void
-date_edit_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_ALLOW_NO_DATE_SET:
- e_date_edit_set_allow_no_date_set (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_SHOW_DATE:
- e_date_edit_set_show_date (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_SHOW_TIME:
- e_date_edit_set_show_time (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_SHOW_WEEK_NUMBERS:
- e_date_edit_set_show_week_numbers (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_USE_24_HOUR_FORMAT:
- e_date_edit_set_use_24_hour_format (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_WEEK_START_DAY:
- e_date_edit_set_week_start_day (
- E_DATE_EDIT (object),
- g_value_get_int (value));
- return;
-
- case PROP_TWODIGIT_YEAR_CAN_FUTURE:
- e_date_edit_set_twodigit_year_can_future (
- E_DATE_EDIT (object),
- g_value_get_boolean (value));
- return;
-
- case PROP_SET_NONE:
- if (g_value_get_boolean (value))
- e_date_edit_set_time (E_DATE_EDIT (object), -1);
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-date_edit_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id) {
- case PROP_ALLOW_NO_DATE_SET:
- g_value_set_boolean (
- value, e_date_edit_get_allow_no_date_set (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_SHOW_DATE:
- g_value_set_boolean (
- value, e_date_edit_get_show_date (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_SHOW_TIME:
- g_value_set_boolean (
- value, e_date_edit_get_show_time (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_SHOW_WEEK_NUMBERS:
- g_value_set_boolean (
- value, e_date_edit_get_show_week_numbers (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_USE_24_HOUR_FORMAT:
- g_value_set_boolean (
- value, e_date_edit_get_use_24_hour_format (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_WEEK_START_DAY:
- g_value_set_int (
- value, e_date_edit_get_week_start_day (
- E_DATE_EDIT (object)));
- return;
-
- case PROP_TWODIGIT_YEAR_CAN_FUTURE:
- g_value_set_boolean (
- value, e_date_edit_get_twodigit_year_can_future (
- E_DATE_EDIT (object)));
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
-}
-
-static void
-date_edit_dispose (GObject *object)
-{
- EDateEdit *dedit;
-
- dedit = E_DATE_EDIT (object);
-
- e_date_edit_set_get_time_callback (dedit, NULL, NULL, NULL);
-
- if (dedit->priv->cal_popup != NULL) {
- gtk_widget_destroy (dedit->priv->cal_popup);
- dedit->priv->cal_popup = NULL;
- }
-
- if (dedit->priv->grabbed_keyboard != NULL) {
- gdk_device_ungrab (
- dedit->priv->grabbed_keyboard,
- GDK_CURRENT_TIME);
- g_object_unref (dedit->priv->grabbed_keyboard);
- dedit->priv->grabbed_keyboard = NULL;
- }
-
- if (dedit->priv->grabbed_pointer != NULL) {
- gdk_device_ungrab (
- dedit->priv->grabbed_pointer,
- GDK_CURRENT_TIME);
- g_object_unref (dedit->priv->grabbed_pointer);
- dedit->priv->grabbed_pointer = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_date_edit_parent_class)->dispose (object);
-}
-
-static void
-e_date_edit_class_init (EDateEditClass *class)
-{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- g_type_class_add_private (class, sizeof (EDateEditPrivate));
-
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = date_edit_set_property;
- object_class->get_property = date_edit_get_property;
- object_class->dispose = date_edit_dispose;
-
- widget_class = GTK_WIDGET_CLASS (class);
- widget_class->mnemonic_activate = e_date_edit_mnemonic_activate;
- widget_class->grab_focus = e_date_edit_grab_focus;
-
- g_object_class_install_property (
- object_class,
- PROP_ALLOW_NO_DATE_SET,
- g_param_spec_boolean (
- "allow-no-date-set",
- "Allow No Date Set",
- NULL,
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_SHOW_DATE,
- g_param_spec_boolean (
- "show-date",
- "Show Date",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_SHOW_TIME,
- g_param_spec_boolean (
- "show-time",
- "Show Time",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_SHOW_WEEK_NUMBERS,
- g_param_spec_boolean (
- "show-week-numbers",
- "Show Week Numbers",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_USE_24_HOUR_FORMAT,
- g_param_spec_boolean (
- "use-24-hour-format",
- "Use 24-Hour Format",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_WEEK_START_DAY,
- g_param_spec_int (
- "week-start-day",
- "Week Start Day",
- NULL,
- 0, /* Monday */
- 6, /* Sunday */
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_TWODIGIT_YEAR_CAN_FUTURE,
- g_param_spec_boolean (
- "twodigit-year-can-future",
- "Two-digit year can be treated as future",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (
- object_class,
- PROP_SET_NONE,
- g_param_spec_boolean (
- "set-none",
- "Sets None as selected date",
- NULL,
- FALSE,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
- signals[CHANGED] = g_signal_new (
- "changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (EDateEditClass, changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-e_date_edit_init (EDateEdit *dedit)
-{
- dedit->priv = E_DATE_EDIT_GET_PRIVATE (dedit);
-
- dedit->priv->show_date = TRUE;
- dedit->priv->show_time = TRUE;
- dedit->priv->use_24_hour_format = TRUE;
-
- dedit->priv->make_time_insensitive = FALSE;
-
- dedit->priv->lower_hour = 0;
- dedit->priv->upper_hour = 24;
-
- dedit->priv->date_is_valid = TRUE;
- dedit->priv->date_set_to_none = TRUE;
- dedit->priv->time_is_valid = TRUE;
- dedit->priv->time_set_to_none = TRUE;
- dedit->priv->time_callback = NULL;
- dedit->priv->time_callback_data = NULL;
- dedit->priv->time_callback_destroy = NULL;
-
- dedit->priv->twodigit_year_can_future = TRUE;
- dedit->priv->has_been_changed = FALSE;
-
- create_children (dedit);
-
- /* Set it to the current time. */
- e_date_edit_set_time (dedit, 0);
-
- e_extensible_load_extensions (E_EXTENSIBLE (dedit));
-}
-
-/**
- * e_date_edit_new:
- *
- * Description: Creates a new #EDateEdit widget which can be used
- * to provide an easy to use way for entering dates and times.
- *
- * Returns: a new #EDateEdit widget.
- */
-GtkWidget *
-e_date_edit_new (void)
-{
- EDateEdit *dedit;
- AtkObject *a11y;
-
- dedit = g_object_new (E_TYPE_DATE_EDIT, NULL);
- a11y = gtk_widget_get_accessible (GTK_WIDGET (dedit));
- atk_object_set_name (a11y, _("Date and Time"));
-
- return GTK_WIDGET (dedit);
-}
-
-static void
-create_children (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- ECalendar *calendar;
- GtkWidget *frame, *arrow;
- GtkWidget *vbox, *bbox;
- GtkWidget *child;
- AtkObject *a11y;
- GtkListStore *time_store;
- GList *cells;
- GtkCssProvider *css_provider;
- GtkStyleContext *style_context;
- const gchar *css;
- GError *error = NULL;
-
- priv = dedit->priv;
-
- priv->date_entry = gtk_entry_new ();
- a11y = gtk_widget_get_accessible (priv->date_entry);
- atk_object_set_description (a11y, _("Text entry to input date"));
- atk_object_set_name (a11y, _("Date"));
- gtk_box_pack_start (GTK_BOX (dedit), priv->date_entry, FALSE, TRUE, 0);
- gtk_widget_set_size_request (priv->date_entry, 100, -1);
-
- g_signal_connect (
- priv->date_entry, "key_press_event",
- G_CALLBACK (on_date_entry_key_press), dedit);
- g_signal_connect (
- priv->date_entry, "key_release_event",
- G_CALLBACK (on_date_entry_key_release), dedit);
- g_signal_connect_after (
- priv->date_entry, "focus_out_event",
- G_CALLBACK (on_date_entry_focus_out), dedit);
-
- priv->date_button = gtk_button_new ();
- g_signal_connect (
- priv->date_button, "clicked",
- G_CALLBACK (on_date_button_clicked), dedit);
- gtk_box_pack_start (
- GTK_BOX (dedit), priv->date_button,
- FALSE, FALSE, 0);
- a11y = gtk_widget_get_accessible (priv->date_button);
- atk_object_set_description (a11y, _("Click this button to show a calendar"));
- atk_object_set_name (a11y, _("Date"));
-
- arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
- gtk_container_add (GTK_CONTAINER (priv->date_button), arrow);
- gtk_widget_show (arrow);
-
- if (priv->show_date) {
- gtk_widget_show (priv->date_entry);
- gtk_widget_show (priv->date_button);
- }
-
- /* This is just to create a space between the date & time parts. */
- priv->space = gtk_drawing_area_new ();
- gtk_box_pack_start (GTK_BOX (dedit), priv->space, FALSE, FALSE, 2);
-
- time_store = gtk_list_store_new (1, G_TYPE_STRING);
- priv->time_combo = gtk_combo_box_new_with_model_and_entry (
- GTK_TREE_MODEL (time_store));
- gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (priv->time_combo), 0);
- g_object_unref (time_store);
-
- css_provider = gtk_css_provider_new ();
- css = "GtkComboBox { -GtkComboBox-appears-as-list: 1; }";
- gtk_css_provider_load_from_data (css_provider, css, -1, &error);
- style_context = gtk_widget_get_style_context (priv->time_combo);
- if (error == NULL) {
- gtk_style_context_add_provider (
- style_context,
- GTK_STYLE_PROVIDER (css_provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- } else {
- g_warning ("%s: %s", G_STRFUNC, error->message);
- g_clear_error (&error);
- }
- g_object_unref (css_provider);
-
- child = gtk_bin_get_child (GTK_BIN (priv->time_combo));
-
- /* We need to make sure labels are right-aligned, since we want
- * digits to line up, and with a nonproportional font, the width
- * of a space != width of a digit. Technically, only 12-hour
- * format needs this, but we do it always, for consistency. */
- g_object_set (child, "xalign", 1.0, NULL);
- cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (priv->time_combo));
- if (cells) {
- g_object_set (GTK_CELL_RENDERER (cells->data), "xalign", 1.0, NULL);
- g_list_free (cells);
- }
-
- gtk_box_pack_start (GTK_BOX (dedit), priv->time_combo, FALSE, TRUE, 0);
- gtk_widget_set_size_request (priv->time_combo, 110, -1);
- rebuild_time_popup (dedit);
- a11y = gtk_widget_get_accessible (priv->time_combo);
- atk_object_set_description (a11y, _("Drop-down combination box to select time"));
- atk_object_set_name (a11y, _("Time"));
-
- g_signal_connect (
- child, "key_press_event",
- G_CALLBACK (on_time_entry_key_press), dedit);
- g_signal_connect (
- child, "key_release_event",
- G_CALLBACK (on_time_entry_key_release), dedit);
- g_signal_connect_after (
- child, "focus_out_event",
- G_CALLBACK (on_time_entry_focus_out), dedit);
- g_signal_connect_after (
- priv->time_combo, "changed",
- G_CALLBACK (on_date_edit_time_selected), dedit);
-
- if (priv->show_time || priv->make_time_insensitive)
- gtk_widget_show (priv->time_combo);
-
- if (!priv->show_time && priv->make_time_insensitive)
- gtk_widget_set_sensitive (priv->time_combo, FALSE);
-
- if (priv->show_date
- && (priv->show_time || priv->make_time_insensitive))
- gtk_widget_show (priv->space);
-
- priv->cal_popup = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_window_set_type_hint (
- GTK_WINDOW (priv->cal_popup),
- GDK_WINDOW_TYPE_HINT_COMBO);
- gtk_widget_set_events (
- priv->cal_popup,
- gtk_widget_get_events (priv->cal_popup)
- | GDK_KEY_PRESS_MASK);
- g_signal_connect (
- priv->cal_popup, "delete_event",
- G_CALLBACK (on_date_popup_delete_event), dedit);
- g_signal_connect (
- priv->cal_popup, "key_press_event",
- G_CALLBACK (on_date_popup_key_press), dedit);
- g_signal_connect (
- priv->cal_popup, "button_press_event",
- G_CALLBACK (on_date_popup_button_press), dedit);
- gtk_window_set_resizable (GTK_WINDOW (priv->cal_popup), TRUE);
-
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (priv->cal_popup), frame);
- gtk_widget_show (frame);
-
- vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (frame), vbox);
- gtk_widget_show (vbox);
-
- priv->calendar = e_calendar_new ();
- calendar = E_CALENDAR (priv->calendar);
- gnome_canvas_item_set (
- GNOME_CANVAS_ITEM (calendar->calitem),
- "maximum_days_selected", 1,
- "move_selection_when_moving", FALSE,
- NULL);
-
- g_signal_connect (
- calendar->calitem, "selection_changed",
- G_CALLBACK (on_date_popup_date_selected), dedit);
-
- gtk_box_pack_start (GTK_BOX (vbox), priv->calendar, FALSE, FALSE, 0);
- gtk_widget_show (priv->calendar);
-
- bbox = gtk_hbutton_box_new ();
- gtk_container_set_border_width (GTK_CONTAINER (bbox), 4);
- gtk_box_set_spacing (GTK_BOX (bbox), 2);
- gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
- gtk_widget_show (bbox);
-
- priv->now_button = gtk_button_new_with_mnemonic (_("No_w"));
- gtk_container_add (GTK_CONTAINER (bbox), priv->now_button);
- gtk_widget_show (priv->now_button);
- g_signal_connect (
- priv->now_button, "clicked",
- G_CALLBACK (on_date_popup_now_button_clicked), dedit);
-
- priv->today_button = gtk_button_new_with_mnemonic (_("_Today"));
- gtk_container_add (GTK_CONTAINER (bbox), priv->today_button);
- gtk_widget_show (priv->today_button);
- g_signal_connect (
- priv->today_button, "clicked",
- G_CALLBACK (on_date_popup_today_button_clicked), dedit);
-
- /* Note that we don't show this here, since by default a 'None' date
- * is not permitted. */
- priv->none_button = gtk_button_new_with_mnemonic (_("_None"));
- gtk_container_add (GTK_CONTAINER (bbox), priv->none_button);
- g_signal_connect (
- priv->none_button, "clicked",
- G_CALLBACK (on_date_popup_none_button_clicked), dedit);
- g_object_bind_property (
- dedit, "allow-no-date-set",
- priv->none_button, "visible",
- G_BINDING_SYNC_CREATE);
-}
-
-/* GtkWidget::mnemonic_activate() handler for the EDateEdit */
-static gboolean
-e_date_edit_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling)
-{
- e_date_edit_grab_focus (widget);
- return TRUE;
-}
-
-/* Grab_focus handler for the EDateEdit. If the date field is being shown, we
- * grab the focus to that, otherwise we grab it to the time field. */
-static void
-e_date_edit_grab_focus (GtkWidget *widget)
-{
- EDateEdit *dedit;
- GtkWidget *child;
-
- g_return_if_fail (E_IS_DATE_EDIT (widget));
-
- dedit = E_DATE_EDIT (widget);
- child = gtk_bin_get_child (GTK_BIN (dedit->priv->time_combo));
-
- if (dedit->priv->show_date)
- gtk_widget_grab_focus (dedit->priv->date_entry);
- else
- gtk_widget_grab_focus (child);
-}
-
-/**
- * e_date_edit_set_editable:
- * @dedit: an #EDateEdit widget.
- * @editable: whether or not the widget should accept edits.
- *
- * Allows the programmer to disallow editing (and the popping up of
- * the calendar widget), while still allowing the user to select the
- * date from the GtkEntry.
- */
-void
-e_date_edit_set_editable (EDateEdit *dedit,
- gboolean editable)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- gtk_editable_set_editable (GTK_EDITABLE (priv->date_entry), editable);
- gtk_widget_set_sensitive (priv->date_button, editable);
-}
-
-/**
- * e_date_edit_get_time:
- * @dedit: an #EDateEdit widget.
- * @the_time: returns the last valid time entered.
- * @Returns: the last valid time entered, or -1 if the time is not set.
- *
- * Returns the last valid time entered. If empty times are valid, by calling
- * e_date_edit_set_allow_no_date_set(), then it may return -1.
- *
- * Note that the last time entered may actually have been invalid. You can
- * check this with e_date_edit_time_is_valid().
- */
-time_t
-e_date_edit_get_time (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- struct tm tmp_tm = { 0 };
-
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), -1);
-
- priv = dedit->priv;
-
- /* Try to parse any new value now. */
- e_date_edit_check_date_changed (dedit);
- e_date_edit_check_time_changed (dedit);
-
- if (priv->date_set_to_none)
- return -1;
-
- tmp_tm.tm_year = priv->year;
- tmp_tm.tm_mon = priv->month;
- tmp_tm.tm_mday = priv->day;
-
- if (!priv->show_time || priv->time_set_to_none) {
- tmp_tm.tm_hour = 0;
- tmp_tm.tm_min = 0;
- } else {
- tmp_tm.tm_hour = priv->hour;
- tmp_tm.tm_min = priv->minute;
- }
- tmp_tm.tm_sec = 0;
- tmp_tm.tm_isdst = -1;
-
- return mktime (&tmp_tm);
-}
-
-/**
- * e_date_edit_set_time:
- * @dedit: the EDateEdit widget
- * @the_time: The time and date that should be set on the widget
- *
- * Description: Changes the displayed date and time in the EDateEdit
- * widget to be the one represented by @the_time. If @the_time is 0
- * then current time is used. If it is -1, then the date is set to None.
- *
- * Note that the time is converted to local time using the Unix timezone,
- * so if you are using your own timezones then you should use
- * e_date_edit_set_date() and e_date_edit_set_time_of_day() instead.
- */
-void
-e_date_edit_set_time (EDateEdit *dedit,
- time_t the_time)
-{
- EDateEditPrivate *priv;
- struct tm tmp_tm;
- gboolean date_changed = FALSE, time_changed = FALSE;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (the_time == -1) {
- date_changed = e_date_edit_set_date_internal (
- dedit, TRUE,
- TRUE, 0, 0, 0);
- time_changed = e_date_edit_set_time_internal (
- dedit, TRUE,
- TRUE, 0, 0);
- } else {
- if (the_time == 0) {
- if (priv->time_callback) {
- tmp_tm = (*priv->time_callback) (dedit, priv->time_callback_data);
- } else {
- the_time = time (NULL);
- tmp_tm = *localtime (&the_time);
- }
- } else {
- tmp_tm = *localtime (&the_time);
- }
-
- date_changed = e_date_edit_set_date_internal (
- dedit, TRUE,
- FALSE,
- tmp_tm.tm_year,
- tmp_tm.tm_mon,
- tmp_tm.tm_mday);
- time_changed = e_date_edit_set_time_internal (
- dedit, TRUE,
- FALSE,
- tmp_tm.tm_hour,
- tmp_tm.tm_min);
- }
-
- e_date_edit_update_date_entry (dedit);
- e_date_edit_update_time_entry (dedit);
- e_date_edit_update_time_combo_state (dedit);
-
- /* Emit the signals if the date and/or time has actually changed. */
- if (date_changed || time_changed)
- g_signal_emit (dedit, signals[CHANGED], 0);
-}
-
-/**
- * e_date_edit_get_date:
- * @dedit: an #EDateEdit widget.
- * @year: returns the year set.
- * @month: returns the month set (1 - 12).
- * @day: returns the day set (1 - 31).
- * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'.
- *
- * Returns the last valid date entered into the date field.
- */
-gboolean
-e_date_edit_get_date (EDateEdit *dedit,
- gint *year,
- gint *month,
- gint *day)
-{
- EDateEditPrivate *priv;
-
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- priv = dedit->priv;
-
- /* Try to parse any new value now. */
- e_date_edit_check_date_changed (dedit);
-
- *year = priv->year + 1900;
- *month = priv->month + 1;
- *day = priv->day;
-
- if (priv->date_set_to_none
- && e_date_edit_get_allow_no_date_set (dedit))
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * e_date_edit_set_date:
- * @dedit: an #EDateEdit widget.
- * @year: the year to set.
- * @month: the month to set (1 - 12).
- * @day: the day to set (1 - 31).
- *
- * Sets the date in the date field.
- */
-void
-e_date_edit_set_date (EDateEdit *dedit,
- gint year,
- gint month,
- gint day)
-{
- gboolean date_changed = FALSE;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- date_changed = e_date_edit_set_date_internal (
- dedit, TRUE, FALSE,
- year - 1900, month - 1,
- day);
-
- e_date_edit_update_date_entry (dedit);
- e_date_edit_update_time_combo_state (dedit);
-
- /* Emit the signals if the date has actually changed. */
- if (date_changed)
- g_signal_emit (dedit, signals[CHANGED], 0);
-}
-
-/**
- * e_date_edit_get_time_of_day:
- * @dedit: an #EDateEdit widget.
- * @hour: returns the hour set, or 0 if the time isn't set.
- * @minute: returns the minute set, or 0 if the time isn't set.
- * @Returns: TRUE if a time was set, or FALSE if the field is empty or 'None'.
- *
- * Returns the last valid time entered into the time field.
- */
-gboolean
-e_date_edit_get_time_of_day (EDateEdit *dedit,
- gint *hour,
- gint *minute)
-{
- EDateEditPrivate *priv;
-
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- priv = dedit->priv;
-
- /* Try to parse any new value now. */
- e_date_edit_check_time_changed (dedit);
-
- if (priv->time_set_to_none) {
- *hour = 0;
- *minute = 0;
- return FALSE;
- } else {
- *hour = priv->hour;
- *minute = priv->minute;
- return TRUE;
- }
-}
-
-/**
- * e_date_edit_set_time_of_day:
- * @dedit: an #EDateEdit widget.
- * @hour: the hour to set, or -1 to set the time to None (i.e. empty).
- * @minute: the minute to set.
- *
- * Description: Sets the time in the time field.
- */
-void
-e_date_edit_set_time_of_day (EDateEdit *dedit,
- gint hour,
- gint minute)
-{
- EDateEditPrivate *priv;
- gboolean time_changed = FALSE;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (hour == -1) {
- gboolean allow_no_date_set = e_date_edit_get_allow_no_date_set (dedit);
- g_return_if_fail (allow_no_date_set);
- if (!priv->time_set_to_none) {
- priv->time_set_to_none = TRUE;
- time_changed = TRUE;
- }
- } else if (priv->time_set_to_none
- || priv->hour != hour
- || priv->minute != minute) {
- priv->time_set_to_none = FALSE;
- priv->hour = hour;
- priv->minute = minute;
- time_changed = TRUE;
- }
-
- e_date_edit_update_time_entry (dedit);
-
- if (time_changed)
- g_signal_emit (dedit, signals[CHANGED], 0);
-}
-
-void
-e_date_edit_set_date_and_time_of_day (EDateEdit *dedit,
- gint year,
- gint month,
- gint day,
- gint hour,
- gint minute)
-{
- gboolean date_changed, time_changed;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- date_changed = e_date_edit_set_date_internal (
- dedit, TRUE, FALSE,
- year - 1900, month - 1, day);
- time_changed = e_date_edit_set_time_internal (
- dedit, TRUE, FALSE,
- hour, minute);
-
- e_date_edit_update_date_entry (dedit);
- e_date_edit_update_time_entry (dedit);
- e_date_edit_update_time_combo_state (dedit);
-
- if (date_changed || time_changed)
- g_signal_emit (dedit, signals[CHANGED], 0);
-}
-
-/**
- * e_date_edit_get_show_date:
- * @dedit: an #EDateEdit widget.
- * @Returns: Whether the date field is shown.
- *
- * Description: Returns TRUE if the date field is currently shown.
- */
-gboolean
-e_date_edit_get_show_date (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE);
-
- return dedit->priv->show_date;
-}
-
-/**
- * e_date_edit_set_show_date:
- * @dedit: an #EDateEdit widget.
- * @show_date: TRUE if the date field should be shown.
- *
- * Description: Specifies whether the date field should be shown. The date
- * field would be hidden if only a time needed to be entered.
- */
-void
-e_date_edit_set_show_date (EDateEdit *dedit,
- gboolean show_date)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (priv->show_date == show_date)
- return;
-
- priv->show_date = show_date;
-
- if (show_date) {
- gtk_widget_show (priv->date_entry);
- gtk_widget_show (priv->date_button);
- } else {
- gtk_widget_hide (priv->date_entry);
- gtk_widget_hide (priv->date_button);
- }
-
- e_date_edit_update_time_combo_state (dedit);
-
- if (priv->show_date
- && (priv->show_time || priv->make_time_insensitive))
- gtk_widget_show (priv->space);
- else
- gtk_widget_hide (priv->space);
-
- g_object_notify (G_OBJECT (dedit), "show-date");
-}
-
-/**
- * e_date_edit_get_show_time:
- * @dedit: an #EDateEdit widget
- * @Returns: Whether the time field is shown.
- *
- * Description: Returns TRUE if the time field is currently shown.
- */
-gboolean
-e_date_edit_get_show_time (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE);
-
- return dedit->priv->show_time;
-}
-
-/**
- * e_date_edit_set_show_time:
- * @dedit: an #EDateEdit widget
- * @show_time: TRUE if the time field should be shown.
- *
- * Description: Specifies whether the time field should be shown. The time
- * field would be hidden if only a date needed to be entered.
- */
-void
-e_date_edit_set_show_time (EDateEdit *dedit,
- gboolean show_time)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (priv->show_time == show_time)
- return;
-
- priv->show_time = show_time;
-
- e_date_edit_update_time_combo_state (dedit);
-
- g_object_notify (G_OBJECT (dedit), "show-time");
-}
-
-/**
- * e_date_edit_get_make_time_insensitive:
- * @dedit: an #EDateEdit widget
- * @Returns: Whether the time field is be made insensitive instead of hiding
- * it.
- *
- * Description: Returns TRUE if the time field is made insensitive instead of
- * hiding it.
- */
-gboolean
-e_date_edit_get_make_time_insensitive (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE);
-
- return dedit->priv->make_time_insensitive;
-}
-
-/**
- * e_date_edit_set_make_time_insensitive:
- * @dedit: an #EDateEdit widget
- * @make_insensitive: TRUE if the time field should be made insensitive instead
- * of hiding it.
- *
- * Description: Specifies whether the time field should be made insensitive
- * rather than hiding it. Note that this doesn't make it insensitive - you
- * need to call e_date_edit_set_show_time() with FALSE as show_time to do that.
- *
- * This is useful if you want to disable the time field, but don't want it to
- * disappear as that may affect the layout of the widgets.
- */
-void
-e_date_edit_set_make_time_insensitive (EDateEdit *dedit,
- gboolean make_insensitive)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (priv->make_time_insensitive == make_insensitive)
- return;
-
- priv->make_time_insensitive = make_insensitive;
-
- e_date_edit_update_time_combo_state (dedit);
-}
-
-/**
- * e_date_edit_get_week_start_day:
- * @dedit: an #EDateEdit widget
- * @Returns: the week start day, from 0 (Monday) to 6 (Sunday).
- *
- * Description: Returns the week start day currently used in the calendar
- * popup.
- */
-gint
-e_date_edit_get_week_start_day (EDateEdit *dedit)
-{
- gint week_start_day;
-
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), 1);
-
- g_object_get (
- E_CALENDAR (dedit->priv->calendar)->calitem,
- "week_start_day", &week_start_day, NULL);
-
- return week_start_day;
-}
-
-/**
- * e_date_edit_set_week_start_day:
- * @dedit: an #EDateEdit widget
- * @week_start_day: the week start day, from 0 (Monday) to 6 (Sunday).
- *
- * Description: Sets the week start day to use in the calendar popup.
- */
-void
-e_date_edit_set_week_start_day (EDateEdit *dedit,
- gint week_start_day)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- gnome_canvas_item_set (
- GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
- "week_start_day", week_start_day, NULL);
-
- g_object_notify (G_OBJECT (dedit), "week-start-day");
-}
-
-/* Whether we show week numbers in the date popup. */
-gboolean
-e_date_edit_get_show_week_numbers (EDateEdit *dedit)
-{
- gboolean show_week_numbers;
-
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- g_object_get (
- E_CALENDAR (dedit->priv->calendar)->calitem,
- "show_week_numbers", &show_week_numbers, NULL);
-
- return show_week_numbers;
-}
-
-void
-e_date_edit_set_show_week_numbers (EDateEdit *dedit,
- gboolean show_week_numbers)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- gnome_canvas_item_set (
- GNOME_CANVAS_ITEM (E_CALENDAR (dedit->priv->calendar)->calitem),
- "show_week_numbers", show_week_numbers, NULL);
-
- g_object_notify (G_OBJECT (dedit), "show-week-numbers");
-}
-
-/* Whether we use 24 hour format in the time field & popup. */
-gboolean
-e_date_edit_get_use_24_hour_format (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), TRUE);
-
- return dedit->priv->use_24_hour_format;
-}
-
-void
-e_date_edit_set_use_24_hour_format (EDateEdit *dedit,
- gboolean use_24_hour_format)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- if (dedit->priv->use_24_hour_format == use_24_hour_format)
- return;
-
- dedit->priv->use_24_hour_format = use_24_hour_format;
-
- rebuild_time_popup (dedit);
-
- e_date_edit_update_time_entry (dedit);
-
- g_object_notify (G_OBJECT (dedit), "use-24-hour-format");
-}
-
-/* Whether we allow the date to be set to 'None'. e_date_edit_get_time() will
- * return (time_t) -1 in this case. */
-gboolean
-e_date_edit_get_allow_no_date_set (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- return dedit->priv->allow_no_date_set;
-}
-
-void
-e_date_edit_set_allow_no_date_set (EDateEdit *dedit,
- gboolean allow_no_date_set)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- if (dedit->priv->allow_no_date_set == allow_no_date_set)
- return;
-
- dedit->priv->allow_no_date_set = allow_no_date_set;
-
- if (!allow_no_date_set) {
- /* If the date is showing, we make sure it isn't 'None' (we
- * don't really mind if the time is empty), else if just the
- * time is showing we make sure it isn't 'None'. */
- if (dedit->priv->show_date) {
- if (dedit->priv->date_set_to_none)
- e_date_edit_set_time (dedit, 0);
- } else {
- if (dedit->priv->time_set_to_none)
- e_date_edit_set_time (dedit, 0);
- }
- }
-
- g_object_notify (G_OBJECT (dedit), "allow-no-date-set");
-}
-
-/* The range of time to show in the time combo popup. */
-void
-e_date_edit_get_time_popup_range (EDateEdit *dedit,
- gint *lower_hour,
- gint *upper_hour)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- *lower_hour = dedit->priv->lower_hour;
- *upper_hour = dedit->priv->upper_hour;
-}
-
-void
-e_date_edit_set_time_popup_range (EDateEdit *dedit,
- gint lower_hour,
- gint upper_hour)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (priv->lower_hour == lower_hour
- && priv->upper_hour == upper_hour)
- return;
-
- priv->lower_hour = lower_hour;
- priv->upper_hour = upper_hour;
-
- rebuild_time_popup (dedit);
-
- /* Setting the combo list items seems to mess up the time entry, so
- * we set it again. We have to reset it to its last valid time. */
- priv->time_is_valid = TRUE;
- e_date_edit_update_time_entry (dedit);
-}
-
-/* The arrow button beside the date field has been clicked, so we show the
- * popup with the ECalendar in. */
-static void
-on_date_button_clicked (GtkWidget *widget,
- EDateEdit *dedit)
-{
- GdkEvent *event;
-
- /* Obtain the GdkEvent that triggered
- * the date button's "clicked" signal. */
- event = gtk_get_current_event ();
- e_date_edit_show_date_popup (dedit, event);
-}
-
-static void
-e_date_edit_show_date_popup (EDateEdit *dedit,
- GdkEvent *event)
-{
- EDateEditPrivate *priv;
- ECalendar *calendar;
- GdkDevice *event_device;
- GdkDevice *assoc_device;
- GdkDevice *keyboard_device;
- GdkDevice *pointer_device;
- GdkWindow *window;
- GdkGrabStatus grab_status;
- struct tm mtm;
- const gchar *date_text;
- GDate selected_day;
- gboolean clear_selection = FALSE;
- guint event_time;
-
- priv = dedit->priv;
- calendar = E_CALENDAR (priv->calendar);
-
- date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry));
- if (field_set_to_none (date_text)
- || !e_date_edit_parse_date (dedit, date_text, &mtm))
- clear_selection = TRUE;
-
- if (clear_selection) {
- e_calendar_item_set_selection (calendar->calitem, NULL, NULL);
- } else {
- g_date_clear (&selected_day, 1);
- g_date_set_dmy (
- &selected_day, mtm.tm_mday, mtm.tm_mon + 1,
- mtm.tm_year + 1900);
- e_calendar_item_set_selection (
- calendar->calitem,
- &selected_day, NULL);
- }
-
- /* FIXME: Hack. Change ECalendarItem so it doesn't queue signal
- * emissions. */
- calendar->calitem->selection_changed = FALSE;
-
- position_date_popup (dedit);
- gtk_widget_show (priv->cal_popup);
- gtk_widget_grab_focus (priv->cal_popup);
- gtk_grab_add (priv->cal_popup);
-
- window = gtk_widget_get_window (priv->cal_popup);
-
- g_return_if_fail (priv->grabbed_keyboard == NULL);
- g_return_if_fail (priv->grabbed_pointer == NULL);
-
- event_device = gdk_event_get_device (event);
- assoc_device = gdk_device_get_associated_device (event_device);
-
- event_time = gdk_event_get_time (event);
-
- if (gdk_device_get_source (event_device) == GDK_SOURCE_KEYBOARD) {
- keyboard_device = event_device;
- pointer_device = assoc_device;
- } else {
- keyboard_device = assoc_device;
- pointer_device = event_device;
- }
-
- if (keyboard_device != NULL) {
- grab_status = gdk_device_grab (
- keyboard_device,
- window,
- GDK_OWNERSHIP_WINDOW,
- TRUE,
- GDK_KEY_PRESS_MASK |
- GDK_KEY_RELEASE_MASK,
- NULL,
- event_time);
- if (grab_status == GDK_GRAB_SUCCESS) {
- priv->grabbed_keyboard =
- g_object_ref (keyboard_device);
- }
- }
-
- if (pointer_device != NULL) {
- grab_status = gdk_device_grab (
- pointer_device,
- window,
- GDK_OWNERSHIP_WINDOW,
- TRUE,
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK,
- NULL,
- event_time);
- if (grab_status == GDK_GRAB_SUCCESS) {
- priv->grabbed_pointer =
- g_object_ref (pointer_device);
- } else if (priv->grabbed_keyboard != NULL) {
- gdk_device_ungrab (
- priv->grabbed_keyboard,
- event_time);
- g_object_unref (priv->grabbed_keyboard);
- priv->grabbed_keyboard = NULL;
- }
- }
-
- gdk_window_focus (window, event_time);
-}
-
-/* This positions the date popup below and to the left of the arrow button,
- * just before it is shown. */
-static void
-position_date_popup (EDateEdit *dedit)
-{
- gint x, y;
- gint win_x, win_y;
- gint bwidth, bheight;
- GtkWidget *toplevel;
- GdkWindow *window;
- GtkRequisition cal_req, button_req;
- gint screen_width, screen_height;
-
- gtk_widget_get_preferred_size (dedit->priv->cal_popup, &cal_req, NULL);
-
- gtk_widget_get_preferred_size (dedit->priv->date_button, &button_req, NULL);
- bwidth = button_req.width;
- gtk_widget_get_preferred_size (
- gtk_widget_get_parent (dedit->priv->date_button), &button_req, NULL);
- bheight = button_req.height;
-
- gtk_widget_translate_coordinates (
- dedit->priv->date_button,
- gtk_widget_get_toplevel (dedit->priv->date_button),
- bwidth - cal_req.width, bheight, &x, &y);
-
- toplevel = gtk_widget_get_toplevel (dedit->priv->date_button);
- window = gtk_widget_get_window (toplevel);
- gdk_window_get_origin (window, &win_x, &win_y);
-
- x += win_x;
- y += win_y;
-
- screen_width = gdk_screen_width ();
- screen_height = gdk_screen_height ();
-
- x = CLAMP (x, 0, MAX (0, screen_width - cal_req.width));
- y = CLAMP (y, 0, MAX (0, screen_height - cal_req.height));
-
- gtk_window_move (GTK_WINDOW (dedit->priv->cal_popup), x, y);
-}
-
-/* A date has been selected in the date popup, so we set the date field
- * and hide the popup. */
-static void
-on_date_popup_date_selected (ECalendarItem *calitem,
- EDateEdit *dedit)
-{
- GDate start_date, end_date;
-
- hide_date_popup (dedit);
-
- if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
- return;
-
- e_date_edit_set_date (
- dedit, g_date_get_year (&start_date),
- g_date_get_month (&start_date),
- g_date_get_day (&start_date));
-}
-
-static void
-on_date_popup_now_button_clicked (GtkWidget *button,
- EDateEdit *dedit)
-{
- hide_date_popup (dedit);
- e_date_edit_set_time (dedit, 0);
-}
-
-static void
-on_date_popup_today_button_clicked (GtkWidget *button,
- EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- struct tm tmp_tm;
- time_t t;
-
- priv = dedit->priv;
-
- hide_date_popup (dedit);
-
- if (priv->time_callback) {
- tmp_tm = (*priv->time_callback) (dedit, priv->time_callback_data);
- } else {
- t = time (NULL);
- tmp_tm = *localtime (&t);
- }
-
- e_date_edit_set_date (
- dedit, tmp_tm.tm_year + 1900,
- tmp_tm.tm_mon + 1, tmp_tm.tm_mday);
-}
-
-static void
-on_date_popup_none_button_clicked (GtkWidget *button,
- EDateEdit *dedit)
-{
- hide_date_popup (dedit);
- e_date_edit_set_time (dedit, -1);
-}
-
-/* A key has been pressed while the date popup is showing. If it is the Escape
- * key we hide the popup. */
-static gint
-on_date_popup_key_press (GtkWidget *widget,
- GdkEventKey *event,
- EDateEdit *dedit)
-{
- if (event->keyval == GDK_KEY_Escape) {
- g_signal_stop_emission_by_name (widget, "key_press_event");
- hide_date_popup (dedit);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* A mouse button has been pressed while the date popup is showing.
- * Any button press events used to select days etc. in the popup will have
- * have been handled elsewhere, so here we just hide the popup.
- * (This function is yanked from gtkcombo.c) */
-static gint
-on_date_popup_button_press (GtkWidget *widget,
- GdkEvent *button_event,
- gpointer data)
-{
- EDateEdit *dedit;
- GtkWidget *child;
-
- dedit = data;
-
- child = gtk_get_event_widget (button_event);
-
- /* We don't ask for button press events on the grab widget, so
- * if an event is reported directly to the grab widget, it must
- * be on a window outside the application (and thus we remove
- * the popup window). Otherwise, we check if the widget is a child
- * of the grab widget, and only remove the popup window if it
- * is not.
- */
- if (child != widget) {
- while (child) {
- if (child == widget)
- return FALSE;
- child = gtk_widget_get_parent (child);
- }
- }
-
- hide_date_popup (dedit);
-
- return TRUE;
-}
-
-/* A delete event has been received for the date popup, so we hide it and
- * return TRUE so it doesn't get destroyed. */
-static gint
-on_date_popup_delete_event (GtkWidget *widget,
- EDateEdit *dedit)
-{
- hide_date_popup (dedit);
- return TRUE;
-}
-
-/* Hides the date popup, removing any grabs. */
-static void
-hide_date_popup (EDateEdit *dedit)
-{
- gtk_widget_hide (dedit->priv->cal_popup);
- gtk_grab_remove (dedit->priv->cal_popup);
-
- if (dedit->priv->grabbed_keyboard != NULL) {
- gdk_device_ungrab (
- dedit->priv->grabbed_keyboard,
- GDK_CURRENT_TIME);
- g_object_unref (dedit->priv->grabbed_keyboard);
- dedit->priv->grabbed_keyboard = NULL;
- }
-
- if (dedit->priv->grabbed_pointer != NULL) {
- gdk_device_ungrab (
- dedit->priv->grabbed_pointer,
- GDK_CURRENT_TIME);
- g_object_unref (dedit->priv->grabbed_pointer);
- dedit->priv->grabbed_pointer = NULL;
- }
-}
-
-/* Clears the time popup and rebuilds it using the lower_hour, upper_hour
- * and use_24_hour_format settings. */
-static void
-rebuild_time_popup (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- GtkTreeModel *model;
- GtkListStore *list_store;
- GtkTreeIter iter;
- gchar buffer[40];
- struct tm tmp_tm;
- gint hour, min;
-
- priv = dedit->priv;
-
- model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->time_combo));
- list_store = GTK_LIST_STORE (model);
- gtk_list_store_clear (list_store);
-
- /* Fill the struct tm with some sane values. */
- tmp_tm.tm_year = 2000;
- tmp_tm.tm_mon = 0;
- tmp_tm.tm_mday = 1;
- tmp_tm.tm_sec = 0;
- tmp_tm.tm_isdst = 0;
-
- for (hour = priv->lower_hour; hour <= priv->upper_hour; hour++) {
-
- /* We don't want to display midnight at the end,
- * since that is really in the next day. */
- if (hour == 24)
- break;
-
- /* We want to finish on upper_hour, with min == 0. */
- for (min = 0;
- min == 0 || (min < 60 && hour != priv->upper_hour);
- min += 30) {
- tmp_tm.tm_hour = hour;
- tmp_tm.tm_min = min;
-
- if (priv->use_24_hour_format)
- /* This is a strftime() format.
- * %H = hour (0-23), %M = minute. */
- e_time_format_time (
- &tmp_tm, 1, 0,
- buffer, sizeof (buffer));
- else
- /* This is a strftime() format.
- * %I = hour (1-12), %M = minute,
- * %p = am/pm string. */
- e_time_format_time (
- &tmp_tm, 0, 0,
- buffer, sizeof (buffer));
-
- /* For 12-hour am/pm format, we want space padding,
- * not zero padding. This can be done with strftime's
- * %l, but it's a potentially unportable extension. */
- if (!priv->use_24_hour_format && buffer[0] == '0')
- buffer[0] = ' ';
-
- gtk_list_store_append (list_store, &iter);
- gtk_list_store_set (list_store, &iter, 0, buffer, -1);
- }
- }
-}
-
-static gboolean
-e_date_edit_parse_date (EDateEdit *dedit,
- const gchar *date_text,
- struct tm *date_tm)
-{
- gboolean twodigit_year = FALSE;
-
- if (e_time_parse_date_ex (date_text, date_tm, &twodigit_year) != E_TIME_PARSE_OK)
- return FALSE;
-
- if (twodigit_year && !dedit->priv->twodigit_year_can_future) {
- time_t t = time (NULL);
- struct tm *today_tm = localtime (&t);
-
- /* It was only 2 digit year in dedit and it was interpreted as
- * in the future, but we don't want it as this, so decrease by
- * 100 years to last century. */
- if (date_tm->tm_year > today_tm->tm_year)
- date_tm->tm_year -= 100;
- }
-
- return TRUE;
-}
-
-static gboolean
-e_date_edit_parse_time (EDateEdit *dedit,
- const gchar *time_text,
- struct tm *time_tm)
-{
- if (field_set_to_none (time_text)) {
- time_tm->tm_hour = 0;
- time_tm->tm_min = 0;
- return TRUE;
- }
-
- if (e_time_parse_time (time_text, time_tm) != E_TIME_PARSE_OK)
- return FALSE;
-
- return TRUE;
-}
-
-/* Returns TRUE if the string is empty or is "None" in the current locale.
- * It ignores whitespace. */
-static gboolean
-field_set_to_none (const gchar *text)
-{
- const gchar *pos;
- const gchar *none_string;
- gint n;
-
- pos = text;
- while (n = (gint)((guchar) * pos), isspace (n))
- pos++;
-
- /* Translators: "None" for date field of a date edit, shown when
- * there is no date set. */
- none_string = C_("date", "None");
-
- if (*pos == '\0' || !strncmp (pos, none_string, strlen (none_string)))
- return TRUE;
- return FALSE;
-}
-
-static void
-on_date_edit_time_selected (GtkComboBox *combo,
- EDateEdit *dedit)
-{
- GtkWidget *child;
-
- child = gtk_bin_get_child (GTK_BIN (combo));
-
- /* We only want to emit signals when an item is selected explicitly,
- * not when it is selected by the silly combo update thing. */
- if (gtk_combo_box_get_active (combo) == -1)
- return;
-
- if (!gtk_widget_get_mapped (child))
- return;
-
- e_date_edit_check_time_changed (dedit);
-}
-
-static gint
-on_date_entry_key_press (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit)
-{
- GdkModifierType event_state = 0;
- guint event_keyval = 0;
-
- gdk_event_get_keyval (key_event, &event_keyval);
- gdk_event_get_state (key_event, &event_state);
-
- if (event_state & GDK_MOD1_MASK
- && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down
- || event_keyval == GDK_KEY_Return)) {
- g_signal_stop_emission_by_name (widget, "key_press_event");
- e_date_edit_show_date_popup (dedit, key_event);
- return TRUE;
- }
-
- /* If the user hits the return key emit a "date_changed" signal if
- * needed. But let the signal carry on. */
- if (event_keyval == GDK_KEY_Return) {
- e_date_edit_check_date_changed (dedit);
- return FALSE;
- }
-
- return FALSE;
-}
-
-static gint
-on_time_entry_key_press (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit)
-{
- GtkWidget *child;
- GdkModifierType event_state = 0;
- guint event_keyval = 0;
-
- gdk_event_get_keyval (key_event, &event_keyval);
- gdk_event_get_state (key_event, &event_state);
-
- child = gtk_bin_get_child (GTK_BIN (dedit->priv->time_combo));
-
- /* I'd like to use Alt+Up/Down for popping up the list, like Win32,
- * but the combo steals any Up/Down keys, so we use Alt + Return. */
-#if 0
- if (event_state & GDK_MOD1_MASK
- && (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down)) {
-#else
- if (event_state & GDK_MOD1_MASK && event_keyval == GDK_KEY_Return) {
-#endif
- g_signal_stop_emission_by_name (widget, "key_press_event");
- g_signal_emit_by_name (child, "activate", 0);
- return TRUE;
- }
-
- /* Stop the return key from emitting the activate signal, and check
- * if we need to emit a "time_changed" signal. */
- if (event_keyval == GDK_KEY_Return) {
- g_signal_stop_emission_by_name (widget, "key_press_event");
- e_date_edit_check_time_changed (dedit);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gint
-on_date_entry_key_release (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit)
-{
- e_date_edit_check_date_changed (dedit);
- return TRUE;
-}
-
-static gint
-on_time_entry_key_release (GtkWidget *widget,
- GdkEvent *key_event,
- EDateEdit *dedit)
-{
- guint event_keyval = 0;
-
- gdk_event_get_keyval (key_event, &event_keyval);
-
- if (event_keyval == GDK_KEY_Up || event_keyval == GDK_KEY_Down) {
- g_signal_stop_emission_by_name (widget, "key_release_event");
- e_date_edit_check_time_changed (dedit);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gint
-on_date_entry_focus_out (GtkEntry *entry,
- GdkEventFocus *event,
- EDateEdit *dedit)
-{
- struct tm tmp_tm;
- GtkWidget *msg_dialog;
-
- tmp_tm.tm_year = 0;
- tmp_tm.tm_mon = 0;
- tmp_tm.tm_mday = 0;
-
- e_date_edit_check_date_changed (dedit);
-
- if (!e_date_edit_date_is_valid (dedit)) {
- msg_dialog = gtk_message_dialog_new (
- NULL,
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK,
- "%s", _("Invalid Date Value"));
- gtk_dialog_run (GTK_DIALOG (msg_dialog));
- gtk_widget_destroy (msg_dialog);
- e_date_edit_get_date (
- dedit, &tmp_tm.tm_year,
- &tmp_tm.tm_mon, &tmp_tm.tm_mday);
- e_date_edit_set_date (
- dedit, tmp_tm.tm_year,
- tmp_tm.tm_mon, tmp_tm.tm_mday);
- gtk_widget_grab_focus (GTK_WIDGET (entry));
- return FALSE;
- } else if (e_date_edit_get_date (
- dedit, &tmp_tm.tm_year, &tmp_tm.tm_mon, &tmp_tm.tm_mday)) {
-
- e_date_edit_set_date (
- dedit,tmp_tm.tm_year,tmp_tm.tm_mon,tmp_tm.tm_mday);
-
- if (dedit->priv->has_been_changed) {
- /* The previous one didn't emit changed signal,
- * but we want it even here, thus doing itself. */
- g_signal_emit (dedit, signals[CHANGED], 0);
- dedit->priv->has_been_changed = FALSE;
- }
- } else {
- dedit->priv->date_set_to_none = TRUE;
- e_date_edit_update_date_entry (dedit);
- }
- return FALSE;
-}
-
-static gint
-on_time_entry_focus_out (GtkEntry *entry,
- GdkEventFocus *event,
- EDateEdit *dedit)
-{
- GtkWidget *msg_dialog;
-
- e_date_edit_check_time_changed (dedit);
-
- if (!e_date_edit_time_is_valid (dedit)) {
- msg_dialog = gtk_message_dialog_new (
- NULL,
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK,
- "%s", _("Invalid Time Value"));
- gtk_dialog_run (GTK_DIALOG (msg_dialog));
- gtk_widget_destroy (msg_dialog);
- e_date_edit_set_time (dedit,e_date_edit_get_time (dedit));
- gtk_widget_grab_focus (GTK_WIDGET (entry));
- return FALSE;
- }
- return FALSE;
-}
-
-static void
-add_relation (EDateEdit *dedit,
- GtkWidget *widget)
-{
- AtkObject *a11yEdit, *a11yWidget;
- AtkRelationSet *set;
- AtkRelation *relation;
- GPtrArray *target;
- gpointer target_object;
-
- /* add a labelled_by relation for widget for accessibility */
-
- a11yEdit = gtk_widget_get_accessible (GTK_WIDGET (dedit));
- a11yWidget = gtk_widget_get_accessible (widget);
-
- set = atk_object_ref_relation_set (a11yWidget);
- if (set != NULL) {
- relation = atk_relation_set_get_relation_by_type (
- set, ATK_RELATION_LABELLED_BY);
- /* check whether has a labelled_by relation already */
- if (relation != NULL)
- return;
- }
-
- set = atk_object_ref_relation_set (a11yEdit);
- if (!set)
- return;
-
- relation = atk_relation_set_get_relation_by_type (
- set, ATK_RELATION_LABELLED_BY);
- if (relation != NULL) {
- target = atk_relation_get_target (relation);
- target_object = g_ptr_array_index (target, 0);
- if (ATK_IS_OBJECT (target_object)) {
- atk_object_add_relationship (
- a11yWidget,
- ATK_RELATION_LABELLED_BY,
- ATK_OBJECT (target_object));
- }
- }
-}
-
-/* This sets the text in the date entry according to the current settings. */
-static void
-e_date_edit_update_date_entry (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- gchar buffer[100];
- struct tm tmp_tm = { 0 };
-
- priv = dedit->priv;
-
- if (priv->date_set_to_none || !priv->date_is_valid) {
- gtk_entry_set_text (GTK_ENTRY (priv->date_entry), C_("date", "None"));
- } else {
- /* This is a strftime() format for a short date.
- * %x the preferred date representation for the current locale
- * without the time, but is forced to use 4 digit year. */
- gchar *format = e_time_get_d_fmt_with_4digit_year ();
- time_t tt;
-
- tmp_tm.tm_year = priv->year;
- tmp_tm.tm_mon = priv->month;
- tmp_tm.tm_mday = priv->day;
- tmp_tm.tm_isdst = -1;
-
- /* initialize all 'struct tm' members properly */
- tt = mktime (&tmp_tm);
- if (tt && localtime (&tt))
- tmp_tm = *localtime (&tt);
-
- e_utf8_strftime (buffer, sizeof (buffer), format, &tmp_tm);
- g_free (format);
- gtk_entry_set_text (GTK_ENTRY (priv->date_entry), buffer);
- }
-
- add_relation (dedit, priv->date_entry);
- add_relation (dedit, priv->date_button);
-}
-
-/* This sets the text in the time entry according to the current settings. */
-static void
-e_date_edit_update_time_entry (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- GtkComboBox *combo_box;
- GtkWidget *child;
- gchar buffer[40];
- struct tm tmp_tm = { 0 };
-
- priv = dedit->priv;
-
- combo_box = GTK_COMBO_BOX (priv->time_combo);
- child = gtk_bin_get_child (GTK_BIN (priv->time_combo));
-
- if (priv->time_set_to_none || !priv->time_is_valid) {
- gtk_combo_box_set_active (combo_box, -1);
- gtk_entry_set_text (GTK_ENTRY (child), "");
- } else {
- GtkTreeModel *model;
- GtkTreeIter iter;
- gboolean valid;
- gchar *b;
-
- /* Set these to reasonable values just in case. */
- tmp_tm.tm_year = 2000;
- tmp_tm.tm_mon = 0;
- tmp_tm.tm_mday = 1;
-
- tmp_tm.tm_hour = priv->hour;
- tmp_tm.tm_min = priv->minute;
-
- tmp_tm.tm_sec = 0;
- tmp_tm.tm_isdst = -1;
-
- if (priv->use_24_hour_format)
- /* This is a strftime() format.
- * %H = hour (0-23), %M = minute. */
- e_time_format_time (
- &tmp_tm, 1, 0, buffer, sizeof (buffer));
- else
- /* This is a strftime() format.
- * %I = hour (1-12), %M = minute, %p = am/pm. */
- e_time_format_time (
- &tmp_tm, 0, 0, buffer, sizeof (buffer));
-
- /* For 12-hour am/pm format, we want space padding, not
- * zero padding. This can be done with strftime's %l,
- * but it's a potentially unportable extension. */
- if (!priv->use_24_hour_format && buffer[0] == '0')
- buffer[0] = ' ';
-
- gtk_entry_set_text (GTK_ENTRY (child), buffer);
-
- /* truncate left spaces */
- b = buffer;
- while (*b == ' ')
- b++;
-
- model = gtk_combo_box_get_model (combo_box);
- valid = gtk_tree_model_get_iter_first (model, &iter);
-
- while (valid) {
- gchar *text = NULL;
-
- gtk_tree_model_get (model, &iter, 0, &text, -1);
- if (text) {
- gchar *t = text;
-
- /* truncate left spaces */
- while (*t == ' ')
- t++;
-
- if (strcmp (b, t) == 0) {
- gtk_combo_box_set_active_iter (
- combo_box, &iter);
- g_free (text);
- break;
- }
- }
-
- g_free (text);
-
- valid = gtk_tree_model_iter_next (model, &iter);
- }
- }
-
- add_relation (dedit, priv->time_combo);
-}
-
-static void
-e_date_edit_update_time_combo_state (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- gboolean show = TRUE, show_now_button = TRUE;
- gboolean clear_entry = FALSE, sensitive = TRUE;
- const gchar *text;
-
- priv = dedit->priv;
-
- /* If the date entry is currently shown, and it is set to None,
- * clear the time entry and disable the time combo. */
- if (priv->show_date && priv->date_set_to_none) {
- clear_entry = TRUE;
- sensitive = FALSE;
- }
-
- if (!priv->show_time) {
- if (priv->make_time_insensitive) {
- clear_entry = TRUE;
- sensitive = FALSE;
- } else {
- show = FALSE;
- }
-
- show_now_button = FALSE;
- }
-
- if (clear_entry) {
- GtkWidget *child;
-
- /* Only clear it if it isn't empty already. */
- child = gtk_bin_get_child (GTK_BIN (priv->time_combo));
- text = gtk_entry_get_text (GTK_ENTRY (child));
- if (text[0])
- gtk_entry_set_text (GTK_ENTRY (child), "");
- }
-
- gtk_widget_set_sensitive (priv->time_combo, sensitive);
-
- if (show)
- gtk_widget_show (priv->time_combo);
- else
- gtk_widget_hide (priv->time_combo);
-
- if (show_now_button)
- gtk_widget_show (priv->now_button);
- else
- gtk_widget_hide (priv->now_button);
-
- if (priv->show_date
- && (priv->show_time || priv->make_time_insensitive))
- gtk_widget_show (priv->space);
- else
- gtk_widget_hide (priv->space);
-}
-
-/* Parses the date, and if it is different from the current settings it
- * updates the settings and emits a "date_changed" signal. */
-static void
-e_date_edit_check_date_changed (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- const gchar *date_text;
- struct tm tmp_tm;
- gboolean none = FALSE, valid = TRUE, date_changed = FALSE;
-
- priv = dedit->priv;
-
- tmp_tm.tm_year = 0;
- tmp_tm.tm_mon = 0;
- tmp_tm.tm_mday = 0;
-
- date_text = gtk_entry_get_text (GTK_ENTRY (priv->date_entry));
- if (field_set_to_none (date_text)) {
- none = TRUE;
- } else if (!e_date_edit_parse_date (dedit, date_text, &tmp_tm)) {
- valid = FALSE;
- tmp_tm.tm_year = 0;
- tmp_tm.tm_mon = 0;
- tmp_tm.tm_mday = 0;
- }
-
- date_changed = e_date_edit_set_date_internal (
- dedit, valid, none,
- tmp_tm.tm_year,
- tmp_tm.tm_mon,
- tmp_tm.tm_mday);
-
- if (date_changed) {
- priv->has_been_changed = TRUE;
- g_signal_emit (dedit, signals[CHANGED], 0);
- }
-}
-
-/* Parses the time, and if it is different from the current settings it
- * updates the settings and emits a "time_changed" signal. */
-static void
-e_date_edit_check_time_changed (EDateEdit *dedit)
-{
- EDateEditPrivate *priv;
- GtkWidget *child;
- const gchar *time_text;
- struct tm tmp_tm;
- gboolean none = FALSE, valid = TRUE, time_changed;
-
- priv = dedit->priv;
-
- tmp_tm.tm_hour = 0;
- tmp_tm.tm_min = 0;
-
- child = gtk_bin_get_child (GTK_BIN (priv->time_combo));
- time_text = gtk_entry_get_text (GTK_ENTRY (child));
- if (field_set_to_none (time_text))
- none = TRUE;
- else if (!e_date_edit_parse_time (dedit, time_text, &tmp_tm))
- valid = FALSE;
-
- time_changed = e_date_edit_set_time_internal (
- dedit, valid, none,
- tmp_tm.tm_hour,
- tmp_tm.tm_min);
-
- if (time_changed) {
- e_date_edit_update_time_entry (dedit);
- g_signal_emit (dedit, signals[CHANGED], 0);
- }
-}
-
-/**
- * e_date_edit_date_is_valid:
- * @dedit: an #EDateEdit widget.
- * @Returns: TRUE if the last date entered was valid.
- *
- * Returns TRUE if the last date entered was valid.
- *
- * Note that if this returns FALSE, you can still use e_date_edit_get_time()
- * or e_date_edit_get_date() to get the last time or date entered which was
- * valid.
- */
-gboolean
-e_date_edit_date_is_valid (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- if (!dedit->priv->date_is_valid)
- return FALSE;
-
- /* If the date is empty/None and that isn't permitted, return FALSE. */
- if (dedit->priv->date_set_to_none
- && !e_date_edit_get_allow_no_date_set (dedit))
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * e_date_edit_time_is_valid:
- * @dedit: an #EDateEdit widget.
- * @Returns: TRUE if the last time entered was valid.
- *
- * Returns TRUE if the last time entered was valid.
- *
- * Note that if this returns FALSE, you can still use e_date_edit_get_time()
- * or e_date_edit_get_time_of_day() to get the last time or time of the day
- * entered which was valid.
- */
-gboolean
-e_date_edit_time_is_valid (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- if (!dedit->priv->time_is_valid)
- return FALSE;
-
- /* If the time is empty and that isn't permitted, return FALSE.
- * Note that we don't mind an empty time if the date field is shown
- * - in that case we just assume 0:00. */
- if (dedit->priv->time_set_to_none && !dedit->priv->show_date
- && !e_date_edit_get_allow_no_date_set (dedit))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-e_date_edit_set_date_internal (EDateEdit *dedit,
- gboolean valid,
- gboolean none,
- gint year,
- gint month,
- gint day)
-{
- EDateEditPrivate *priv;
- gboolean date_changed = FALSE;
-
- priv = dedit->priv;
-
- if (!valid) {
- /* Date is invalid. */
- if (priv->date_is_valid) {
- priv->date_is_valid = FALSE;
- date_changed = TRUE;
- }
- } else if (none) {
- /* Date has been set to 'None'. */
- if (!priv->date_is_valid
- || !priv->date_set_to_none) {
- priv->date_is_valid = TRUE;
- priv->date_set_to_none = TRUE;
- date_changed = TRUE;
- }
- } else {
- /* Date has been set to a specific date. */
- if (!priv->date_is_valid
- || priv->date_set_to_none
- || priv->year != year
- || priv->month != month
- || priv->day != day) {
- priv->date_is_valid = TRUE;
- priv->date_set_to_none = FALSE;
- priv->year = year;
- priv->month = month;
- priv->day = day;
- date_changed = TRUE;
- }
- }
-
- return date_changed;
-}
-
-static gboolean
-e_date_edit_set_time_internal (EDateEdit *dedit,
- gboolean valid,
- gboolean none,
- gint hour,
- gint minute)
-{
- EDateEditPrivate *priv;
- gboolean time_changed = FALSE;
-
- priv = dedit->priv;
-
- if (!valid) {
- /* Time is invalid. */
- if (priv->time_is_valid) {
- priv->time_is_valid = FALSE;
- time_changed = TRUE;
- }
- } else if (none) {
- /* Time has been set to empty/'None'. */
- if (!priv->time_is_valid
- || !priv->time_set_to_none) {
- priv->time_is_valid = TRUE;
- priv->time_set_to_none = TRUE;
- time_changed = TRUE;
- }
- } else {
- /* Time has been set to a specific time. */
- if (!priv->time_is_valid
- || priv->time_set_to_none
- || priv->hour != hour
- || priv->minute != minute) {
- priv->time_is_valid = TRUE;
- priv->time_set_to_none = FALSE;
- priv->hour = hour;
- priv->minute = minute;
- time_changed = TRUE;
- }
- }
-
- return time_changed;
-}
-
-gboolean
-e_date_edit_get_twodigit_year_can_future (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), FALSE);
-
- return dedit->priv->twodigit_year_can_future;
-}
-
-void
-e_date_edit_set_twodigit_year_can_future (EDateEdit *dedit,
- gboolean value)
-{
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- dedit->priv->twodigit_year_can_future = value;
-}
-
-/* Sets a callback to use to get the current time. This is useful if the
- * application needs to use its own timezone data rather than rely on the
- * Unix timezone. */
-void
-e_date_edit_set_get_time_callback (EDateEdit *dedit,
- EDateEditGetTimeCallback cb,
- gpointer data,
- GDestroyNotify destroy)
-{
- EDateEditPrivate *priv;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- priv = dedit->priv;
-
- if (priv->time_callback_data && priv->time_callback_destroy)
- (*priv->time_callback_destroy) (priv->time_callback_data);
-
- priv->time_callback = cb;
- priv->time_callback_data = data;
- priv->time_callback_destroy = destroy;
-
-}
-
-GtkWidget *
-e_date_edit_get_entry (EDateEdit *dedit)
-{
- g_return_val_if_fail (E_IS_DATE_EDIT (dedit), NULL);
-
- return GTK_WIDGET (dedit->priv->date_entry);
-}