aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc
diff options
context:
space:
mode:
Diffstat (limited to 'widgets/misc')
-rw-r--r--widgets/misc/ChangeLog4
-rw-r--r--widgets/misc/e-cell-date-edit.c587
-rw-r--r--widgets/misc/e-cell-date-edit.h22
3 files changed, 537 insertions, 76 deletions
diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog
index 8d4c3917c6..6f104db461 100644
--- a/widgets/misc/ChangeLog
+++ b/widgets/misc/ChangeLog
@@ -1,3 +1,7 @@
+2001-03-04 Damon Chaplin <damon@ximian.com>
+
+ * e-cell-date-edit.c: pretty much working now.
+
2001-03-01 Not Zed <NotZed@Ximian.com>
* e-filter-bar.c: New type of search bar that interacts with
diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/misc/e-cell-date-edit.c
index 3318590baf..366ce74b7a 100644
--- a/widgets/misc/e-cell-date-edit.c
+++ b/widgets/misc/e-cell-date-edit.c
@@ -32,6 +32,7 @@
#include <gdk/gdkkeysyms.h>
#include "gal/util/e-util.h"
#include <gal/e-table/e-table-item.h>
+#include <e-util/e-time-utils.h>
#include "e-cell-date-edit.h"
/* This depends on ECalendar which is why I didn't put it in gal. */
@@ -40,9 +41,18 @@
static void e_cell_date_edit_class_init (GtkObjectClass *object_class);
static void e_cell_date_edit_init (ECellDateEdit *ecde);
static void e_cell_date_edit_destroy (GtkObject *object);
+static void e_cell_date_edit_get_arg (GtkObject *o,
+ GtkArg *arg,
+ guint arg_id);
+static void e_cell_date_edit_set_arg (GtkObject *o,
+ GtkArg *arg,
+ guint arg_id);
static gint e_cell_date_edit_do_popup (ECellPopup *ecp,
GdkEvent *event);
+static void e_cell_date_edit_set_popup_values (ECellDateEdit *ecde);
+static void e_cell_date_edit_select_matching_time(ECellDateEdit *ecde,
+ char *time);
static void e_cell_date_edit_show_popup (ECellDateEdit *ecde);
static void e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde,
gint *x,
@@ -55,6 +65,32 @@ static void e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde);
static int e_cell_date_edit_key_press (GtkWidget *popup_window,
GdkEventKey *event,
ECellDateEdit *ecde);
+static void e_cell_date_edit_on_ok_clicked (GtkWidget *button,
+ ECellDateEdit *ecde);
+static void e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde);
+static void e_cell_date_edit_on_now_clicked (GtkWidget *button,
+ ECellDateEdit *ecde);
+static void e_cell_date_edit_on_none_clicked (GtkWidget *button,
+ ECellDateEdit *ecde);
+static void e_cell_date_edit_on_today_clicked (GtkWidget *button,
+ ECellDateEdit *ecde);
+static void e_cell_date_edit_update_cell (ECellDateEdit *ecde,
+ char *text);
+static void e_cell_date_edit_on_time_selected (GtkList *list,
+ ECellDateEdit *ecde);
+static void e_cell_date_edit_hide_popup (ECellDateEdit *ecde);
+
+/* Our arguments. */
+enum {
+ ARG_0,
+ ARG_SHOW_TIME,
+ ARG_SHOW_NOW_BUTTON,
+ ARG_SHOW_TODAY_BUTTON,
+ ARG_ALLOW_NO_DATE_SET,
+ ARG_USE_24_HOUR_FORMAT,
+ ARG_LOWER_HOUR,
+ ARG_UPPER_HOUR
+};
static ECellPopupClass *parent_class;
@@ -69,7 +105,31 @@ e_cell_date_edit_class_init (GtkObjectClass *object_class)
{
ECellPopupClass *ecpc = (ECellPopupClass *) object_class;
+ gtk_object_add_arg_type ("ECellDateEdit::show_time",
+ GTK_TYPE_BOOL, GTK_ARG_READWRITE,
+ ARG_SHOW_TIME);
+ gtk_object_add_arg_type ("ECellDateEdit::show_now_button",
+ GTK_TYPE_BOOL, GTK_ARG_READWRITE,
+ ARG_SHOW_NOW_BUTTON);
+ gtk_object_add_arg_type ("ECellDateEdit::show_today_button",
+ GTK_TYPE_BOOL, GTK_ARG_READWRITE,
+ ARG_SHOW_TODAY_BUTTON);
+ gtk_object_add_arg_type ("ECellDateEdit::allow_no_date_set",
+ GTK_TYPE_BOOL, GTK_ARG_READWRITE,
+ ARG_ALLOW_NO_DATE_SET);
+ gtk_object_add_arg_type ("ECellDateEdit::use_24_hour_format",
+ GTK_TYPE_BOOL, GTK_ARG_READWRITE,
+ ARG_USE_24_HOUR_FORMAT);
+ gtk_object_add_arg_type ("ECellDateEdit::lower_hour",
+ GTK_TYPE_INT, GTK_ARG_READWRITE,
+ ARG_LOWER_HOUR);
+ gtk_object_add_arg_type ("ECellDateEdit::upper_hour",
+ GTK_TYPE_INT, GTK_ARG_READWRITE,
+ ARG_UPPER_HOUR);
+
object_class->destroy = e_cell_date_edit_destroy;
+ object_class->get_arg = e_cell_date_edit_get_arg;
+ object_class->set_arg = e_cell_date_edit_set_arg;
ecpc->popup = e_cell_date_edit_do_popup;
@@ -80,14 +140,15 @@ e_cell_date_edit_class_init (GtkObjectClass *object_class)
static void
e_cell_date_edit_init (ECellDateEdit *ecde)
{
- GtkWidget *frame, *vbox, *table, *label, *entry;
- GtkWidget *calendar, *scrolled_window, *list, *bbox;
- GtkWidget *now_button, *today_button, *none_button;
-
- ecde->use_24_hour_format = TRUE;
+ GtkWidget *frame, *vbox, *hbox, *vbox2;
+ GtkWidget *scrolled_window, *list, *bbox;
+ GtkWidget *now_button, *today_button, *none_button, *ok_button;
ecde->lower_hour = 0;
ecde->upper_hour = 24;
+ ecde->use_24_hour_format = TRUE;
+ ecde->need_time_list_rebuild = TRUE;
+ ecde->freeze_count = 0;
/* We create one popup window for the ECell, since there will only
ever be one popup in use at a time. */
@@ -105,49 +166,29 @@ e_cell_date_edit_init (ECellDateEdit *ecde)
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
- table = gtk_table_new (3, 2, FALSE);
- gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
- gtk_table_set_col_spacings (GTK_TABLE (table), 4);
- gtk_widget_show (table);
-
-#if 0
- label = gtk_label_new (_("Date:"));
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
- GTK_FILL, 0, 0, 0);
- gtk_widget_show (label);
-
- entry = gtk_entry_new ();
- gtk_table_attach (GTK_TABLE (table), entry, 0, 1, 1, 2,
- GTK_FILL, 0, 0, 0);
- gtk_widget_show (entry);
-#endif
+ hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ gtk_widget_show (hbox);
- calendar = e_calendar_new ();
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (calendar)->calitem),
+ ecde->calendar = e_calendar_new ();
+ gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (ecde->calendar)->calitem),
"move_selection_when_moving", FALSE,
NULL);
- gtk_table_attach (GTK_TABLE (table), calendar, 0, 1, 0, 3,
- GTK_FILL, GTK_FILL, 0, 0);
- gtk_widget_show (calendar);
+ gtk_box_pack_start (GTK_BOX (hbox), ecde->calendar, TRUE, TRUE, 0);
+ gtk_widget_show (ecde->calendar);
+ vbox2 = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
+ gtk_widget_show (vbox2);
-#if 0
- label = gtk_label_new (_("Time:"));
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
- gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
- GTK_FILL, 0, 0, 0);
- gtk_widget_show (label);
-
- entry = gtk_entry_new ();
- gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
- GTK_FILL, 0, 0, 0);
- gtk_widget_show (entry);
-#endif
+ ecde->time_entry = gtk_entry_new ();
+ gtk_widget_set_usize (ecde->time_entry, 50, -1);
+ gtk_box_pack_start (GTK_BOX (vbox2), ecde->time_entry,
+ FALSE, FALSE, 0);
+ gtk_widget_show (ecde->time_entry);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_table_attach (GTK_TABLE (table), scrolled_window, 1, 2, 0, 3,
- GTK_FILL, GTK_FILL, 0, 0);
+ gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_NEVER,
GTK_POLICY_ALWAYS);
@@ -159,7 +200,9 @@ e_cell_date_edit_init (ECellDateEdit *ecde)
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
gtk_widget_show (list);
ecde->time_list = list;
- e_cell_date_edit_rebuild_time_list (ecde);
+ gtk_signal_connect (GTK_OBJECT (list), "selection-changed",
+ GTK_SIGNAL_FUNC (e_cell_date_edit_on_time_selected),
+ ecde);
bbox = gtk_hbutton_box_new ();
gtk_container_set_border_width (GTK_CONTAINER (bbox), 4);
@@ -172,28 +215,33 @@ e_cell_date_edit_init (ECellDateEdit *ecde)
now_button = gtk_button_new_with_label (_("Now"));
gtk_container_add (GTK_CONTAINER (bbox), now_button);
gtk_widget_show (now_button);
-#if 0
gtk_signal_connect (GTK_OBJECT (now_button), "clicked",
- GTK_SIGNAL_FUNC (on_date_popup_now_button_clicked), dedit);
-#endif
+ GTK_SIGNAL_FUNC (e_cell_date_edit_on_now_clicked),
+ ecde);
+ ecde->now_button = now_button;
today_button = gtk_button_new_with_label (_("Today"));
gtk_container_add (GTK_CONTAINER (bbox), today_button);
gtk_widget_show (today_button);
-#if 0
gtk_signal_connect (GTK_OBJECT (today_button), "clicked",
- GTK_SIGNAL_FUNC (on_date_popup_today_button_clicked), dedit);
-#endif
+ GTK_SIGNAL_FUNC (e_cell_date_edit_on_today_clicked),
+ ecde);
+ ecde->today_button = today_button;
- /* Note that we don't show this here, since by default a 'None' date
- is not permitted. */
none_button = gtk_button_new_with_label (_("None"));
gtk_container_add (GTK_CONTAINER (bbox), none_button);
-#if 0
+ gtk_widget_show (none_button);
gtk_signal_connect (GTK_OBJECT (none_button), "clicked",
- GTK_SIGNAL_FUNC (on_date_popup_none_button_clicked), dedit);
-#endif
+ GTK_SIGNAL_FUNC (e_cell_date_edit_on_none_clicked),
+ ecde);
+ ecde->none_button = none_button;
+ ok_button = gtk_button_new_with_label (_("OK"));
+ gtk_container_add (GTK_CONTAINER (bbox), ok_button);
+ gtk_widget_show (ok_button);
+ gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
+ GTK_SIGNAL_FUNC (e_cell_date_edit_on_ok_clicked),
+ ecde);
gtk_signal_connect (GTK_OBJECT (ecde->popup_window),
@@ -233,15 +281,133 @@ e_cell_date_edit_destroy (GtkObject *object)
}
+static void
+e_cell_date_edit_get_arg (GtkObject *o,
+ GtkArg *arg,
+ guint arg_id)
+{
+ ECellDateEdit *ecde;
+
+ ecde = E_CELL_DATE_EDIT (o);
+
+ switch (arg_id) {
+ case ARG_SHOW_TIME:
+ GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->time_entry) ? TRUE : FALSE;
+ break;
+ case ARG_SHOW_NOW_BUTTON:
+ GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->now_button) ? TRUE : FALSE;
+ break;
+ case ARG_SHOW_TODAY_BUTTON:
+ GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->today_button) ? TRUE : FALSE;
+ break;
+ case ARG_ALLOW_NO_DATE_SET:
+ GTK_VALUE_BOOL (*arg) = GTK_WIDGET_VISIBLE (ecde->none_button) ? TRUE : FALSE;
+ break;
+ case ARG_USE_24_HOUR_FORMAT:
+ GTK_VALUE_BOOL (*arg) = ecde->use_24_hour_format;
+ break;
+ case ARG_LOWER_HOUR:
+ GTK_VALUE_INT (*arg) = ecde->lower_hour;
+ break;
+ case ARG_UPPER_HOUR:
+ GTK_VALUE_INT (*arg) = ecde->upper_hour;
+ break;
+ default:
+ g_warning ("Invalid arg");
+ }
+}
+
+
+static void
+e_cell_date_edit_set_arg (GtkObject *o,
+ GtkArg *arg,
+ guint arg_id)
+{
+ ECellDateEdit *ecde;
+ gint ivalue;
+ gboolean bvalue;
+
+ ecde = E_CELL_DATE_EDIT (o);
+
+ switch (arg_id){
+ case ARG_SHOW_TIME:
+ bvalue = GTK_VALUE_BOOL (*arg);
+ if (bvalue) {
+ gtk_widget_show (ecde->time_entry);
+ gtk_widget_show (ecde->time_list);
+ } else {
+ gtk_widget_hide (ecde->time_entry);
+ gtk_widget_hide (ecde->time_list);
+ }
+ break;
+ case ARG_SHOW_NOW_BUTTON:
+ bvalue = GTK_VALUE_BOOL (*arg);
+ if (bvalue) {
+ gtk_widget_show (ecde->now_button);
+ } else {
+ gtk_widget_hide (ecde->now_button);
+ }
+ break;
+ case ARG_SHOW_TODAY_BUTTON:
+ bvalue = GTK_VALUE_BOOL (*arg);
+ if (bvalue) {
+ gtk_widget_show (ecde->today_button);
+ } else {
+ gtk_widget_hide (ecde->today_button);
+ }
+ break;
+ case ARG_ALLOW_NO_DATE_SET:
+ bvalue = GTK_VALUE_BOOL (*arg);
+ if (bvalue) {
+ gtk_widget_show (ecde->none_button);
+ } else {
+ /* FIXME: What if we have no date set now. */
+ gtk_widget_hide (ecde->none_button);
+ }
+ break;
+ case ARG_USE_24_HOUR_FORMAT:
+ bvalue = GTK_VALUE_BOOL (*arg);
+ if (ecde->use_24_hour_format != bvalue) {
+ ecde->use_24_hour_format = bvalue;
+ ecde->need_time_list_rebuild = TRUE;
+ }
+ break;
+ case ARG_LOWER_HOUR:
+ ivalue = GTK_VALUE_INT (*arg);
+ ivalue = CLAMP (ivalue, 0, 24);
+ if (ecde->lower_hour != ivalue) {
+ ecde->lower_hour = ivalue;
+ ecde->need_time_list_rebuild = TRUE;
+ }
+ break;
+ case ARG_UPPER_HOUR:
+ ivalue = GTK_VALUE_INT (*arg);
+ ivalue = CLAMP (ivalue, 0, 24);
+ if (ecde->upper_hour != ivalue) {
+ ecde->upper_hour = ivalue;
+ ecde->need_time_list_rebuild = TRUE;
+ }
+ break;
+ default:
+ g_warning ("Invalid arg");
+ }
+
+#if 0
+ if (ecde->need_time_list_rebuild && ecde->freeze_count == 0)
+ e_cell_date_edit_rebuild_time_list (ecde);
+#endif
+}
+
+
static gint
e_cell_date_edit_do_popup (ECellPopup *ecp,
GdkEvent *event)
{
ECellDateEdit *ecde = E_CELL_DATE_EDIT (ecp);
guint32 time;
- gint error_code;
e_cell_date_edit_show_popup (ecde);
+ e_cell_date_edit_set_popup_values (ecde);
if (event->type == GDK_BUTTON_PRESS) {
time = event->button.time;
@@ -249,16 +415,6 @@ e_cell_date_edit_do_popup (ECellPopup *ecp,
time = event->key.time;
}
- error_code = gdk_pointer_grab (ecde->popup_window->window, TRUE,
- GDK_ENTER_NOTIFY_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_BUTTON1_MOTION_MASK,
- NULL, NULL, time);
- if (error_code != 0)
- g_warning ("Failed to get pointer grab");
-
gtk_grab_add (ecde->popup_window);
return TRUE;
@@ -266,11 +422,105 @@ e_cell_date_edit_do_popup (ECellPopup *ecp,
static void
+e_cell_date_edit_set_popup_values (ECellDateEdit *ecde)
+{
+ ECellPopup *ecp = E_CELL_POPUP (ecde);
+ ECellView *ecv = (ECellView*) ecp->popup_cell_view;
+ ETableItem *eti = E_TABLE_ITEM (ecp->popup_cell_view->cell_view.e_table_item_view);
+ ETableCol *ecol;
+ char *cell_text;
+ ETimeParseStatus status;
+ struct tm date_tm;
+ GDate date;
+ ECalendarItem *calitem;
+ static char buffer[64], *format;
+
+ ecol = e_table_header_get_column (eti->header, ecp->popup_view_col);
+ cell_text = e_table_model_value_at (ecv->e_table_model,
+ ecol->col_idx, ecp->popup_row);
+
+ status = e_time_parse_date_and_time (cell_text, &date_tm);
+
+ /* If there is no date and time set, or the date is invalid, we clear
+ the selections, else we select the appropriate date & time. */
+ calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem);
+ if (status == E_TIME_PARSE_NONE || status == E_TIME_PARSE_INVALID) {
+ gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), "");
+ e_calendar_item_set_selection (calitem, NULL, NULL);
+ gtk_list_unselect_all (GTK_LIST (ecde->time_list));
+ } else {
+ if (ecde->use_24_hour_format) {
+ if (date_tm.tm_sec == 0)
+ /* strftime format of a time in 24-hour format,
+ without seconds. */
+ format = _("%H:%M");
+ else
+ /* strftime format of a time in 24-hour format.
+ */
+ format = _("%H:%M:%S");
+ } else {
+ if (date_tm.tm_sec == 0)
+ /* strftime format of a time in 12-hour format,
+ without seconds. */
+ format = _("%I:%M %p");
+ else
+ /* strftime format of a time in 12-hour format.
+ */
+ format = _("%I:%M:%S %p");
+ }
+
+ strftime (buffer, sizeof (buffer), format, &date_tm);
+
+ gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), buffer);
+
+ g_date_clear (&date, 1);
+ g_date_set_dmy (&date, date_tm.tm_mday, date_tm.tm_mon + 1,
+ date_tm.tm_year + 1900);
+ e_calendar_item_set_selection (calitem, &date, &date);
+
+ e_cell_date_edit_select_matching_time (ecde, buffer);
+ }
+}
+
+
+static void
+e_cell_date_edit_select_matching_time (ECellDateEdit *ecde,
+ char *time)
+{
+ GtkList *list;
+ GtkWidget *listitem, *label;
+ GList *elem;
+ gboolean found = FALSE;
+ char *list_item_text;
+
+ list = GTK_LIST (ecde->time_list);
+ elem = list->children;
+ while (elem) {
+ listitem = GTK_WIDGET (elem->data);
+ label = GTK_BIN (listitem)->child;
+ gtk_label_get (GTK_LABEL (label), &list_item_text);
+
+ if (!strcmp (list_item_text, time)) {
+ found = TRUE;
+ gtk_list_select_child (list, listitem);
+ break;
+ }
+
+ elem = elem->next;
+ }
+
+ if (!found)
+ gtk_list_unselect_all (list);
+}
+
+
+static void
e_cell_date_edit_show_popup (ECellDateEdit *ecde)
{
gint x, y, width, height, old_width, old_height;
- g_print ("In e_cell_popup_popup_list\n");
+ if (ecde->need_time_list_rebuild)
+ e_cell_date_edit_rebuild_time_list (ecde);
/* This code is practically copied from GtkCombo. */
old_width = ecde->popup_window->allocation.width;
@@ -284,8 +534,8 @@ e_cell_date_edit_show_popup (ECellDateEdit *ecde)
gdk_window_resize (ecde->popup_window->window, width, height);
gtk_widget_show (ecde->popup_window);
- /* FIXME: Set the focus to the first widget. */
- gtk_widget_grab_focus (ecde->popup_window);
+ /* Set the focus to the first widget. */
+ gtk_widget_grab_focus (ecde->time_entry);
E_CELL_POPUP (ecde)->popup_shown = TRUE;
}
@@ -309,11 +559,11 @@ e_cell_date_edit_get_popup_pos (ECellDateEdit *ecde,
gdk_window_get_origin (canvas->window, x, y);
x1 = e_table_header_col_diff (eti->header, 0, eti->editing_col + 1);
- y1 = eti_row_diff (eti, 0, eti->editing_row + 1);
+ y1 = e_table_item_row_diff (eti, 0, eti->editing_row + 1);
column_width = e_table_header_col_diff (eti->header, eti->editing_col,
eti->editing_col + 1);
- row_height = eti_row_diff (eti, eti->editing_row,
- eti->editing_row + 1);
+ row_height = e_table_item_row_diff (eti, eti->editing_row,
+ eti->editing_row + 1);
gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (eti), &x1, &y1);
*x += x1;
@@ -375,11 +625,7 @@ e_cell_date_edit_key_press (GtkWidget *popup_window,
if (event->keyval != GDK_Escape)
return FALSE;
- gtk_grab_remove (ecde->popup_window);
- gdk_pointer_ungrab (event->time);
- gtk_widget_hide (ecde->popup_window);
-
- E_CELL_POPUP (ecde)->popup_shown = FALSE;
+ e_cell_date_edit_hide_popup (ecde);
return TRUE;
}
@@ -435,6 +681,197 @@ e_cell_date_edit_rebuild_time_list (ECellDateEdit *ecde)
gtk_container_add (GTK_CONTAINER (list), listitem);
}
}
+
+ ecde->need_time_list_rebuild = FALSE;
+}
+
+
+static void
+e_cell_date_edit_on_ok_clicked (GtkWidget *button,
+ ECellDateEdit *ecde)
+{
+ ECalendarItem *calitem;
+ GDate start_date, end_date;
+ gboolean day_selected;
+ struct tm date_tm;
+ char buffer[64], *text;
+ ETimeParseStatus status;
+
+ calitem = E_CALENDAR_ITEM (E_CALENDAR (ecde->calendar)->calitem);
+ day_selected = e_calendar_item_get_selection (calitem, &start_date,
+ &end_date);
+
+ text = gtk_entry_get_text (GTK_ENTRY (ecde->time_entry));
+ status = e_time_parse_time (text, &date_tm);
+ if (status == E_TIME_PARSE_INVALID) {
+ e_cell_date_edit_show_time_invalid_warning (ecde);
+ return;
+ }
+
+ if (day_selected) {
+ date_tm.tm_year = g_date_year (&start_date) - 1900;
+ date_tm.tm_mon = g_date_month (&start_date) - 1;
+ date_tm.tm_mday = g_date_day (&start_date);
+ /* We need to call this to set the weekday. */
+ mktime (&date_tm);
+ e_time_format_date_and_time (&date_tm,
+ ecde->use_24_hour_format,
+ TRUE, FALSE,
+ buffer, sizeof (buffer));
+ } else {
+ buffer[0] = '\0';
+ }
+
+ e_cell_date_edit_update_cell (ecde, buffer);
+ e_cell_date_edit_hide_popup (ecde);
+}
+
+
+static void
+e_cell_date_edit_show_time_invalid_warning (ECellDateEdit *ecde)
+{
+ GtkWidget *dialog;
+
+ /* FIXME: Better message needed. */
+ dialog = gnome_message_box_new (_("The time is invalid"),
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_widget_show (dialog);
+}
+
+
+static void
+e_cell_date_edit_on_now_clicked (GtkWidget *button,
+ ECellDateEdit *ecde)
+{
+ struct tm *tmp_tm;
+ time_t t;
+ char buffer[64];
+
+ g_print ("In e_cell_date_edit_on_now_clicked\n");
+
+ t = time (NULL);
+ tmp_tm = localtime (&t);
+ e_time_format_date_and_time (tmp_tm,
+ ecde->use_24_hour_format,
+ TRUE, FALSE,
+ buffer, sizeof (buffer));
+
+ e_cell_date_edit_update_cell (ecde, buffer);
+ e_cell_date_edit_hide_popup (ecde);
+}
+
+
+static void
+e_cell_date_edit_on_none_clicked (GtkWidget *button,
+ ECellDateEdit *ecde)
+{
+ g_print ("In e_cell_date_edit_on_none_clicked\n");
+
+ e_cell_date_edit_update_cell (ecde, "");
+ e_cell_date_edit_hide_popup (ecde);
+}
+
+
+static void
+e_cell_date_edit_on_today_clicked (GtkWidget *button,
+ ECellDateEdit *ecde)
+{
+ struct tm *tmp_tm;
+ time_t t;
+ char buffer[64];
+
+ g_print ("In e_cell_date_edit_on_today_clicked\n");
+
+ t = time (NULL);
+ tmp_tm = localtime (&t);
+ tmp_tm->tm_hour = 0;
+ tmp_tm->tm_min = 0;
+ tmp_tm->tm_sec = 0;
+ e_time_format_date_and_time (tmp_tm,
+ ecde->use_24_hour_format,
+ FALSE, FALSE,
+ buffer, sizeof (buffer));
+
+ e_cell_date_edit_update_cell (ecde, buffer);
+ e_cell_date_edit_hide_popup (ecde);
+}
+
+
+static void
+e_cell_date_edit_update_cell (ECellDateEdit *ecde,
+ char *text)
+{
+ ECellPopup *ecp = E_CELL_POPUP (ecde);
+ ECellView *ecv = (ECellView*) ecp->popup_cell_view;
+ ETableItem *eti = E_TABLE_ITEM (ecv->e_table_item_view);
+ ETableCol *ecol;
+ gchar *old_text;
+
+ /* Compare the new text with the existing cell contents. */
+ ecol = e_table_header_get_column (eti->header, ecp->popup_view_col);
+ old_text = e_table_model_value_at (ecv->e_table_model,
+ ecol->col_idx, ecp->popup_row);
+
+ /* If they are different, update the cell contents. */
+ if (strcmp (old_text, text)) {
+ e_table_model_set_value_at (ecv->e_table_model,
+ ecol->col_idx, ecp->popup_row,
+ text);
+ }
+}
+
+
+static void
+e_cell_date_edit_on_time_selected (GtkList *list,
+ ECellDateEdit *ecde)
+{
+ GtkWidget *listitem, *label;
+ char *list_item_text;
+
+ g_print ("In e_cell_date_edit_on_time_selected\n");
+
+ if (!list->selection)
+ return;
+
+ listitem = list->selection->data;
+ label = GTK_BIN (listitem)->child;
+ gtk_label_get (GTK_LABEL (label), &list_item_text);
+ gtk_entry_set_text (GTK_ENTRY (ecde->time_entry), list_item_text);
}
+static void
+e_cell_date_edit_hide_popup (ECellDateEdit *ecde)
+{
+ gtk_grab_remove (ecde->popup_window);
+ gtk_widget_hide (ecde->popup_window);
+ E_CELL_POPUP (ecde)->popup_shown = FALSE;
+}
+
+
+/* These freeze and thaw the rebuilding of the time list. They are useful when
+ setting several properties which result in rebuilds of the list, e.g. the
+ lower_hour, upper_hour and use_24_hour_format properties. */
+void
+e_cell_date_edit_freeze (ECellDateEdit *ecde)
+{
+ g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde));
+
+ ecde->freeze_count++;
+}
+
+
+void
+e_cell_date_edit_thaw (ECellDateEdit *ecde)
+{
+ g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde));
+
+ if (ecde->freeze_count > 0) {
+ ecde->freeze_count--;
+
+ if (ecde->freeze_count == 0)
+ e_cell_date_edit_rebuild_time_list (ecde);
+ }
+}
+
diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/misc/e-cell-date-edit.h
index a852b95361..f3f8beb02b 100644
--- a/widgets/misc/e-cell-date-edit.h
+++ b/widgets/misc/e-cell-date-edit.h
@@ -43,13 +43,27 @@ typedef struct {
ECellPopup parent;
GtkWidget *popup_window;
+ GtkWidget *calendar;
+ GtkWidget *time_entry;
GtkWidget *time_list;
- /* This is the range of hours we show in the time popup. */
+ GtkWidget *now_button;
+ GtkWidget *today_button;
+ GtkWidget *none_button;
+
+ /* This is the range of hours we show in the time list. */
gint lower_hour;
gint upper_hour;
+ /* TRUE if we use 24-hour format for the time list and entry. */
gboolean use_24_hour_format;
+
+ /* This is TRUE if we need to rebuild the list of times. */
+ gboolean need_time_list_rebuild;
+
+ /* The freeze count for rebuilding the time list. We only rebuild when
+ this is 0. */
+ gint freeze_count;
} ECellDateEdit;
typedef struct {
@@ -61,4 +75,10 @@ GtkType e_cell_date_edit_get_type (void);
ECell *e_cell_date_edit_new (void);
+/* These freeze and thaw the rebuilding of the time list. They are useful when
+ setting several properties which result in rebuilds of the list, e.g. the
+ lower_hour, upper_hour and use_24_hour_format properties. */
+void e_cell_date_edit_freeze (ECellDateEdit *ecde);
+void e_cell_date_edit_thaw (ECellDateEdit *ecde);
+
#endif /* _E_CELL_DATE_EDIT_H_ */