diff options
author | Federico Mena Quintero <federico@helixcode.com> | 2000-06-01 08:48:01 +0800 |
---|---|---|
committer | Federico Mena Quintero <federico@src.gnome.org> | 2000-06-01 08:48:01 +0800 |
commit | 19150e7c7b614544188f93dbffd748a2846d2a1b (patch) | |
tree | 038bed0dd7a7d6921d19cc0a992910ea5c1144fa | |
parent | ebdac7989a6fcb20ddd3ecf7b875d7c16b75cabb (diff) | |
download | gsoc2013-evolution-19150e7c7b614544188f93dbffd748a2846d2a1b.tar.gz gsoc2013-evolution-19150e7c7b614544188f93dbffd748a2846d2a1b.tar.zst gsoc2013-evolution-19150e7c7b614544188f93dbffd748a2846d2a1b.zip |
Added a hash table to map calendar objects to their respective event
2000-05-31 Federico Mena Quintero <federico@helixcode.com>
* gui/gnome-cal.h (GnomeCalendar): Added a hash table to map
calendar objects to their respective event editors.
* gui/gnome-cal.c (gnome_calendar_init): Create the
object_editor_hash.
(gnome_calendar_destroy): Free the object_editor_hash.
(gnome_calendar_edit_object): New function to centralize the
launching of event editors; if one already exists for a particular
calendar object, we just raise its window.
(edit): Use gnome_calendar_edit_object().
* gui/calendar-commands.c (display_objedit): Use
gnome_calendar_edit_object().
(display_objedit_today): Likewise.
* gui/e-day-view.c (e_day_view_on_new_appointment): Likewise.
(e_day_view_on_edit_appointment): Likewise.
* gui/e-week-view.c (e_week_view_on_new_appointment): Likewise.
(e_week_view_on_edit_appointment): Likewise.
* gui/event-editor.c (event_editor_new): Do not take in an
iCalObject; rather provide an event_editor_set_ical_object()
function. We need this because a single editor may be switched
between different calendar objects. Also, do not show the event
editor; leave it up to the client code.
(event_editor_construct): Likewise.
(clear_widgets): New function to clear the widgets to default
values.
(fill_widgets): New function to fill in the widgets from the
iCalObject. We don't do this in init_widgets() anymore.
(free_exception_clist_data): New function to free the exceptions
clist data. We were leaking the row data.
(init_widgets): Hook to the destroy signal of the exceptions
clist.
(event_editor_set_ical_object): New function. Now it also makes a
copy of the calendar object for the event editor; clients do not
need to copy it anymore.
(event_editor_destroy): Unref the UI handler as well.
(event_editor_class_init): New "ical_object_released" signal to
notify the parent that we are no longer editing the calendar
object.
(make_title_from_ico): Handle NULL objects.
* gui/event-editor.h (EventEditor): Removed fields that are no
longer used.
svn path=/trunk/; revision=3317
-rw-r--r-- | calendar/ChangeLog | 49 | ||||
-rw-r--r-- | calendar/gui/calendar-commands.c | 37 | ||||
-rw-r--r-- | calendar/gui/control-factory.c | 1 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 62 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 15 | ||||
-rw-r--r-- | calendar/gui/event-editor.c | 373 | ||||
-rw-r--r-- | calendar/gui/event-editor.h | 23 | ||||
-rw-r--r-- | calendar/gui/eventedit.c | 1576 | ||||
-rw-r--r-- | calendar/gui/eventedit.h | 83 | ||||
-rw-r--r-- | calendar/gui/evolution-calendar-control.c | 1 | ||||
-rw-r--r-- | calendar/gui/gncal-todo.c | 2 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 89 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 22 | ||||
-rw-r--r-- | calendar/gui/main.c | 1 |
14 files changed, 504 insertions, 1830 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 6a913637af..d18ac9e750 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,52 @@ +2000-05-31 Federico Mena Quintero <federico@helixcode.com> + + * gui/gnome-cal.h (GnomeCalendar): Added a hash table to map + calendar objects to their respective event editors. + + * gui/gnome-cal.c (gnome_calendar_init): Create the + object_editor_hash. + (gnome_calendar_destroy): Free the object_editor_hash. + (gnome_calendar_edit_object): New function to centralize the + launching of event editors; if one already exists for a particular + calendar object, we just raise its window. + (edit): Use gnome_calendar_edit_object(). + + * gui/calendar-commands.c (display_objedit): Use + gnome_calendar_edit_object(). + (display_objedit_today): Likewise. + + * gui/e-day-view.c (e_day_view_on_new_appointment): Likewise. + (e_day_view_on_edit_appointment): Likewise. + + * gui/e-week-view.c (e_week_view_on_new_appointment): Likewise. + (e_week_view_on_edit_appointment): Likewise. + + * gui/event-editor.c (event_editor_new): Do not take in an + iCalObject; rather provide an event_editor_set_ical_object() + function. We need this because a single editor may be switched + between different calendar objects. Also, do not show the event + editor; leave it up to the client code. + (event_editor_construct): Likewise. + (clear_widgets): New function to clear the widgets to default + values. + (fill_widgets): New function to fill in the widgets from the + iCalObject. We don't do this in init_widgets() anymore. + (free_exception_clist_data): New function to free the exceptions + clist data. We were leaking the row data. + (init_widgets): Hook to the destroy signal of the exceptions + clist. + (event_editor_set_ical_object): New function. Now it also makes a + copy of the calendar object for the event editor; clients do not + need to copy it anymore. + (event_editor_destroy): Unref the UI handler as well. + (event_editor_class_init): New "ical_object_released" signal to + notify the parent that we are no longer editing the calendar + object. + (make_title_from_ico): Handle NULL objects. + + * gui/event-editor.h (EventEditor): Removed fields that are no + longer used. + 2000-05-31 Damon Chaplin <damon@helixcode.com> * cal-util/Makefile.am: added test-recur test program. diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c index 5726f45362..afc8580d09 100644 --- a/calendar/gui/calendar-commands.c +++ b/calendar/gui/calendar-commands.c @@ -20,7 +20,6 @@ #include <libgnorba/gnorba.h> #include <bonobo.h> #include <cal-util/timeutil.h> -#include "eventedit.h" #include "gnome-cal.h" #include "calendar-commands.h" @@ -185,28 +184,44 @@ about_calendar_cmd (BonoboUIHandler *uih, void *user_data, const char *path) static void display_objedit (BonoboUIHandler *uih, void *user_data, const char *path) { - GtkWidget *ee; + GnomeCalendar *gcal; iCalObject *ico; - GnomeCalendar *gcal = GNOME_CALENDAR (user_data); - ico = ical_new ("", user_name, ""); - ico->new = 1; + gcal = GNOME_CALENDAR (user_data); + ico = ical_new ("", user_name, ""); + ico->new = TRUE; gnome_calendar_get_current_time_range (gcal, &ico->dtstart, &ico->dtend); - ee = event_editor_new (gcal, ico); - gtk_widget_show (ee); + gnome_calendar_edit_object (gcal, ico); + ical_object_unref (ico); } static void display_objedit_today (BonoboUIHandler *uih, void *user_data, const char *path) { - GtkWidget *ee; - GnomeCalendar *gcal = GNOME_CALENDAR (user_data); + GnomeCalendar *gcal; + iCalObject *ico; + struct tm tm; + + gcal = GNOME_CALENDAR (user_data); + + ico = ical_new ("", user_name, ""); + ico->new = TRUE; + ico->dtstart = time (NULL); + + tm = *localtime (&ico->dtstart); + tm.tm_hour++; + ico->dtend = mktime (&tm); + if (ico->dtend == -1) { + g_message ("display_objedit_today(): mktime() generated -1 invalid time!"); + ical_object_unref (ico); + return; + } - ee = event_editor_new (gcal, NULL); - gtk_widget_show (ee); + gnome_calendar_edit_object (gcal, ico); + ical_object_unref (ico); } void diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c index a55d0dac79..bbfe796ce7 100644 --- a/calendar/gui/control-factory.c +++ b/calendar/gui/control-factory.c @@ -40,7 +40,6 @@ #include <cal-util/timeutil.h> #include <gui/alarm.h> -#include <gui/eventedit.h> #include <gui/gnome-cal.h> #include <gui/calendar-commands.h> diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 81bcf436bd..f80562fb12 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -1,13 +1,13 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : +/* + * Author : * Damon Chaplin <damon@helixcode.com> * * Copyright 1999, Helix Code, Inc. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as + * This program 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 2 of the * License, or (at your option) any later version. * @@ -38,7 +38,6 @@ #include "e-day-view-main-item.h" #include "calendar-commands.h" #include "popup-menu.h" -#include "eventedit.h" #include "../e-util/e-canvas.h" #include "../widgets/e-text/e-text.h" @@ -487,7 +486,7 @@ e_day_view_init (EDayView *day_view) if (!day_view->large_font) g_warning ("Couldn't load font"); - + /* Allocate the colors. */ #if 1 day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].red = 255 * 257; @@ -1944,7 +1943,7 @@ e_day_view_on_long_event_button_press (EDayView *day_view, return TRUE; } } else if (event->button == 3) { - e_day_view_on_event_right_click (day_view, event, + e_day_view_on_event_right_click (day_view, event, E_DAY_VIEW_LONG_EVENT, event_num); return TRUE; @@ -2228,7 +2227,7 @@ e_day_view_on_event_right_click (EDayView *day_view, EDayViewEvent *event; int have_selection, not_being_edited, items, i; struct menu_item *context_menu; - + static struct menu_item main_items[] = { { N_("New appointment..."), (GtkSignalFunc) e_day_view_on_new_appointment, NULL, TRUE } }; @@ -2288,7 +2287,7 @@ e_day_view_on_event_right_click (EDayView *day_view, for (i = 0; i < items; i++) context_menu[i].data = day_view; - + day_view->popup_event_day = day; day_view->popup_event_num = event_num; popup_menu (context_menu, items, bevent); @@ -2299,19 +2298,17 @@ static void e_day_view_on_new_appointment (GtkWidget *widget, gpointer data) { EDayView *day_view; - GtkWidget *event_editor; iCalObject *ico; - + day_view = E_DAY_VIEW (data); ico = ical_new ("", user_name, ""); ico->new = 1; - e_day_view_get_selected_time_range (day_view, &ico->dtstart, &ico->dtend); - event_editor = event_editor_new (day_view->calendar, ico); + + gnome_calendar_edit_object (day_view->calendar, ico); ical_object_unref (ico); - //gtk_widget_show (event_editor); } @@ -2320,8 +2317,6 @@ e_day_view_on_edit_appointment (GtkWidget *widget, gpointer data) { EDayView *day_view; EDayViewEvent *event; - GtkWidget *event_editor; - iCalObject *ico; day_view = E_DAY_VIEW (data); @@ -2329,14 +2324,7 @@ e_day_view_on_edit_appointment (GtkWidget *widget, gpointer data) if (event == NULL) return; - /* We must duplicate the iCalObject, since the event editor will change - * the fields. - */ - ico = ical_object_duplicate (event->ico); - - event_editor = event_editor_new (day_view->calendar, ico); - ical_object_unref (ico); - //gtk_widget_show (event_editor); + gnome_calendar_edit_object (day_view->calendar, event->ico); } @@ -2394,7 +2382,7 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) event = e_day_view_get_popup_menu_event (day_view); if (event == NULL) return; - + /* For the recurring object, we add a exception to get rid of the instance. */ ico = ical_object_duplicate (event->ico); @@ -2822,7 +2810,7 @@ e_day_view_update_long_event_resize (EDayView *day_view, if (day != day_view->resize_start_row) { need_reshape = TRUE; day_view->resize_start_row = day; - + } } else { day = MAX (day, day_view->resize_start_row); @@ -2863,7 +2851,7 @@ e_day_view_update_resize (EDayView *day_view, if (row != day_view->resize_start_row) { need_reshape = TRUE; day_view->resize_start_row = row; - + } } else { row = MAX (row, day_view->resize_start_row); @@ -2975,7 +2963,7 @@ e_day_view_abort_resize (EDayView *day_view, if (day == E_DAY_VIEW_LONG_EVENT) { e_day_view_reshape_long_event (day_view, event_num); gtk_widget_queue_draw (day_view->top_canvas); - + day_view->last_cursor_set_in_top_canvas = day_view->normal_cursor; gdk_window_set_cursor (day_view->top_canvas->window, day_view->normal_cursor); @@ -2984,7 +2972,7 @@ e_day_view_abort_resize (EDayView *day_view, e_day_view_reshape_day_event (day_view, day, event_num); e_day_view_reshape_main_canvas_resize_bars (day_view); gtk_widget_queue_draw (day_view->main_canvas); - + day_view->last_cursor_set_in_main_canvas = day_view->normal_cursor; gdk_window_set_cursor (day_view->main_canvas->window, day_view->normal_cursor); @@ -3081,7 +3069,7 @@ e_day_view_add_event (iCalObject *ico, start_tm = *(localtime (&start)); end_tm = *(localtime (&end)); - + event.ico = ico; ical_object_ref (ico); event.start = start; @@ -3132,7 +3120,7 @@ e_day_view_add_event (iCalObject *ico, } -/* This lays out the short (less than 1 day) events in the columns. +/* This lays out the short (less than 1 day) events in the columns. Any long events are simply skipped. */ void e_day_view_check_layout (EDayView *day_view) @@ -3887,7 +3875,7 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) /* We add the event locally and start editing it. When we get the "update_event" callback from the server, we basically ignore it. If we were to wait for the "update_event" callback it wouldn't be - as responsive and we may lose a few keystrokes. */ + as responsive and we may lose a few keystrokes. */ e_day_view_add_event (ico, ico->dtstart, ico->dtend, day_view); e_day_view_check_layout (day_view); gtk_widget_queue_draw (day_view->top_canvas); @@ -4223,7 +4211,7 @@ e_day_view_convert_time_to_grid_position (EDayView *day_view, minutes = tmp_tm->tm_hour * 60 + tmp_tm->tm_min; minutes -= day_view->first_hour_shown * 60 + day_view->first_minute_shown; - + *row = minutes / day_view->mins_per_row; if (*row < 0 || *row >= day_view->rows) @@ -4468,7 +4456,7 @@ e_day_view_convert_position_in_top_canvas (EDayView *day_view, day = -1; for (col = 1; col <= day_view->days_shown; col++) { if (x < day_view->day_offsets[col]) { - day = col - 1; + day = col - 1; break; } } @@ -4549,7 +4537,7 @@ e_day_view_convert_position_in_main_canvas (EDayView *day_view, day = -1; for (col = 1; col <= day_view->days_shown; col++) { if (x < day_view->day_offsets[col]) { - day = col - 1; + day = col - 1; break; } } @@ -5040,7 +5028,7 @@ e_day_view_on_drag_data_get (GtkWidget *widget, } -static void +static void e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, @@ -5117,7 +5105,7 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, } -static void +static void e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index e45efdf908..3dd20e4e48 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -36,7 +36,6 @@ #include "e-week-view-titles-item.h" #include <cal-util/timeutil.h> #include "popup-menu.h" -#include "eventedit.h" #include "../e-util/e-canvas.h" #include "../widgets/e-text/e-text.h" @@ -2611,7 +2610,6 @@ static void e_week_view_on_new_appointment (GtkWidget *widget, gpointer data) { EWeekView *week_view; - GtkWidget *event_editor; iCalObject *ico; week_view = E_WEEK_VIEW (data); @@ -2621,9 +2619,8 @@ e_week_view_on_new_appointment (GtkWidget *widget, gpointer data) ico->dtstart = week_view->day_starts[week_view->selection_start_day]; ico->dtend = week_view->day_starts[week_view->selection_end_day + 1]; - event_editor = event_editor_new (week_view->calendar, ico); + gnome_calendar_edit_object (week_view->calendar, ico); ical_object_unref (ico); - gtk_widget_show (event_editor); } @@ -2632,8 +2629,6 @@ e_week_view_on_edit_appointment (GtkWidget *widget, gpointer data) { EWeekView *week_view; EWeekViewEvent *event; - GtkWidget *event_editor; - iCalObject *ico; week_view = E_WEEK_VIEW (data); @@ -2643,13 +2638,7 @@ e_week_view_on_edit_appointment (GtkWidget *widget, gpointer data) event = &g_array_index (week_view->events, EWeekViewEvent, week_view->popup_event_num); - /* We must duplicate the iCalObject, since the event editor will - change the fields. */ - ico = ical_object_duplicate (event->ico); - - event_editor = event_editor_new (week_view->calendar, ico); - ical_object_unref (ico); - gtk_widget_show (event_editor); + gnome_calendar_edit_object (week_view->calendar, event->ico); } diff --git a/calendar/gui/event-editor.c b/calendar/gui/event-editor.c index 2df6d8ebf7..5082db36cc 100644 --- a/calendar/gui/event-editor.c +++ b/calendar/gui/event-editor.c @@ -40,7 +40,9 @@ typedef struct { /* UI handler */ BonoboUIHandler *uih; - /* Calendar object we are editing */ + /* Calendar object we are editing; this is an internal copy and is not + * one of the read-only objects from the parent calendar. + */ iCalObject *ico; /* Widgets from the Glade file */ @@ -114,6 +116,12 @@ typedef struct { +/* Signal IDs */ +enum { + ICAL_OBJECT_RELEASED, + LAST_SIGNAL +}; + static void event_editor_class_init (EventEditorClass *class); static void event_editor_init (EventEditor *ee); static void event_editor_destroy (GtkObject *object); @@ -137,6 +145,8 @@ static void recurrence_exception_added (GtkWidget *widget, EventEditor *ee); static void recurrence_exception_deleted (GtkWidget *widget, EventEditor *ee); static void recurrence_exception_changed (GtkWidget *widget, EventEditor *ee); +static guint event_editor_signals[LAST_SIGNAL]; + /** @@ -181,6 +191,17 @@ event_editor_class_init (EventEditorClass *class) parent_class = gtk_type_class (gnome_app_get_type ()); + event_editor_signals[ICAL_OBJECT_RELEASED] = + gtk_signal_new ("ical_object_released", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EventEditorClass, ical_object_released), + gtk_marshal_NONE__STRING, + GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, event_editor_signals, LAST_SIGNAL); + object_class->destroy = event_editor_destroy; } @@ -207,11 +228,21 @@ event_editor_destroy (GtkObject *object) ee = EVENT_EDITOR (object); priv = ee->priv; + if (priv->ico) { + gtk_signal_emit (GTK_OBJECT (ee), event_editor_signals[ICAL_OBJECT_RELEASED], + priv->ico->uid); + ical_object_unref (priv->ico); + priv->ico = NULL; + } + if (priv->xml) { gtk_object_unref (GTK_OBJECT (priv->xml)); priv->xml = NULL; } + bonobo_object_unref (BONOBO_OBJECT (priv->uih)); + priv->uih = NULL; + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -222,6 +253,9 @@ make_title_from_ico (iCalObject *ico) { const char *summary; + if (!ico) + return g_strdup (_("Edit Appointment")); + if (ico->summary) summary = ico->summary; else @@ -436,22 +470,43 @@ recur_options_get (GtkWidget *widget) static const int month_pos_map[] = { 0, 1, 2, 3, 4, -1 }; static const int weekday_map[] = { 0, 1, 2, 3, 4, 5, 6, -1 }; -/* Initializes the widget's values and signals */ +/* Frees the rows and the row data in the recurrence exceptions GtkCList */ static void -init_widgets (EventEditor *ee) +free_exception_clist_data (GtkCList *clist) { + int i; + + for (i = 0; i < clist->rows; i++) { + gpointer data; + + data = gtk_clist_get_row_data (clist, i); + g_free (data); + gtk_clist_set_row_data (clist, i, NULL); + } + + gtk_clist_clear (clist); +} + +/* Callback used when the exception date GtkCList is destroyed */ +static void +exception_clist_destroyed (GtkObject *object, gpointer data) +{ + EventEditor *ee; EventEditorPrivate *priv; - GList *list; + ee = EVENT_EDITOR (data); priv = ee->priv; - /* Owner, summary */ + free_exception_clist_data (GTK_CLIST (priv->recurrence_exceptions_list)); +} - e_dialog_editable_set (priv->general_owner, - priv->ico->organizer->addr ? - priv->ico->organizer->addr : _("?")); +/* Hooks the widget signals */ +static void +init_widgets (EventEditor *ee) +{ + EventEditorPrivate *priv; - e_dialog_editable_set (priv->general_summary, priv->ico->summary); + priv = ee->priv; /* Start and end times */ @@ -465,24 +520,11 @@ init_widgets (EventEditor *ee) gtk_signal_connect (GTK_OBJECT (priv->end_time), "time_changed", GTK_SIGNAL_FUNC (check_times), ee); - e_dialog_dateedit_set (priv->start_time, priv->ico->dtstart); - e_dialog_dateedit_set (priv->end_time, priv->ico->dtend); - - check_all_day (ee); - gtk_signal_connect (GTK_OBJECT (priv->all_day_event), "toggled", GTK_SIGNAL_FUNC (set_all_day), ee); /* Alarms */ - e_dialog_toggle_set (priv->alarm_display, priv->ico->dalarm.enabled); - e_dialog_toggle_set (priv->alarm_program, priv->ico->palarm.enabled); - e_dialog_toggle_set (priv->alarm_audio, priv->ico->aalarm.enabled); - e_dialog_toggle_set (priv->alarm_mail, priv->ico->malarm.enabled); - alarm_toggle (priv->alarm_display, ee); - alarm_toggle (priv->alarm_program, ee); - alarm_toggle (priv->alarm_audio, ee); - alarm_toggle (priv->alarm_mail, ee); gtk_signal_connect (GTK_OBJECT (priv->alarm_display), "toggled", GTK_SIGNAL_FUNC (alarm_toggle), ee); gtk_signal_connect (GTK_OBJECT (priv->alarm_program), "toggled", @@ -492,6 +534,165 @@ init_widgets (EventEditor *ee) gtk_signal_connect (GTK_OBJECT (priv->alarm_mail), "toggled", GTK_SIGNAL_FUNC (alarm_toggle), ee); + /* Recurrence types */ + + gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_none), "toggled", + GTK_SIGNAL_FUNC (recurrence_toggled), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_daily), "toggled", + GTK_SIGNAL_FUNC (recurrence_toggled), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_weekly), "toggled", + GTK_SIGNAL_FUNC (recurrence_toggled), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_monthly), "toggled", + GTK_SIGNAL_FUNC (recurrence_toggled), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_yearly), "toggled", + GTK_SIGNAL_FUNC (recurrence_toggled), ee); + + /* Exception buttons */ + + gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_add), "clicked", + GTK_SIGNAL_FUNC (recurrence_exception_added), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_delete), "clicked", + GTK_SIGNAL_FUNC (recurrence_exception_deleted), ee); + gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_change), "clicked", + GTK_SIGNAL_FUNC (recurrence_exception_changed), ee); + + /* Exception list */ + + gtk_signal_connect (GTK_OBJECT (priv->recurrence_exceptions_list), "destroy", + GTK_SIGNAL_FUNC (exception_clist_destroyed), ee); +} + +/* Fills the widgets with default values */ +static void +clear_widgets (EventEditor *ee) +{ + EventEditorPrivate *priv; + time_t now; + + priv = ee->priv; + + now = time (NULL); + + /* Owner, summary */ + + e_dialog_editable_set (priv->general_owner, _("?")); + e_dialog_editable_set (priv->general_summary, NULL); + + /* Start and end times */ + + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); + + e_dialog_dateedit_set (priv->start_time, now); + e_dialog_dateedit_set (priv->end_time, now); + + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); + + check_all_day (ee); + + /* Alarms */ + + /* FIXMe: these should use configurable defaults */ + + e_dialog_toggle_set (priv->alarm_display, FALSE); + e_dialog_toggle_set (priv->alarm_program, FALSE); + e_dialog_toggle_set (priv->alarm_audio, FALSE); + e_dialog_toggle_set (priv->alarm_mail, FALSE); + + e_dialog_spin_set (priv->alarm_display_amount, 15); + e_dialog_spin_set (priv->alarm_audio_amount, 15); + e_dialog_spin_set (priv->alarm_program_amount, 15); + e_dialog_spin_set (priv->alarm_mail_amount, 15); + + alarm_unit_set (priv->alarm_display_unit, ALARM_MINUTES); + alarm_unit_set (priv->alarm_audio_unit, ALARM_MINUTES); + alarm_unit_set (priv->alarm_program_unit, ALARM_MINUTES); + alarm_unit_set (priv->alarm_mail_unit, ALARM_MINUTES); + + e_dialog_editable_set (priv->alarm_program_run_program_entry, NULL); + e_dialog_editable_set (priv->alarm_mail_mail_to, NULL); + + /* Classification */ + + e_dialog_radio_set (priv->classification_radio, CLASSIFICATION_PRIVATE, classification_map); + + /* Recurrences */ + + e_dialog_radio_set (priv->recurrence_rule_none, RECUR_OPTION_NONE, recur_options_map); + + e_dialog_spin_set (priv->recurrence_rule_daily_days, 1); + + e_dialog_spin_set (priv->recurrence_rule_weekly_weeks, 1); + e_dialog_toggle_set (priv->recurrence_rule_weekly_sun, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_mon, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_tue, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_wed, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_thu, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_fri, FALSE); + e_dialog_toggle_set (priv->recurrence_rule_weekly_sat, FALSE); + + e_dialog_toggle_set (priv->recurrence_rule_monthly_on_day, TRUE); + e_dialog_spin_set (priv->recurrence_rule_monthly_day_nth, 1); + e_dialog_spin_set (priv->recurrence_rule_monthly_every_n_months, 1); + e_dialog_option_menu_set (priv->recurrence_rule_monthly_week, 0, month_pos_map); + e_dialog_option_menu_set (priv->recurrence_rule_monthly_weekpos, 0, weekday_map); + e_dialog_spin_set (priv->recurrence_rule_monthly_every_n_months, 1); + + e_dialog_spin_set (priv->recurrence_rule_yearly_every_n_years, 1); + + e_dialog_toggle_set (priv->recurrence_ending_date_repeat_forever, TRUE); + e_dialog_spin_set (priv->recurrence_ending_date_end_after_count, 1); + e_dialog_dateedit_set (priv->recurrence_ending_date_end_on_date, + time_add_day (time (NULL), 1)); + + /* Exceptions list */ + + free_exception_clist_data (GTK_CLIST (priv->recurrence_exceptions_list)); +} + +/* Fills in the widgets with the proper values */ +static void +fill_widgets (EventEditor *ee) +{ + EventEditorPrivate *priv; + GList *list; + + priv = ee->priv; + + clear_widgets (ee); + + if (!priv->ico) + return; + + /* Owner, summary */ + + e_dialog_editable_set (priv->general_owner, + priv->ico->organizer->addr ? + priv->ico->organizer->addr : _("?")); + + e_dialog_editable_set (priv->general_summary, priv->ico->summary); + + /* Start and end times */ + + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); + + e_dialog_dateedit_set (priv->start_time, priv->ico->dtstart); + e_dialog_dateedit_set (priv->end_time, priv->ico->dtend); + + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); + + check_all_day (ee); + + /* Alarms */ + + e_dialog_toggle_set (priv->alarm_display, priv->ico->dalarm.enabled); + e_dialog_toggle_set (priv->alarm_program, priv->ico->palarm.enabled); + e_dialog_toggle_set (priv->alarm_audio, priv->ico->aalarm.enabled); + e_dialog_toggle_set (priv->alarm_mail, priv->ico->malarm.enabled); + /* Alarm data */ e_dialog_spin_set (priv->alarm_display_amount, priv->ico->dalarm.count); @@ -519,28 +720,14 @@ init_widgets (EventEditor *ee) e_dialog_radio_set (priv->classification_radio, CLASSIFICATION_CONFIDENTIAL, classification_map); else { - /* What do do? */ + /* What do do? We can't g_assert_not_reached() since it is a + * value from an external file. + */ } - /* Recurrence types */ - - gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_none), "toggled", - GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_daily), "toggled", - GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_weekly), "toggled", - GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_monthly), "toggled", - GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_rule_yearly), "toggled", - GTK_SIGNAL_FUNC (recurrence_toggled), ee); - - /* Recurrence rules */ + /* Recurrences */ - if (!priv->ico->recur) - e_dialog_radio_set (priv->recurrence_rule_none, RECUR_OPTION_NONE, - recur_options_map); - else { + if (priv->ico->recur) { switch (priv->ico->recur->type) { case RECUR_DAILY: e_dialog_radio_set (priv->recurrence_rule_daily, RECUR_OPTION_DAILY, @@ -619,21 +806,12 @@ init_widgets (EventEditor *ee) } else { e_dialog_toggle_set (priv->recurrence_ending_date_end_on, TRUE); /* Shorten by one day, as we store end-on date a day ahead */ - /* FIX ME is this correct? */ + /* FIXME is this correct? */ e_dialog_dateedit_set (priv->recurrence_ending_date_end_on_date, time_add_day (priv->ico->recur->enddate, -1)); } } - /* Exception buttons */ - - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_add), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_added), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_delete), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_deleted), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_change), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_changed), ee); - /* Exceptions list */ for (list = priv->ico->exdate; list; list = list->next) @@ -874,11 +1052,22 @@ create_toolbar (EventEditor *ee) gtk_toolbar_set_style (GTK_TOOLBAR (child), GTK_TOOLBAR_ICONS); } +/** + * event_editor_construct: + * @ee: An event editor. + * @gcal: Calendar that this event editor will operate on. + * + * Constructs an event editor by binding it to the specified calendar and creating + * its widgets. + * + * Return value: The same object as @ee, or NULL if the widgets could not be + * created. In the latter case, the event editor will automatically be + * destroyed. + **/ GtkWidget * -event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico) +event_editor_construct (EventEditor *ee, GnomeCalendar *gcal) { EventEditorPrivate *priv; - char *title; GtkWidget *toplevel; GtkWidget *contents; @@ -886,8 +1075,6 @@ event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico) g_return_val_if_fail (IS_EVENT_EDITOR (ee), NULL); g_return_val_if_fail (gcal != NULL, NULL); g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - g_return_val_if_fail (ico != NULL, NULL); - g_return_val_if_fail (ico->uid != NULL, NULL); priv = ee->priv; @@ -907,7 +1094,6 @@ event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico) } priv->gcal = gcal; - priv->ico = ico; if (!get_widgets (ee)) { g_message ("event_editor_construct(): Could not find all widgets in the XML file!"); @@ -922,11 +1108,7 @@ event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico) /* Construct the app */ - title = make_title_from_ico (ico); - gnome_app_construct (GNOME_APP (ee), "event-editor", title); - g_free (title); - - /* Create the UI handler */ + gnome_app_construct (GNOME_APP (ee), "event-editor", N_("Edit Appointment")); priv->uih = bonobo_ui_handler_new (); if (!priv->uih) { @@ -953,24 +1135,63 @@ event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico) return NULL; } +/** + * event_editor_new: + * @gcal: Calendar that this event editor will operate on. + * + * Creates a new event editor dialog. + * + * Return value: A newly-created event editor dialog, or NULL if the event + * editor could not be created. + **/ GtkWidget * -event_editor_new (GnomeCalendar *gcal, iCalObject *ico) +event_editor_new (GnomeCalendar *gcal) { GtkWidget *ee; g_return_val_if_fail (gcal != NULL, NULL); g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - g_return_val_if_fail (ico != NULL, NULL); - g_return_val_if_fail (ico->uid != NULL, NULL); ee = GTK_WIDGET (gtk_type_new (TYPE_EVENT_EDITOR)); + return event_editor_construct (EVENT_EDITOR (ee), gcal); +} + +/** + * event_editor_set_ical_object: + * @ee: An event editor. + * @ico: A calendar object. + * + * Sets the calendar object that an event editor dialog will manipulate. + **/ +void +event_editor_set_ical_object (EventEditor *ee, iCalObject *ico) +{ + EventEditorPrivate *priv; + char *title; + + g_return_if_fail (ee != NULL); + g_return_if_fail (IS_EVENT_EDITOR (ee)); + + if (ico) + g_return_if_fail (ico->uid != NULL); + + priv = ee->priv; + + if (priv->ico) { + gtk_signal_emit (GTK_OBJECT (ee), event_editor_signals[ICAL_OBJECT_RELEASED], + priv->ico->uid); + ical_object_unref (priv->ico); + priv->ico = NULL; + } - ee = event_editor_construct (EVENT_EDITOR (ee), gcal, ico); + if (ico) + priv->ico = ical_object_duplicate (ico); - if (ee) - gtk_widget_show (ee); + title = make_title_from_ico (priv->ico); + gtk_window_set_title (GTK_WINDOW (ee), title); + g_free (title); - return ee; + fill_widgets (ee); } #if 0 @@ -1328,13 +1549,19 @@ check_dates (GnomeDateEdit *gde, EventEditor *ee) tm_end.tm_mon = tm_start.tm_mon; tm_end.tm_mday = tm_start.tm_mday; + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); e_dialog_dateedit_set (priv->end_time, mktime (&tm_end)); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); } else if (GTK_WIDGET (gde) == priv->end_time) { tm_start.tm_year = tm_end.tm_year; tm_start.tm_mon = tm_end.tm_mon; tm_start.tm_mday = tm_end.tm_mday; -/* e_dialog_dateedit_set (priv->start_time, mktime (&tm_start)); */ +#if 0 + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); + e_dialog_dateedit_set (priv->start_time, mktime (&tm_start)); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); +#endif } } } @@ -1351,10 +1578,10 @@ check_times (GnomeDateEdit *gde, EventEditor *ee) struct tm tm_start, tm_end; priv = ee->priv; - +#if 0 gdk_pointer_ungrab (GDK_CURRENT_TIME); gdk_flush (); - +#endif start = e_dialog_dateedit_get (priv->start_time); end = e_dialog_dateedit_get (priv->end_time); @@ -1373,7 +1600,9 @@ check_times (GnomeDateEdit *gde, EventEditor *ee) tm_end.tm_sec = 0; } + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); e_dialog_dateedit_set (priv->end_time, mktime (&tm_end)); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); } else if (GTK_WIDGET (gde) == priv->end_time) { tm_start.tm_min = tm_end.tm_min; tm_start.tm_sec = tm_end.tm_sec; @@ -1385,7 +1614,9 @@ check_times (GnomeDateEdit *gde, EventEditor *ee) tm_start.tm_min = 0; } + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); e_dialog_dateedit_set (priv->start_time, mktime (&tm_start)); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); } } diff --git a/calendar/gui/event-editor.h b/calendar/gui/event-editor.h index b3a9550555..401f2142e2 100644 --- a/calendar/gui/event-editor.h +++ b/calendar/gui/event-editor.h @@ -45,30 +45,23 @@ struct _EventEditor { /* Private data */ gpointer priv; - - /* The associated ical object */ - iCalObject *ical; - - /* The calendar owner of this event */ - GnomeCalendar *gnome_cal; - - /* - char *description; - char *host; - int port; - char *rootdn; - */ }; struct _EventEditorClass { GnomeAppClass parent_class; + + /* Notification signals */ + + void (* ical_object_released) (EventEditor *ee, const char *uid); }; GtkType event_editor_get_type (void); -GtkWidget *event_editor_construct (EventEditor *ee, GnomeCalendar *gcal, iCalObject *ico); +GtkWidget *event_editor_construct (EventEditor *ee, GnomeCalendar *gcal); + +GtkWidget *event_editor_new (GnomeCalendar *gcal); -GtkWidget *event_editor_new (GnomeCalendar *gcal, iCalObject *ico); +void event_editor_set_ical_object (EventEditor *ee, iCalObject *ico); #if 0 /* Convenience function to create and show a new event editor for an diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c deleted file mode 100644 index c1b8b860f7..0000000000 --- a/calendar/gui/eventedit.c +++ /dev/null @@ -1,1576 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * EventEditor widget - * Copyright (C) 1998 the Free Software Foundation - * - * Authors: Miguel de Icaza (miguel@kernel.org) - * Federico Mena (quartic@gimp.org) - */ -#include <config.h> -#include <gnome.h> -#include <string.h> -#include <cal-util/timeutil.h> -#include "eventedit.h" -#include "calendar-commands.h" - - -static void event_editor_class_init (EventEditorClass *class); -static void event_editor_init (EventEditor *ee); -static void event_editor_destroy (GtkObject *object); - -GtkWidget* make_spin_button (int val, int low, int high); -void ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, - int y, gboolean control_sens, GtkSignalFunc dirty_func); -void ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type); - -/* Note: do not i18n these strings, they are part of the vCalendar protocol */ -static char *class_names [] = { "PUBLIC", "PRIVATE", "CONFIDENTIAL" }; - -static GnomeDialogClass *parent_class; - -struct numbered_item { - char *text; - int num; -}; - - -guint -event_editor_get_type (void) -{ - static guint event_editor_type = 0; - - if(!event_editor_type) { - GtkTypeInfo event_editor_info = { - "EventEditor", - sizeof(EventEditor), - sizeof(EventEditorClass), - (GtkClassInitFunc) event_editor_class_init, - (GtkObjectInitFunc) event_editor_init, - (GtkArgSetFunc) NULL, - (GtkArgGetFunc) NULL, - }; - event_editor_type = gtk_type_unique (gnome_dialog_get_type (), &event_editor_info); - } - return event_editor_type; -} - -static void -event_editor_class_init (EventEditorClass *class) -{ - GtkObjectClass *object_class; - - parent_class = gtk_type_class (gnome_dialog_get_type ()); - object_class = (GtkObjectClass*) class; - object_class->destroy = event_editor_destroy; -} - -GtkWidget * -make_spin_button (int val, int low, int high) -{ - GtkAdjustment *adj; - GtkWidget *spin; - - adj = GTK_ADJUSTMENT (gtk_adjustment_new (val, low, high, 1, 10, 10)); - spin = gtk_spin_button_new (adj, 0.5, 0); - gtk_widget_set_usize (spin, 60, 0); - - return spin; -} - -/* - * Checks if the day range occupies all the day, and if so, check the - * box accordingly - */ -static void -ee_check_all_day (EventEditor *ee) -{ - time_t ev_start, ev_end; - - ev_start = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); - ev_end = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); - - if (get_time_t_hour (ev_start) <= day_begin && get_time_t_hour (ev_end) >= day_end) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 1); - else - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 0); -} - -/* - * Callback: checks that the dates are start < end - */ -static void -check_dates (GnomeDateEdit *gde, EventEditor *ee) -{ - time_t start, end; - struct tm tm_start, tm_end; - - start = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); - end = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); - - if (start > end) { - tm_start = *localtime (&start); - tm_end = *localtime (&end); - - if (GTK_WIDGET (gde) == ee->start_time) { - tm_end.tm_year = tm_start.tm_year; - tm_end.tm_mon = tm_start.tm_mon; - tm_end.tm_mday = tm_start.tm_mday; - - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (&tm_end)); - } else if (GTK_WIDGET (gde) == ee->end_time) { - tm_start.tm_year = tm_end.tm_year; - tm_start.tm_mon = tm_end.tm_mon; - tm_start.tm_mday = tm_end.tm_mday; - - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->start_time), mktime (&tm_start)); - } - } -} - -/* - * Callback: checks that start_time < end_time and whether the - * selected hour range spans all of the day - */ -static void -check_times (GnomeDateEdit *gde, EventEditor *ee) -{ - time_t start, end; - struct tm tm_start, tm_end; - - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_flush (); - - start = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); - end = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); - - if (start >= end) { - tm_start = *localtime (&start); - tm_end = *localtime (&end); - - if (GTK_WIDGET (gde) == ee->start_time) { - tm_end.tm_min = tm_start.tm_min; - tm_end.tm_sec = tm_start.tm_sec; - - tm_end.tm_hour = tm_start.tm_hour + 1; - - if (tm_end.tm_hour >= 24) { - tm_end.tm_hour = 24; /* mktime() will bump the day */ - tm_end.tm_min = 0; - tm_end.tm_sec = 0; - } - - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (&tm_end)); - } else if (GTK_WIDGET (gde) == ee->end_time) { - tm_start.tm_min = tm_end.tm_min; - tm_start.tm_sec = tm_end.tm_sec; - - tm_start.tm_hour = tm_end.tm_hour - 1; - - if (tm_start.tm_hour < 0) { - tm_start.tm_hour = 0; - tm_start.tm_min = 0; - tm_start.tm_min = 0; - } - - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->start_time), mktime (&tm_start)); - } - } - - /* Check whether the event spans the whole day */ - - ee_check_all_day (ee); -} - -/* - * Callback: all day event box clicked - */ -static void -set_all_day (GtkToggleButton *toggle, EventEditor *ee) -{ - struct tm tm; - time_t start_t; - - start_t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); - tm = *localtime (&start_t); - tm.tm_hour = day_begin; - tm.tm_min = 0; - tm.tm_sec = 0; - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->start_time), mktime (&tm)); - - if (toggle->active) - tm.tm_hour = day_end; - else - tm.tm_hour++; - - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (&tm)); -} - -/* Convenience function to create a properly-configured date editor widget */ -GtkWidget * -date_edit_new (time_t the_time, int show_time) -{ - return gnome_date_edit_new_flags (the_time, - ((show_time ? GNOME_DATE_EDIT_SHOW_TIME : 0) - | (am_pm_flag ? 0 : GNOME_DATE_EDIT_24_HR) - | (week_starts_on_monday - ? GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY - : 0))); -} - -static GtkWidget * -event_editor_setup_time_frame (EventEditor *ee) -{ - GtkWidget *frame; - GtkWidget *start_time, *end_time; - GtkTable *t; - - frame = gtk_frame_new (_("Time")); - t = GTK_TABLE (ee->general_time_table = gtk_table_new (1, 1, 0)); - gtk_container_border_width (GTK_CONTAINER (t), 4); - gtk_table_set_row_spacings (t, 4); - gtk_table_set_col_spacings (t, 4); - gtk_container_add (GTK_CONTAINER (frame), ee->general_time_table); - - /* 1. Start time */ - if (ee->ical->dtstart == 0){ - ee->ical->dtstart = time (NULL); - ee->ical->dtend = time_add_minutes (ee->ical->dtstart, 30); - } - ee->start_time = start_time = date_edit_new (ee->ical->dtstart, TRUE); - gnome_date_edit_set_popup_range ((GnomeDateEdit *) start_time, day_begin, day_end); - gtk_signal_connect (GTK_OBJECT (start_time), "date_changed", - GTK_SIGNAL_FUNC (check_dates), ee); - gtk_signal_connect (GTK_OBJECT (start_time), "time_changed", - GTK_SIGNAL_FUNC (check_times), ee); - gtk_table_attach (t, gtk_label_new (_("Start time:")), 1, 2, 1, 2, - GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - gtk_table_attach (t, start_time, 2, 3, 1, 2, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - - /* 2. End time */ - ee->end_time = end_time = date_edit_new (ee->ical->dtend, TRUE); - gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); - gtk_signal_connect (GTK_OBJECT (end_time), "date_changed", - GTK_SIGNAL_FUNC (check_dates), ee); - gtk_signal_connect (GTK_OBJECT (end_time), "time_changed", - GTK_SIGNAL_FUNC (check_times), ee); - gtk_table_attach (t, gtk_label_new (_("End time:")), 1, 2, 2, 3, - GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - gtk_table_attach (t, end_time, 2, 3, 2, 3, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - - /* 3. All day checkbox */ - ee->general_allday = gtk_check_button_new_with_label (_("All day event")); - gtk_signal_connect (GTK_OBJECT (ee->general_allday), "toggled", - GTK_SIGNAL_FUNC (set_all_day), ee); - gtk_table_attach (t, ee->general_allday, 3, 4, 1, 2, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 4, 0); - ee_check_all_day (ee); - - return frame; -} - -static GtkWidget * -timesel_new (void) -{ - GtkWidget *menu, *option_menu; - char *items [] = { N_("Minutes"), N_("Hours"), N_("Days") }; - int i; - - option_menu = gtk_option_menu_new (); - menu = gtk_menu_new (); - for (i = 0; i < 3; i++){ - GtkWidget *item; - - item = gtk_menu_item_new_with_label (_(items [i])); - gtk_menu_append (GTK_MENU (menu), item); - gtk_widget_show (item); - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); - return option_menu; -} - -/* - * Set the sensitive state depending on whether the alarm enabled flag. - */ -static void -ee_alarm_setting (CalendarAlarm *alarm, int sensitive) -{ - gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_count), sensitive); - gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_timesel), sensitive); - - if (alarm->type == ALARM_PROGRAM || alarm->type == ALARM_MAIL){ - gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_entry), sensitive); - gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_label), sensitive); - } -} - -static void -alarm_toggle (GtkToggleButton *toggle, CalendarAlarm *alarm) -{ - ee_alarm_setting (alarm, toggle->active); -} - -#define FXS (GTK_FILL | GTK_EXPAND | GTK_SHRINK) -#define FS (GTK_FILL | GTK_SHRINK) - -void -ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y, gboolean control_sens, GtkSignalFunc dirty_func) -{ - GtkWidget *entry; - - alarm->w_enabled = gtk_check_button_new_with_label (str); - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (alarm->w_enabled), - alarm->enabled); - if (control_sens) - gtk_signal_connect (GTK_OBJECT (alarm->w_enabled), "toggled", - GTK_SIGNAL_FUNC (alarm_toggle), alarm); - if (dirty_func) - gtk_signal_connect (GTK_OBJECT (alarm->w_enabled), "toggled", - GTK_SIGNAL_FUNC (dirty_func), NULL); - gtk_table_attach (table, alarm->w_enabled, 0, 1, y, y+1, FS, FS, 0, 0); - - alarm->w_count = make_spin_button (alarm->count, 0, 10000); - if (dirty_func) - gtk_signal_connect (GTK_OBJECT (alarm->w_count), "changed", - GTK_SIGNAL_FUNC (dirty_func), NULL); - gtk_table_attach (table, alarm->w_count, 1, 2, y, y+1, FS, FS, 0, 0); - - alarm->w_timesel = timesel_new (); - /* is there a "changed" signal which we can connect to? */ - gtk_option_menu_set_history (GTK_OPTION_MENU (alarm->w_timesel), alarm->units); - gtk_table_attach (table, alarm->w_timesel, 2, 3, y, y+1, FS, FS, 0, 0); - - switch (type){ - case ALARM_MAIL: - alarm->w_label = gtk_label_new (_("Mail to:")); - gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); - gtk_table_attach (table, alarm->w_label, 3, 4, y, y+1, FS, FS, 0, 0); - alarm->w_entry = gtk_entry_new (); - gtk_table_attach (table, alarm->w_entry, 4, 5, y, y+1, FXS, FS, 0, 0); - gtk_entry_set_text (GTK_ENTRY (alarm->w_entry), alarm->data ? alarm->data : ""); - if (dirty_func) - gtk_signal_connect (GTK_OBJECT (alarm->w_entry), - "changed", - GTK_SIGNAL_FUNC (dirty_func), - NULL); - break; - - case ALARM_PROGRAM: - alarm->w_label = gtk_label_new (_("Run program:")); - gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); - gtk_table_attach (table, alarm->w_label, 3, 4, y, y+1, FS, FS, 0, 0); - alarm->w_entry = gnome_file_entry_new ("alarm-program", _("Select program to run at alarm time")); - entry = gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (alarm->w_entry)); - gtk_entry_set_text (GTK_ENTRY (entry), alarm->data ? alarm->data : ""); - gtk_table_attach (table, alarm->w_entry, 4, 5, y, y+1, FXS, FS, 0, 0); - if (dirty_func) - gtk_signal_connect (GTK_OBJECT (entry), - "changed", - GTK_SIGNAL_FUNC (dirty_func), - NULL); - break; - - default: - break; - } - - if (control_sens) - ee_alarm_setting (alarm, alarm->enabled); - else - ee_alarm_setting (alarm, TRUE); -} - -static GtkWidget * -ee_alarm_widgets (EventEditor *ee) -{ - GtkWidget *table, *mailto, *mailte, *l; - - l = gtk_frame_new (_("Alarms")); - - table = gtk_table_new (1, 1, 0); - gtk_container_border_width (GTK_CONTAINER (table), 4); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - gtk_container_add (GTK_CONTAINER (l), table); - - mailto = gtk_label_new (_("Mail to:")); - mailte = gtk_entry_new (); - - ee_create_ae (GTK_TABLE (table), _("Display"), &ee->ical->dalarm, ALARM_DISPLAY, 1, TRUE, NULL); - ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->aalarm, ALARM_AUDIO, 2, TRUE, NULL); - ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->palarm, ALARM_PROGRAM, 3, TRUE, NULL); - ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->malarm, ALARM_MAIL, 4, TRUE, NULL); - - return l; -} - -static GtkWidget * -ee_classification_widgets (EventEditor *ee) -{ - GtkWidget *rpub, *rpriv, *rconf; - GtkWidget *frame, *hbox; - - frame = gtk_frame_new (_("Classification")); - - hbox = gtk_hbox_new (TRUE, 0); - gtk_container_border_width (GTK_CONTAINER (hbox), 4); - gtk_container_add (GTK_CONTAINER (frame), hbox); - - rpub = gtk_radio_button_new_with_label (NULL, _("Public")); - rpriv = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Private")); - rconf = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Confidential")); - - gtk_box_pack_start (GTK_BOX (hbox), rpub, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), rpriv, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), rconf, FALSE, FALSE, 0); - - if (strcmp (ee->ical->class, class_names[0]) == 0) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (rpub), TRUE); - else if (strcmp (ee->ical->class, class_names[1]) == 0) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (rpriv), TRUE); - else if (strcmp (ee->ical->class, class_names[2]) == 0) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (rconf), TRUE); - - ee->general_radios = rpub; - - return frame; -} - -/* - * Retrieves the information from the CalendarAlarm widgets and stores them - * on the CalendarAlarm generic values - */ -void -ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type) -{ - GtkWidget *item; - GtkMenu *menu; - GList *child; - int idx; - - if (alarm->data){ - g_free (alarm->data); - alarm->data = 0; - } - - alarm->enabled = GTK_TOGGLE_BUTTON (alarm->w_enabled)->active; - - if (!alarm->enabled) - return; - - if (type == ALARM_PROGRAM) - alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (alarm->w_entry)))); - if (type == ALARM_MAIL) - alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (alarm->w_entry))); - - /* Find out the index */ - menu = GTK_MENU (GTK_OPTION_MENU (alarm->w_timesel)->menu); - - item = gtk_menu_get_active (menu); - - for (idx = 0, child = GTK_MENU_SHELL (menu)->children; child->data != item; child = child->next) - idx++; - - alarm->units = idx; - alarm->count = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (alarm->w_count)); -} - -static void -ee_store_general_values_to_ical (EventEditor *ee) -{ - GtkRadioButton *radio = GTK_RADIO_BUTTON (ee->general_radios); - iCalObject *ical = ee->ical; - GSList *list = radio->group; - int idx; - time_t now; - - now = time (NULL); - ical->dtstart = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); - ical->dtend = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); - - if (ical->summary) - g_free (ical->summary); - - ical->summary = gtk_editable_get_chars (GTK_EDITABLE (ee->general_summary), 0, -1); - - ee_store_alarm (&ical->dalarm, ALARM_DISPLAY); - ee_store_alarm (&ical->aalarm, ALARM_AUDIO); - ee_store_alarm (&ical->palarm, ALARM_PROGRAM); - ee_store_alarm (&ical->malarm, ALARM_MAIL); - - for (idx = 2; list; list = list->next) { - if (GTK_TOGGLE_BUTTON (list->data)->active) - break; - idx--; /* The group is stored in reverse order of insertion */ - } - - g_free (ical->class); - ical->class = g_strdup (class_names [idx]); -} - -static int -option_menu_active_number (GtkWidget *omenu) -{ - GtkWidget *menu; - GtkWidget *item; - struct numbered_item *ni; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu)); - item = gtk_menu_get_active (GTK_MENU (menu)); - - ni = gtk_object_get_user_data (GTK_OBJECT (item)); - - return ni->num; -} - -static int -ee_store_recur_rule_to_ical (EventEditor *ee) -{ - iCalObject *ical; - int i, j; - GSList *list; - - ical = ee->ical; - - for (i = 0, list = ee->recur_rr_group; list; i++, list = list->next) - if (GTK_TOGGLE_BUTTON (list->data)->active) - break; - - i = g_slist_length (ee->recur_rr_group) - i - 1; /* buttons are stored in reverse order of insertion */ - - /* None selected, no rule to be stored */ - if (i == 0) - return 0; - - if (!ical->recur) - ical->recur = g_new0 (Recurrence, 1); - - switch (i) { - case 1: - /* Daily */ - ical->recur->type = RECUR_DAILY; - ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_day_period)); - break; - - case 2: - /* Weekly */ - ical->recur->type = RECUR_WEEKLY; - ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_week_period)); - ical->recur->weekday = 0; - - for (j = 0; j < 7; j++) - if (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days[j])->active) { - if (j == 6) - ical->recur->weekday |= 1 << 0; /* sunday is at bit 0 */ - else - ical->recur->weekday |= 1 << (j + 1); - } - - break; - - case 3: - /* Monthly */ - - if (GTK_WIDGET_SENSITIVE (ee->recur_rr_month_date)) { - /* by day */ - - ical->recur->type = RECUR_MONTHLY_BY_DAY; - ical->recur->u.month_day = - gtk_spin_button_get_value_as_int ( - GTK_SPIN_BUTTON (ee->recur_rr_month_date)); - ical->recur->interval = - gtk_spin_button_get_value_as_int ( - GTK_SPIN_BUTTON (ee->recur_rr_month_period)); - } else { - /* by position */ - - ical->recur->type = RECUR_MONTHLY_BY_POS; - - ical->recur->u.month_pos = - option_menu_active_number (ee->recur_rr_month_day); - ical->recur->weekday = - option_menu_active_number (ee->recur_rr_month_weekday); - ical->recur->interval = - gtk_spin_button_get_value_as_int ( - GTK_SPIN_BUTTON (ee->recur_rr_month_period)); - } - - break; - - case 4: - /* Yearly */ - ical->recur->type = RECUR_YEARLY_BY_DAY; - ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_year_period)); - /* FIXME: need to specify anything else? I am assuming the code will look at the dtstart - * to figure out when to recur. - Federico - */ - break; - - default: - g_assert_not_reached (); - } - return 1; -} - -static void -ee_store_recur_end_to_ical (EventEditor *ee) -{ - iCalObject *ical; - GSList *list; - int i; - - /* Ending date of recurrence */ - - ical = ee->ical; - - for (i = 0, list = ee->recur_ed_group; list; i++, list = list->next) - if (GTK_TOGGLE_BUTTON (list->data)->active) - break; - - i = g_slist_length (ee->recur_ed_group) - i - 1; /* the list is stored in reverse order of insertion */ - - switch (i) { - case 0: - /* repeat forever */ - ical->recur->_enddate = 0; - ical->recur->enddate = 0; - ical->recur->duration = 0; - break; - - case 1: - /* end date */ - /* Also here, to ensure that the event is used, we add 86400 secs to get - get next day, in accordance to the RFC */ - ical->recur->_enddate = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ed_end_on)) + 86400; - ical->recur->enddate = ical->recur->_enddate; - ical->recur->duration = 0; - break; - - case 2: - /* end after n occurrences */ - ical->recur->duration = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_ed_end_after)); - ical_object_compute_end (ical); - break; - - default: - g_assert_not_reached (); - break; - } -} - -static void -free_exdate (iCalObject *ical) -{ - GList *list; - - if (!ical->exdate) - return; - - for (list = ical->exdate; list; list = list->next) - g_free (list->data); - - g_list_free (ical->exdate); - ical->exdate = NULL; -} - -static void -ee_store_recur_exceptions_to_ical (EventEditor *ee) -{ - iCalObject *ical; - GtkCList *clist; - int i; - time_t *t; - - ical = ee->ical; - clist = GTK_CLIST (ee->recur_ex_clist); - - free_exdate (ical); - - for (i = 0; i < clist->rows; i++) { - t = gtk_clist_get_row_data (clist, i); - ical->exdate = g_list_prepend (ical->exdate, t); - } -} - -static void -ee_store_recur_values_to_ical (EventEditor *ee) -{ - if (ee_store_recur_rule_to_ical (ee)){ - ee_store_recur_exceptions_to_ical (ee); - ee_store_recur_end_to_ical (ee); - } else if (ee->ical->recur) { - g_free (ee->ical->recur); - ee->ical->recur = NULL; - if (ee->ical->exdate){ - GList *l = ee->ical->exdate; - - for (; l; l = l->next) - g_free (l->data); - g_list_free (l); - } - } -} - -/* - * Retrieves all of the information from the different widgets and updates - * the iCalObject accordingly. - */ -static void -ee_store_dlg_values_to_ical (EventEditor *ee) -{ - time_t now; - - ee_store_general_values_to_ical (ee); - ee_store_recur_values_to_ical (ee); - - now = time (NULL); - - /* FIXME: This is not entirely correct; we should check if the values actually changed */ - ee->ical->last_mod = now; - - if (ee->ical->new) - ee->ical->created = now; -} - -static void -ee_ok (GtkWidget *widget, EventEditor *ee) -{ - ee_store_dlg_values_to_ical (ee); - - if (ee->ical->new) - gnome_calendar_add_object (ee->gnome_cal, ee->ical); - else - gnome_calendar_object_changed (ee->gnome_cal, ee->ical); - - ee->ical->new = 0; -} - -static void -ee_cancel (GtkWidget *widget, EventEditor *ee) -{ - if (ee->ical) { - ical_object_unref (ee->ical); - ee->ical = NULL; - } -} - -static void -ee_create_buttons (EventEditor *ee) -{ - gnome_dialog_append_buttons(GNOME_DIALOG(ee), - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, NULL); - gnome_dialog_set_default (GNOME_DIALOG (ee), 0); - gnome_dialog_button_connect (GNOME_DIALOG (ee), 0, GTK_SIGNAL_FUNC(ee_ok), ee); - gnome_dialog_button_connect (GNOME_DIALOG (ee), 1, GTK_SIGNAL_FUNC(ee_cancel), ee); - - return; -} - -enum { - OWNER_LINE, - SUMMARY_LINE, - TIME_LINE, - ALARM_LINE, - CLASS_LINE -}; - -/* Create/setup the general page */ -static void -ee_init_general_page (EventEditor *ee) -{ - GtkWidget *l; - GtkWidget *hbox; - - ee->general_table = gtk_table_new (1, 1, FALSE); - gtk_container_border_width (GTK_CONTAINER (ee->general_table), 4); - gtk_table_set_row_spacings (GTK_TABLE (ee->general_table), 4); - gtk_table_set_col_spacings (GTK_TABLE (ee->general_table), 4); - gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), GTK_WIDGET (ee->general_table), - gtk_label_new (_("General"))); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (ee->general_table), hbox, - 0, 1, OWNER_LINE, OWNER_LINE + 1, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 4); - - l = gtk_label_new (_("Owner:")); - gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0); - - ee->general_owner = gtk_label_new (ee->ical->organizer->addr ? - ee->ical->organizer->addr : _("?")); - gtk_misc_set_alignment (GTK_MISC (ee->general_owner), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), ee->general_owner, TRUE, TRUE, 4); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (ee->general_table), hbox, - 0, 1, SUMMARY_LINE, SUMMARY_LINE + 1, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 4); - - l = gtk_label_new (_("Summary:")); - gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (hbox), l, FALSE, FALSE, 0); - - ee->general_summary = gtk_entry_new (); - gtk_entry_set_editable (GTK_ENTRY (ee->general_summary), 1); - gtk_entry_set_text (GTK_ENTRY (ee->general_summary), - ee->ical->summary ? ee->ical->summary : ""); - gtk_box_pack_start (GTK_BOX (hbox), ee->general_summary, - TRUE, TRUE, 4); - - l = ee_alarm_widgets (ee); - gtk_table_attach (GTK_TABLE (ee->general_table), l, - 0, 1, ALARM_LINE, ALARM_LINE + 1, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - - l = event_editor_setup_time_frame (ee); - gtk_table_attach (GTK_TABLE (ee->general_table), l, - 0, 1, TIME_LINE, TIME_LINE + 1, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); - - l = ee_classification_widgets (ee); - gtk_table_attach (GTK_TABLE (ee->general_table), l, - 0, 1, CLASS_LINE, CLASS_LINE + 1, - GTK_EXPAND | GTK_SHRINK, - GTK_FILL | GTK_SHRINK, - 0, 0); -} - -static void -ee_init_summary_page (EventEditor *ee) -{ -} - -struct { - char *name; -} recurrence_types [] = { - { N_("None") }, - { N_("Daily") }, - { N_("Weekly") }, - { N_("Monthly") }, - { N_("Yearly") }, - { 0 } -}; - -static void -recurrence_toggled (GtkRadioButton *radio, EventEditor *ee) -{ - GSList *list = ee->recur_rr_group; - int which; - - if (!GTK_TOGGLE_BUTTON (radio)->active) - return; - - for (which = 0; list; list = list->next, which++) { - if (list->data == radio) { - gtk_notebook_set_page (GTK_NOTEBOOK (ee->recur_rr_notebook), 4 - which); - return; - } - } -} - -static struct numbered_item weekday_positions[] = { - { N_("1st"), 1 }, - { N_("2nd"), 2 }, - { N_("3rd"), 3 }, - { N_("4th"), 4 }, - { N_("5th"), 5 }, - { 0 } -}; - -static struct numbered_item weekday_names[] = { - { N_("Monday"), 1 }, - { N_("Tuesday"), 2 }, - { N_("Wednesday"), 3 }, - { N_("Thursday"), 4 }, - { N_("Friday"), 5 }, - { N_("Saturday"), 6 }, - { N_("Sunday"), 0 }, /* on the spec, Sunday is zero */ - { 0 } -}; - -static GtkWidget * -make_numbered_menu (struct numbered_item *items, int sel) -{ - GtkWidget *option_menu, *menu; - int i; - - option_menu = gtk_option_menu_new (); - menu = gtk_menu_new (); - - for (i = 0; items[i].text; i++) { - GtkWidget *item; - - item = gtk_menu_item_new_with_label (_(items[i].text)); - gtk_object_set_user_data (GTK_OBJECT (item), &items[i]); - gtk_menu_append (GTK_MENU (menu), item); - gtk_widget_show (item); - } - - gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); - gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), sel); - - return option_menu; -} - -static void -month_sensitize (EventEditor *ee, int state) -{ - gtk_widget_set_sensitive (ee->recur_rr_month_date, state); - gtk_widget_set_sensitive (ee->recur_rr_month_date_label, state); - - gtk_widget_set_sensitive (ee->recur_rr_month_day, !state); - gtk_widget_set_sensitive (ee->recur_rr_month_weekday, !state); -} - -static void -recur_month_enable_date (GtkToggleButton *button, EventEditor *ee) -{ - month_sensitize (ee, button->active); -} - -static void -desensitize_on_toggle (GtkToggleButton *toggle, gpointer data) -{ - gtk_widget_set_sensitive (GTK_WIDGET (data), !toggle->active); -} - -static void -ee_rp_init_rule (EventEditor *ee) -{ - static char *day_names [] = { N_("Mon"), N_("Tue"), N_("Wed"), N_("Thu"), N_("Fri"), N_("Sat"), N_("Sun") }; - GtkWidget *r, *re, *r1, *f, *vbox, *hbox, *b, *week_hbox, *week_day, *w; - GtkWidget *none, *daily, *weekly, *monthly, *yearly; - GtkNotebook *notebook; - GSList *group; - int i, page, day_period, week_period, month_period, year_period; - int week_vector, default_day, def_pos, def_off; - struct tm tm; - - tm = *localtime (&ee->ical->dtstart); - - f = gtk_frame_new (_("Recurrence rule")); - - hbox = gtk_hbox_new (FALSE, 4); - gtk_container_border_width (GTK_CONTAINER (hbox), 4); - gtk_container_add (GTK_CONTAINER (f), hbox); - - vbox = gtk_vbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (hbox), gtk_vseparator_new (), FALSE, FALSE, 0); - - ee->recur_rr_notebook = gtk_notebook_new (); - notebook = GTK_NOTEBOOK (ee->recur_rr_notebook); - gtk_box_pack_start (GTK_BOX (hbox), ee->recur_rr_notebook, TRUE, TRUE, 0); - - day_period = 1; - week_period = 1; - month_period = 1; - year_period = 1; - - /* Default to today */ - - week_vector = 1 << tm.tm_wday; - default_day = tm.tm_mday; - def_pos = 0; - def_off = 0; - - /* Determine which should be the default selection */ - - page = 0; - if (ee->ical->recur) { - enum RecurType type = ee->ical->recur->type; - int interval = ee->ical->recur->interval; - - switch (type) { - case RECUR_DAILY: - page = 1; - day_period = interval; - break; - - case RECUR_WEEKLY: - page = 2; - week_period = interval; - week_vector = ee->ical->recur->weekday; - break; - - case RECUR_MONTHLY_BY_POS: - page = 3; - month_period = interval; - def_pos = ee->ical->recur->u.month_pos; - default_day = ee->ical->recur->weekday; /* you can't use u.month_pos and u.month_day-- it's a union... */ - break; - - case RECUR_MONTHLY_BY_DAY: - page = 3; - month_period = interval; - default_day = ee->ical->recur->u.month_day; - break; - - case RECUR_YEARLY_BY_MONTH: - page = 4; - year_period = interval; - break; - - case RECUR_YEARLY_BY_DAY: - page = 4; - year_period = interval; - break; - } - } else - page = 0; - - /* The recurrency selector */ - - for (i = 0, group = NULL; recurrence_types [i].name; i++) { - r = gtk_radio_button_new_with_label (group, _(recurrence_types [i].name)); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (r)); - - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r), i == page); - gtk_signal_connect (GTK_OBJECT (r), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_box_pack_start (GTK_BOX (vbox), r, FALSE, FALSE, 0); - - if (i == 0) - gtk_signal_connect (GTK_OBJECT (r), "toggled", - (GtkSignalFunc) desensitize_on_toggle, - ee->recur_hbox); - } - - ee->recur_rr_group = group; - - /* 0. No recurrence */ - none = gtk_label_new (""); - - /* 1. The daily recurrence */ - - daily = gtk_vbox_new (FALSE, 0); - - b = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (daily), b, FALSE, FALSE, 0); - - ee->recur_rr_day_period = make_spin_button (day_period, 1, 10000); - /* in some languages "Every" can follow the gender of the word it - refers to (here "day(s)"). leave the two leadin letter "d_" - in the translation they are ther on purpose */ - gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("d_Every") +2), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_day_period, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("day(s)")), FALSE, FALSE, 0); - - /* 2. The weekly recurrence */ - - weekly = gtk_vbox_new (FALSE, 4); - - week_hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (weekly), week_hbox, FALSE, FALSE, 0); - - /* 2.1 The week period selector */ - - ee->recur_rr_week_period = make_spin_button (week_period, 1, 10000); - /* in some languages "Every" can follow the gender of the word it - refers to (here "week(s)"). leave the two leadin letter "w_" - in the translation they are ther on purpose */ - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("w_Every") +2), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (week_hbox), ee->recur_rr_week_period, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("week(s)")), FALSE, FALSE, 0); - - /* 2.2 The week day selector */ - - week_day = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (weekly), week_day, FALSE, FALSE, 0); - - for (i = 0; i < 7; i++) { - ee->recur_rr_week_days [i] = gtk_check_button_new_with_label (_(day_names [i])); - gtk_box_pack_start (GTK_BOX (week_day), ee->recur_rr_week_days [i], FALSE, FALSE, 0); - - if (week_vector & (1 << ((i + 1) % 7))) /* on the spec, Sunday is 0 */ - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days [i]), TRUE); - } - - /* 3. The monthly recurrence */ - - monthly = gtk_table_new (0, 0, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (monthly), 4); - gtk_table_set_col_spacings (GTK_TABLE (monthly), 4); - - re = gtk_radio_button_new_with_label (NULL, _("Recur on the")); - ee->recur_rr_month_date = make_spin_button (default_day, 1, 31); - ee->recur_rr_month_date_label = w = gtk_label_new (_("th day of the month")); - gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (monthly), re, - 0, 1, 0, 1, FS, FS, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_date, - 1, 2, 0, 1, FS, FS, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), w, - 2, 3, 0, 1, FS, FS, 0, 0); - gtk_signal_connect (GTK_OBJECT (re), "toggled", GTK_SIGNAL_FUNC (recur_month_enable_date), ee); - - r1 = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (re)), _("Recur on the")); - ee->recur_rr_month_day = make_numbered_menu (weekday_positions, def_pos); - ee->recur_rr_month_weekday = make_numbered_menu (weekday_names, default_day); - gtk_table_attach (GTK_TABLE (monthly), r1, - 0, 1, 1, 2, FS, FS, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_day, - 1, 2, 1, 2, FS, FS, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_weekday, - 2, 3, 1, 2, FS, FS, 0, 0); - - /* in some languages "Every" can follow the gender of the word it - refers to (here "month(s)"). leave the two leadin letter "m_" - in the translation they are ther on purpose */ - gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("m_Every") +2), - 3, 4, 0, 2, FS, FS, 0, 0); - ee->recur_rr_month_period = make_spin_button (month_period, 1, 10000); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_period, - 4, 5, 0, 2, FS, FS, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("month(s)")), - 5, 6, 0, 2, FS, FS, 0, 0); - - if (ee->ical->recur) { - if (ee->ical->recur->type == RECUR_MONTHLY_BY_POS) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r1), 1); - } else - recur_month_enable_date (GTK_TOGGLE_BUTTON (re), ee); - - /* 4. The yearly recurrence */ - - yearly = gtk_vbox_new (FALSE, 0); - - b = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (yearly), b, FALSE, FALSE, 0); - - ee->recur_rr_year_period = make_spin_button (year_period, 1, 10000); - /* in some languages "Every" can follow the gender of the word it - refers to (here "year(s)"). leave the two leadin letter "y_" - in the translation they are ther on purpose */ - gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("y_Every") +2), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_year_period, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("year(s)")), FALSE, FALSE, 0); - - /* Finish setting this up */ - - gtk_notebook_set_show_tabs (notebook, FALSE); - - gtk_notebook_append_page (notebook, none, NULL); - gtk_notebook_append_page (notebook, daily, NULL); - gtk_notebook_append_page (notebook, weekly, NULL); - gtk_notebook_append_page (notebook, monthly, NULL); - gtk_notebook_append_page (notebook, yearly, NULL); - - gtk_notebook_set_show_border (notebook, FALSE); - - gtk_notebook_set_page (notebook, page); - - /* Attach to the main box */ - - gtk_box_pack_start (GTK_BOX (ee->recur_vbox), f, FALSE, FALSE, 0); -} - -static void -sensitize_on_toggle (GtkToggleButton *toggle, gpointer data) -{ - gtk_widget_set_sensitive (GTK_WIDGET (data), toggle->active); -} - -static void -ee_rp_init_ending_date (EventEditor *ee) -{ - GtkWidget *frame; - GtkWidget *vbox; - GSList *group; - GtkWidget *radio0, *radio1, *radio2; - GtkWidget *hbox; - GtkWidget *ihbox; - GtkWidget *widget; - time_t enddate; - int repeat; - - frame = gtk_frame_new (_("Ending date")); - - vbox = gtk_vbox_new (TRUE, 4); - gtk_container_border_width (GTK_CONTAINER (vbox), 4); - gtk_container_add (GTK_CONTAINER (frame), vbox); - - group = NULL; - - /* repeat forever */ - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - radio0 = gtk_radio_button_new_with_label (group, _("Repeat forever")); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio0)); - gtk_box_pack_start (GTK_BOX (hbox), radio0, FALSE, FALSE, 0); - - /* end on date */ - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - radio1 = gtk_radio_button_new_with_label (group, _("End on")); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio1)); - gtk_box_pack_start (GTK_BOX (hbox), radio1, FALSE, FALSE, 0); - - ihbox = gtk_hbox_new (FALSE, 4); - gtk_widget_set_sensitive (ihbox, FALSE); - gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); - - if (ee->ical->recur) { - /* Shorten by one day, as we store end-on date a day ahead */ - enddate = ee->ical->recur->enddate - 86400; - } else - enddate = ee->ical->dtend; - - ee->recur_ed_end_on = widget = date_edit_new (enddate, FALSE); - gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); - - gtk_signal_connect (GTK_OBJECT (radio1), "toggled", - (GtkSignalFunc) sensitize_on_toggle, - ihbox); - - /* end after n occurrences */ - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); - - radio2 = gtk_radio_button_new_with_label (group, _("End after")); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio2)); - gtk_box_pack_start (GTK_BOX (hbox), radio2, FALSE, FALSE, 0); - - ihbox = gtk_hbox_new (FALSE, 4); - gtk_widget_set_sensitive (ihbox, FALSE); - gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); - - if (ee->ical->recur && ee->ical->recur->duration) - repeat = ee->ical->recur->duration; - else - repeat = 2; - - ee->recur_ed_end_after = widget = make_spin_button (repeat, 1, 10000); - gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); - - widget = gtk_label_new (_("occurrence(s)")); - gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); - - gtk_signal_connect (GTK_OBJECT (radio2), "toggled", - (GtkSignalFunc) sensitize_on_toggle, - ihbox); - - /* Activate appropriate item */ - - if (ee->ical->recur) { - if (ee->ical->recur->_enddate == 0) { - if (ee->ical->recur->duration == 0) - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio0), TRUE); - else { - gtk_spin_button_set_value (GTK_SPIN_BUTTON (ee->recur_ed_end_after), - ee->ical->recur->duration); - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio2), TRUE); - } - } else { - gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->recur_ed_end_on), ee->ical->recur->enddate); - gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio1), TRUE); - } - } - - /* Done, add to main table */ - - ee->recur_ed_group = group; - - gtk_box_pack_start (GTK_BOX (ee->recur_hbox), frame, FALSE, FALSE, 0); -} - -static char * -get_exception_string (time_t t) -{ - static char buf[256]; - - strftime (buf, sizeof(buf), _("%a %b %d %Y"), localtime (&t)); - return buf; -} - -static void -append_exception (EventEditor *ee, time_t t) -{ - time_t *tt; - char *c[1]; - int i; - - c[0] = get_exception_string (t); - - tt = g_new (time_t, 1); - *tt = t; - - i = gtk_clist_append (GTK_CLIST (ee->recur_ex_clist), c); - gtk_clist_set_row_data (GTK_CLIST (ee->recur_ex_clist), i, tt); - gtk_clist_select_row (GTK_CLIST (ee->recur_ex_clist), i, 0); - - gtk_widget_set_sensitive (ee->recur_ex_vbox, TRUE); -} - -static void -fill_exception_clist (EventEditor *ee) -{ - GList *list; - - for (list = ee->ical->exdate; list; list = list->next) - append_exception (ee, *((time_t *) list->data)); -} - -static void -add_exception (GtkWidget *widget, EventEditor *ee) -{ - time_t t; - - t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); - append_exception (ee, t); -} - -static void -change_exception (GtkWidget *widget, EventEditor *ee) -{ - GtkCList *clist; - time_t *t; - int sel; - - clist = GTK_CLIST (ee->recur_ex_clist); - sel = GPOINTER_TO_INT(clist->selection->data); - - t = gtk_clist_get_row_data (clist, sel); - *t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); - - gtk_clist_set_text (clist, sel, 0, get_exception_string (*t)); -} - -static void -delete_exception (GtkWidget *widget, EventEditor *ee) -{ - GtkCList *clist; - int sel, length; - - clist = GTK_CLIST (ee->recur_ex_clist); - sel = GPOINTER_TO_INT(clist->selection->data); - - g_free (gtk_clist_get_row_data (clist, sel)); /* free the time_t stored there */ - - gtk_clist_remove (clist, sel); - length = g_list_length(clist->row_list); - if (sel >= length) - sel--; - gtk_clist_select_row (GTK_CLIST (ee->recur_ex_clist), sel, 0); - - if (clist->rows == 0) - gtk_widget_set_sensitive (ee->recur_ex_vbox, FALSE); -} - -static void -ee_rp_init_exceptions (EventEditor *ee) -{ - GtkWidget *frame; - GtkWidget *hbox; - GtkWidget *vbox; - GtkWidget *ivbox; - GtkWidget *widget; - GtkWidget *sw; - - frame = gtk_frame_new (_("Exceptions")); - - hbox = gtk_hbox_new (FALSE, 4); - gtk_container_border_width (GTK_CONTAINER (hbox), 4); - gtk_container_add (GTK_CONTAINER (frame), hbox); - - vbox = gtk_vbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); - - ee->recur_ex_date = widget = date_edit_new (time (NULL), FALSE); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); - - widget = gtk_button_new_with_label (_("Add exception")); - gtk_signal_connect (GTK_OBJECT (widget), "clicked", - (GtkSignalFunc) add_exception, - ee); - gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); - - ee->recur_ex_vbox = ivbox = gtk_vbox_new (FALSE, 4); - gtk_widget_set_sensitive (ivbox, FALSE); /* at first there are no items to change or delete */ - gtk_box_pack_start (GTK_BOX (vbox), ivbox, FALSE, FALSE, 0); - - widget = gtk_button_new_with_label (_("Change selected")); - gtk_signal_connect (GTK_OBJECT (widget), "clicked", - (GtkSignalFunc) change_exception, - ee); - gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); - - widget = gtk_button_new_with_label (_("Delete selected")); - gtk_signal_connect (GTK_OBJECT (widget), "clicked", - (GtkSignalFunc) delete_exception, - ee); - gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); - - ee->recur_ex_clist = widget = gtk_clist_new (1); - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (sw), widget); - gtk_clist_set_selection_mode (GTK_CLIST (widget), GTK_SELECTION_BROWSE); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - fill_exception_clist (ee); - gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0); - - /* Done, add to main table */ - - gtk_box_pack_start (GTK_BOX (ee->recur_hbox), frame, TRUE, TRUE, 0); -} - -static void -ee_init_recurrence_page (EventEditor *ee) -{ - ee->recur_vbox = gtk_vbox_new (FALSE, 4); - gtk_container_border_width (GTK_CONTAINER (ee->recur_vbox), 4); - - ee->recur_hbox = gtk_hbox_new (FALSE, 4); - gtk_widget_set_sensitive (ee->recur_hbox, FALSE); - - ee->recur_page_label = gtk_label_new (_("Recurrence")); - - gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), ee->recur_vbox, - ee->recur_page_label); - - - ee_rp_init_rule (ee); - - /* pack here so that the box gets inserted after the recurrence rule frame */ - gtk_box_pack_start (GTK_BOX (ee->recur_vbox), ee->recur_hbox, FALSE, FALSE, 0); - - ee_rp_init_ending_date (ee); - ee_rp_init_exceptions (ee); - -} - -static void -event_editor_init_widgets (EventEditor *ee) -{ - ee->notebook = gtk_notebook_new (); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG(ee)->vbox), ee->notebook, 1, 1, 0); - - /* Init the various configuration pages */ - ee_init_general_page (ee); - ee_init_summary_page (ee); - ee_init_recurrence_page (ee); - - /* Buttons */ - ee_create_buttons(ee); - - /* We show all of the contained widgets */ - gtk_widget_show_all (GTK_BIN (ee)->child); -} - -static void -event_editor_init (EventEditor *ee) -{ - ee->ical = 0; - gnome_dialog_set_close (GNOME_DIALOG(ee), TRUE); -} - -static void -event_editor_destroy (GtkObject *object) -{ - EventEditor *ee; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_EVENT_EDITOR (object)); - - ee = EVENT_EDITOR (object); - - if (ee->ical) { - ical_object_unref (ee->ical); - ee->ical = NULL; - } -} - -GtkWidget * -event_editor_new (GnomeCalendar *gcal, iCalObject *ical) -{ - GtkWidget *retval; - EventEditor *ee; - - gdk_pointer_ungrab (GDK_CURRENT_TIME); - gdk_flush (); - - retval = gtk_type_new (event_editor_get_type ()); - ee = EVENT_EDITOR (retval); - - if (ical == 0){ - ical = ical_new ("", user_name, ""); - ical->new = 1; - } else { - ical_object_ref (ical); - } - - if (ical->new){ - gtk_window_set_title (GTK_WINDOW (ee), _("Create new appointment")); - } else { - gtk_window_set_title (GTK_WINDOW (ee), _("Edit appointment")); - } - - ical->user_data = ee; /* so that the world can know we are editing it */ - - ee->ical = ical; - ee->gnome_cal = gcal; - event_editor_init_widgets (ee); - - gtk_widget_show (retval); - - return retval; -} - -void -event_editor_new_whole_day (GnomeCalendar *owner, time_t day) -{ - struct tm tm; - iCalObject *ico; - GtkWidget *ee; - - g_return_if_fail (owner != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (owner)); - - ico = ical_new ("", user_name, ""); - ico->new = TRUE; - - tm = *localtime (&day); - - /* Set the start time of the event to the beginning of the day */ - - tm.tm_hour = day_begin; - tm.tm_min = 0; - tm.tm_sec = 0; - ico->dtstart = mktime (&tm); - - /* Set the end time of the event to the end of the day */ - - tm.tm_hour = day_end; - ico->dtend = mktime (&tm); - - /* Launch the event editor */ - - ee = event_editor_new (owner, ico); -} diff --git a/calendar/gui/eventedit.h b/calendar/gui/eventedit.h deleted file mode 100644 index 4d605892dd..0000000000 --- a/calendar/gui/eventedit.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * EventEditor widget - * Copyright (C) 1998 the Free Software Foundation - * - * Author: Miguel de Icaza (miguel@kernel.org) - */ - -#ifndef EVENT_EDITOR_H -#define EVENT_EDITOR_H - -#include "gnome-cal.h" -#include <libgnomeui/gnome-dialog.h> - -BEGIN_GNOME_DECLS - - -#define EVENT_EDITOR(obj) GTK_CHECK_CAST(obj, event_editor_get_type(), EventEditor) -#define EVENT_EDITOR_CLASS(class) GTK_CHECK_CAST_CLASS(class, event_editor_get_type(), EventEditorClass) -#define IS_EVENT_EDITOR(obj) GTK_CHECK_TYPE(obj, event_editor_get_type()) - - -typedef struct { - GnomeDialog dialog; - GtkWidget *notebook; - - GtkWidget *general; - GtkWidget *general_table; - GtkWidget *general_time_table; - GtkWidget *general_allday; - GtkWidget *general_owner; - GtkWidget *general_summary; - GtkWidget *start_time, *end_time; - GtkWidget *general_radios; - - GtkWidget *recur_page_label; - GtkWidget *recur_vbox; - GtkWidget *recur_hbox; - - GSList *recur_rr_group; - GtkWidget *recur_rr_notebook; - GtkWidget *recur_rr_day_period; - GtkWidget *recur_rr_week_period; - GtkWidget *recur_rr_week_days [7]; - GtkWidget *recur_rr_month_date; - GtkWidget *recur_rr_month_date_label; - GtkWidget *recur_rr_month_day; - GtkWidget *recur_rr_month_weekday; - GtkWidget *recur_rr_month_period; - GtkWidget *recur_rr_year_period; - - GSList *recur_ed_group; - GtkWidget *recur_ed_end_on; - GtkWidget *recur_ed_end_after; - - GtkWidget *recur_ex_date; - GtkWidget *recur_ex_vbox; - GtkWidget *recur_ex_clist; - - /* The associated ical object */ - iCalObject *ical; - - /* The calendar owner of this event */ - GnomeCalendar *gnome_cal; -} EventEditor; - -typedef struct { - GnomeDialogClass parent_class; -} EventEditorClass; - - -guint event_editor_get_type (void); -GtkWidget *event_editor_new (GnomeCalendar *owner, iCalObject *); - -/* Convenience function to create and show a new event editor for an event that goes from day_begin - * to day_end of the specified day. - */ -void event_editor_new_whole_day (GnomeCalendar *owner, time_t day); - -GtkWidget *date_edit_new (time_t the_time, int show_time); - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/evolution-calendar-control.c b/calendar/gui/evolution-calendar-control.c index 90b4f26cd4..2e5e7741da 100644 --- a/calendar/gui/evolution-calendar-control.c +++ b/calendar/gui/evolution-calendar-control.c @@ -15,7 +15,6 @@ #include <cal-util/timeutil.h> #include <gui/alarm.h> -#include <gui/eventedit.h> #include <gui/gnome-cal.h> #include <gui/calendar-commands.h> diff --git a/calendar/gui/gncal-todo.c b/calendar/gui/gncal-todo.c index 1308a6f5eb..e10840bf8d 100644 --- a/calendar/gui/gncal-todo.c +++ b/calendar/gui/gncal-todo.c @@ -9,10 +9,10 @@ #include <config.h> #include <string.h> #include <gnome.h> +#include "event-editor.h" #include "gncal-todo.h" #include "calendar-commands.h" #include "popup-menu.h" -#include "eventedit.h" int todo_show_due_date = 0; int todo_show_priority = 0; diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index b6d035c201..e1e366885f 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -24,7 +24,7 @@ #include "alarm.h" #include "e-day-view.h" #include "e-week-view.h" -#include "eventedit.h" +#include "event-editor.h" #include "gncal-todo.h" #include "gnome-cal.h" #include "calendar-commands.h" @@ -99,6 +99,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class) static void gnome_calendar_init (GnomeCalendar *gcal) { + gcal->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal); gcal->alarms = g_hash_table_new (g_str_hash, g_str_equal); } @@ -121,6 +122,16 @@ free_object_alarms (gpointer key, gpointer value, gpointer data) g_free (oa); } +/* Used from g_hash_table_foreach(); frees an UID string */ +static void +free_uid (gpointer key, gpointer value, gpointer data) +{ + char *uid; + + uid = key; + g_free (uid); +} + static void gnome_calendar_destroy (GtkObject *object) { @@ -137,6 +148,10 @@ gnome_calendar_destroy (GtkObject *object) g_hash_table_destroy (gcal->alarms); gcal->alarms = NULL; + g_hash_table_foreach (gcal->object_editor_hash, free_uid, NULL); + g_hash_table_destroy (gcal->object_editor_hash); + gcal->object_editor_hash = NULL; + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -525,16 +540,7 @@ snooze (GnomeCalendar *gcal, iCalObject *ico, time_t occur, int snooze_mins, gbo static void edit (GnomeCalendar *gcal, iCalObject *ico) { - iCalObject *new_ico; - GtkWidget *event_editor; - - /* We must duplicate the iCalObject, since the event editor will change - * the fields. - */ - new_ico = ical_object_duplicate (ico); - - event_editor = event_editor_new (gcal, new_ico); - gtk_widget_show (event_editor); + gnome_calendar_edit_object (gcal, ico); } struct alarm_notify_closure { @@ -1301,6 +1307,67 @@ gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, gnome_calendar_update_gtk_calendar (gcal); } +/* Brings attention to a window by raising it and giving it focus */ +static void +raise_and_focus (GtkWidget *widget) +{ + g_assert (GTK_WIDGET_REALIZED (widget)); + gdk_window_show (widget->window); + gtk_widget_grab_focus (widget); +} + +/* Callback used when an event editor finishes editing an object */ +static void +ical_object_released_cb (EventEditor *ee, const char *uid, gpointer data) +{ + GnomeCalendar *gcal; + gboolean result; + gpointer orig_key; + char *orig_uid; + + gcal = GNOME_CALENDAR (data); + + result = g_hash_table_lookup_extended (gcal->object_editor_hash, uid, &orig_key, NULL); + g_assert (result != FALSE); + + orig_uid = orig_key; + + g_hash_table_remove (gcal->object_editor_hash, orig_uid); + g_free (orig_uid); +} + +void +gnome_calendar_edit_object (GnomeCalendar *gcal, iCalObject *ico) +{ + GtkWidget *ee; + + g_return_if_fail (gcal != NULL); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (ico != NULL); + g_return_if_fail (ico->uid != NULL); + + ee = g_hash_table_lookup (gcal->object_editor_hash, ico->uid); + if (!ee) { + ee = event_editor_new (gcal); + if (!ee) { + g_message ("gnome_calendar_edit_object(): Could not create the event editor"); + return; + } + + /* FIXME: what to do when an event editor wants to switch + * objects? We would need to know about it as well. + */ + + g_hash_table_insert (gcal->object_editor_hash, g_strdup (ico->uid), ee); + gtk_signal_connect (GTK_OBJECT (ee), "ical_object_released", + GTK_SIGNAL_FUNC (ical_object_released_cb), gcal); + + event_editor_set_ical_object (EVENT_EDITOR (ee), ico); + } + + gtk_widget_show_now (ee); + raise_and_focus (ee); +} /* Returns the selected time range for the current view. Note that this may be different from the fields in the GnomeCalendar, since the view may clip diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 41f8b43d9e..e6d01b8567 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -32,6 +32,8 @@ typedef struct { BonoboPropertyBag *properties; BonoboControl *control; + GHashTable *object_editor_hash; + time_t selection_start_time; time_t selection_end_time; @@ -99,6 +101,9 @@ void gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, time_t start_time, time_t end_time); +void gnome_calendar_edit_object (GnomeCalendar *gcal, + iCalObject *ico); + /* Returns the selected time range for the current view. Note that this may be different from the fields in the GnomeCalendar, since the view may clip this or choose a more appropriate time. */ @@ -106,22 +111,21 @@ void gnome_calendar_get_current_time_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time); -/* Flags is a bitmask of CalObjectChange values */ void gnome_calendar_object_changed (GnomeCalendar *gcal, iCalObject *obj); -GnomeCalendar *gnome_calendar_locate (const char *pathname); - /* Notifies the calendar that the time format has changed and it must update all its views */ void gnome_calendar_time_format_changed (GnomeCalendar *gcal); -/* Notifies the calendar that the todo list properties have changed and its time to update the views */ -void -gnome_calendar_colors_changed (GnomeCalendar *gcal); +/* Notifies the calendar that the todo list properties have changed and its time + * to update the views. + */ +void gnome_calendar_colors_changed (GnomeCalendar *gcal); -/* Notifies the calendar that the todo list properties have changed and its time to update the views */ -void -gnome_calendar_todo_properties_changed (GnomeCalendar *gcal); +/* Notifies the calendar that the todo list properties have changed and its time + * to update the views. + */ +void gnome_calendar_todo_properties_changed (GnomeCalendar *gcal); diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 2b3f3ac762..486372463d 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -39,7 +39,6 @@ #include <cal-util/timeutil.h> #include <gui/alarm.h> -#include <gui/eventedit.h> #include <gui/gnome-cal.h> #include <gui/calendar-commands.h> #include "component-factory.h" |