aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/gnome-cal.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/gnome-cal.c')
-rw-r--r--calendar/gui/gnome-cal.c1465
1 files changed, 0 insertions, 1465 deletions
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
deleted file mode 100644
index bf3ce408d5..0000000000
--- a/calendar/gui/gnome-cal.c
+++ /dev/null
@@ -1,1465 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * GnomeCalendar widget
- * Copyright (C) 1998 the Free Software Foundation
- *
- * Authors: Miguel de Icaza (miguel@kernel.org)
- * Federico Mena-Quintero <federico@helixcode.com>
- */
-
-#include <config.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <gtk/gtkframe.h>
-#include <widgets/e-paned/e-hpaned.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <widgets/e-paned/e-vpaned.h>
-#include <libgnomeui/gnome-messagebox.h>
-#include <cal-util/timeutil.h>
-#include "dialogs/alarm-notify-dialog.h"
-#include "alarm.h"
-#include "e-calendar-table.h"
-#include "e-day-view.h"
-#include "e-week-view.h"
-#include "event-editor.h"
-#include "gnome-cal.h"
-#include "calendar-commands.h"
-
-
-
-/* An entry in the UID->alarms hash table. The UID key *is* the uid field in
- * this structure, so don't free it separately.
- */
-typedef struct {
- char *uid;
- GList *alarm_ids;
-} ObjectAlarms;
-
-
-
-static void gnome_calendar_class_init (GnomeCalendarClass *class);
-static void gnome_calendar_init (GnomeCalendar *gcal);
-static void gnome_calendar_destroy (GtkObject *object);
-
-static void gnome_calendar_update_view_times (GnomeCalendar *gcal,
- GtkWidget *page);
-static void gnome_calendar_update_gtk_calendar (GnomeCalendar *gcal);
-static void gnome_calendar_on_day_selected (GtkCalendar *calendar,
- GnomeCalendar *gcal);
-static void gnome_calendar_on_month_changed (GtkCalendar *calendar,
- GnomeCalendar *gcal);
-
-static GtkVBoxClass *parent_class;
-
-static void setup_alarm (GnomeCalendar *cal, CalAlarmInstance *ai);
-
-
-
-guint
-gnome_calendar_get_type (void)
-{
- static guint gnome_calendar_type = 0;
- if(!gnome_calendar_type) {
- GtkTypeInfo gnome_calendar_info = {
- "GnomeCalendar",
- sizeof (GnomeCalendar),
- sizeof (GnomeCalendarClass),
- (GtkClassInitFunc) gnome_calendar_class_init,
- (GtkObjectInitFunc) gnome_calendar_init,
- (GtkArgSetFunc) NULL,
- (GtkArgGetFunc) NULL,
- };
- /*
- gnome_calendar_type = gtk_type_unique(gnome_app_get_type(), &gnome_calendar_info);
- parent_class = gtk_type_class (gnome_app_get_type());
- */
- gnome_calendar_type = gtk_type_unique (gtk_vbox_get_type (),
- &gnome_calendar_info);
- parent_class = gtk_type_class (gtk_vbox_get_type ());
- }
- return gnome_calendar_type;
-}
-
-/* Class initialization function for the gnome calendar */
-static void
-gnome_calendar_class_init (GnomeCalendarClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- object_class->destroy = gnome_calendar_destroy;
-}
-
-/* Object initialization function for the gnome calendar */
-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);
-}
-
-/* Used from g_hash_table_foreach(); frees an object alarms entry */
-static void
-free_object_alarms (gpointer key, gpointer value, gpointer data)
-{
- ObjectAlarms *oa;
-
- oa = value;
-
- g_assert (oa->uid != NULL);
- g_free (oa->uid);
- oa->uid = NULL;
-
- g_assert (oa->alarm_ids != NULL);
- g_list_free (oa->alarm_ids);
- oa->alarm_ids = NULL;
-
- 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)
-{
- GnomeCalendar *gcal;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (object));
-
- gcal = GNOME_CALENDAR (object);
-
- gtk_object_unref (GTK_OBJECT (gcal->client));
-
- g_hash_table_foreach (gcal->alarms, free_object_alarms, NULL);
- 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);
-}
-
-
-static void
-setup_widgets (GnomeCalendar *gcal)
-{
- GtkWidget *vpane, *w;
-
- /* The Main Notebook. */
- gcal->main_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (gcal->main_notebook),
- FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gcal->main_notebook), FALSE);
- gtk_widget_show (gcal->main_notebook);
- gtk_box_pack_start (GTK_BOX (gcal), gcal->main_notebook,
- TRUE, TRUE, 0);
-
- /* The First Page of the Main Notebook, containing a HPaned with the
- Sub-Notebook on the left and the GtkCalendar and ToDo list on the
- right. */
- gcal->hpane = e_hpaned_new ();
- gtk_widget_show (gcal->hpane);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->main_notebook),
- gcal->hpane, gtk_label_new (""));
-
- /* The Sub-Notebook, to contain the Day, Work-Week & Week views. */
- gcal->sub_notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (gcal->sub_notebook),
- FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (gcal->sub_notebook), FALSE);
- gtk_widget_show (gcal->sub_notebook);
- e_paned_pack1 (E_PANED (gcal->hpane), gcal->sub_notebook,
- TRUE, TRUE);
-
- /* The VPaned widget, to contain the GtkCalendar & ToDo list. */
- vpane = e_vpaned_new ();
- gtk_widget_show (vpane);
- e_paned_pack2 (E_PANED (gcal->hpane), vpane, FALSE, TRUE);
-
- /* The GtkCalendar. */
- w = gtk_calendar_new ();
- gcal->gtk_calendar = GTK_CALENDAR (w);
- gtk_widget_show (w);
- e_paned_pack1 (E_PANED (vpane), w, FALSE, TRUE);
- gcal->day_selected_id = gtk_signal_connect (GTK_OBJECT (gcal->gtk_calendar),
- "day_selected",
- (GtkSignalFunc) gnome_calendar_on_day_selected,
- gcal);
- gtk_signal_connect (GTK_OBJECT (gcal->gtk_calendar), "month_changed",
- GTK_SIGNAL_FUNC (gnome_calendar_on_month_changed),
- gcal);
-
- /* The ToDo list. */
-#if 0
- gcal->todo = gncal_todo_new (gcal);
- e_paned_pack2 (E_PANED (vpane), gcal->todo, TRUE, TRUE);
- gtk_widget_show (gcal->todo);
-#endif
-
- gcal->todo = e_calendar_table_new ();
- e_paned_pack2 (E_PANED (vpane), gcal->todo, TRUE, TRUE);
- gtk_widget_show (gcal->todo);
- e_calendar_table_set_cal_client (E_CALENDAR_TABLE (gcal->todo),
- gcal->client);
-
-
- /* The Day View. */
- gcal->day_view = e_day_view_new ();
- e_day_view_set_calendar (E_DAY_VIEW (gcal->day_view), gcal);
- gtk_widget_show (gcal->day_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
- gcal->day_view, gtk_label_new (""));
-
- /* The Work Week View. */
- gcal->work_week_view = e_day_view_new ();
- e_day_view_set_days_shown (E_DAY_VIEW (gcal->work_week_view), 5);
- e_day_view_set_calendar (E_DAY_VIEW (gcal->work_week_view), gcal);
- gtk_widget_show (gcal->work_week_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
- gcal->work_week_view, gtk_label_new (""));
-
- /* The Week View. */
- gcal->week_view = e_week_view_new ();
- e_week_view_set_calendar (E_WEEK_VIEW (gcal->week_view), gcal);
- gtk_widget_show (gcal->week_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->sub_notebook),
- gcal->week_view, gtk_label_new (""));
-
- /* The Month View. */
- gcal->month_view = e_week_view_new ();
- e_week_view_set_calendar (E_WEEK_VIEW (gcal->month_view), gcal);
- e_week_view_set_display_month (E_WEEK_VIEW (gcal->month_view), TRUE);
- gtk_widget_show (gcal->month_view);
- gtk_notebook_append_page (GTK_NOTEBOOK (gcal->main_notebook),
- gcal->month_view, gtk_label_new (""));
-}
-
-static GtkWidget *
-get_current_page (GnomeCalendar *gcal)
-{
- GtkWidget *page;
-
- page = GTK_NOTEBOOK (gcal->main_notebook)->cur_page->child;
- if (page == gcal->hpane)
- return GTK_NOTEBOOK (gcal->sub_notebook)->cur_page->child;
- else
- return page;
-}
-
-char *
-gnome_calendar_get_current_view_name (GnomeCalendar *gcal)
-{
- GtkWidget *page;
-
- g_return_val_if_fail (gcal != NULL, "dayview");
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), "dayview");
-
- page = get_current_page (gcal);
-
- if (page == gcal->day_view)
- return "dayview";
- else if (page == gcal->work_week_view)
- return "workweekview";
- else if (page == gcal->week_view)
- return "weekview";
- else if (page == gcal->month_view)
- return "monthview";
- else
- return "dayview";
-}
-
-void
-gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (new_time != -1);
-
- gcal->selection_start_time = time_day_begin (new_time);
- gcal->selection_end_time = time_add_day (gcal->selection_start_time,
- 1);
- gnome_calendar_update_view_times (gcal, NULL);
- gnome_calendar_update_gtk_calendar (gcal);
-}
-
-
-static void
-gnome_calendar_update_view_times (GnomeCalendar *gcal,
- GtkWidget *page)
-{
- if (page == NULL)
- page = get_current_page (gcal);
-
- if (page == gcal->day_view
- || page == gcal->work_week_view)
- e_day_view_set_selected_time_range (E_DAY_VIEW (page),
- gcal->selection_start_time,
- gcal->selection_end_time);
- else if (page == gcal->week_view
- || page == gcal->month_view)
- e_week_view_set_selected_time_range (E_WEEK_VIEW (page),
- gcal->selection_start_time,
- gcal->selection_end_time);
- else {
- g_warning ("My penguin is gone!");
- g_assert_not_reached ();
- }
-}
-
-static void
-gnome_calendar_direction (GnomeCalendar *gcal, int direction)
-{
- GtkWidget *cp = get_current_page (gcal);
- time_t start_time, end_time;
-
- start_time = gcal->selection_start_time;
- end_time = gcal->selection_end_time;
-
- if (cp == gcal->day_view) {
- start_time = time_add_day (start_time, direction);
- end_time = time_add_day (end_time, direction);
- } else if (cp == gcal->work_week_view) {
- start_time = time_add_week (start_time, direction);
- end_time = time_add_week (end_time, direction);
- } else if (cp == gcal->week_view) {
- start_time = time_add_week (start_time, direction);
- end_time = time_add_week (end_time, direction);
- } else if (cp == gcal->month_view) {
- start_time = time_add_month (start_time, direction);
- end_time = time_add_month (end_time, direction);
- } else {
- g_warning ("Weee! Where did the penguin go?");
- g_assert_not_reached ();
- start_time = 0;
- end_time = 0;
- }
-
- gcal->selection_start_time = start_time;
- gcal->selection_end_time = end_time;
-
- gnome_calendar_update_view_times (gcal, NULL);
- gnome_calendar_update_gtk_calendar (gcal);
-}
-
-void
-gnome_calendar_next (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_direction (gcal, 1);
-}
-
-void
-gnome_calendar_previous (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_direction (gcal, -1);
-}
-
-void
-gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_set_view (gcal, "dayview");
- gnome_calendar_goto (gcal, time);
-}
-
-void
-gnome_calendar_goto_today (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_goto (gcal, time (NULL));
-}
-
-
-/* This sets which view is currently shown. It also updates the selection time
- of the view so it shows the appropriate days. */
-void
-gnome_calendar_set_view (GnomeCalendar *gcal, char *page_name)
-{
- GtkWidget *page;
- int main_page = 0, sub_page = -1;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (page_name != NULL);
-
- if (strcmp (page_name, "dayview") == 0) {
- page = gcal->day_view;
- sub_page = 0;
- } else if (strcmp (page_name, "workweekview") == 0) {
- page = gcal->work_week_view;
- sub_page = 1;
- } else if (strcmp (page_name, "weekview") == 0) {
- page = gcal->week_view;
- sub_page = 2;
- } else if (strcmp (page_name, "monthview") == 0) {
- page = gcal->month_view;
- main_page = 1;
- } else {
- g_warning ("Unknown calendar view: %s", page_name);
- return;
- }
-
- gnome_calendar_update_view_times (gcal, page);
-
- if (sub_page != -1)
- gtk_notebook_set_page (GTK_NOTEBOOK (gcal->sub_notebook),
- sub_page);
- gtk_notebook_set_page (GTK_NOTEBOOK (gcal->main_notebook), main_page);
-
- gnome_calendar_update_gtk_calendar (gcal);
-}
-
-/* Sends a mail notification of an alarm trigger */
-static void
-mail_notification (char *mail_address, char *text, time_t app_time)
-{
- pid_t pid;
- int p [2];
- char *command;
-
- pipe (p);
- pid = fork ();
- if (pid == 0){
- int dev_null;
-
- dev_null = open ("/dev/null", O_RDWR);
- dup2 (p [0], 0);
- dup2 (dev_null, 1);
- dup2 (dev_null, 2);
- execl ("/usr/lib/sendmail", "/usr/lib/sendmail",
- mail_address, NULL);
- _exit (127);
- }
- command = g_strconcat ("To: ", mail_address, "\n",
- "Subject: ", _("Reminder of your appointment at "),
- ctime (&app_time), "\n\n", text, "\n", NULL);
- write (p [1], command, strlen (command));
- close (p [1]);
- close (p [0]);
- g_free (command);
-}
-
-static int
-max_open_files (void)
-{
- static int files;
-
- if (files)
- return files;
-
- files = sysconf (_SC_OPEN_MAX);
- if (files != -1)
- return files;
-#ifdef OPEN_MAX
- return files = OPEN_MAX;
-#else
- return files = 256;
-#endif
-}
-
-/* Executes a program as a notification of an alarm trigger */
-static void
-program_notification (char *command, int close_standard)
-{
- struct sigaction ignore, save_intr, save_quit;
- int status = 0, i;
- pid_t pid;
-
- ignore.sa_handler = SIG_IGN;
- sigemptyset (&ignore.sa_mask);
- ignore.sa_flags = 0;
-
- sigaction (SIGINT, &ignore, &save_intr);
- sigaction (SIGQUIT, &ignore, &save_quit);
-
- if ((pid = fork ()) < 0){
- fprintf (stderr, "\n\nfork () = -1\n");
- return;
- }
- if (pid == 0){
- pid = fork ();
- if (pid == 0){
- const int top = max_open_files ();
- sigaction (SIGINT, &save_intr, NULL);
- sigaction (SIGQUIT, &save_quit, NULL);
-
- for (i = (close_standard ? 0 : 3); i < top; i++)
- close (i);
-
- /* FIXME: As an excercise to the reader, copy the
- * code from mc to setup shell properly instead of
- * /bin/sh. Yes, this comment is larger than a cut and paste.
- */
- execl ("/bin/sh", "/bin/sh", "-c", command, (char *) 0);
-
- _exit (127);
- } else {
- _exit (127);
- }
- }
- wait (&status);
- sigaction (SIGINT, &save_intr, NULL);
- sigaction (SIGQUIT, &save_quit, NULL);
-}
-
-/* Queues a snooze alarm */
-static void
-snooze (GnomeCalendar *gcal, iCalObject *ico, time_t occur, int snooze_mins, gboolean audio)
-{
- time_t now, trigger;
- struct tm tm;
- CalAlarmInstance ai;
-
- now = time (NULL);
- tm = *localtime (&now);
- tm.tm_min += snooze_mins;
-
- trigger = mktime (&tm);
- if (trigger == -1) {
- g_message ("snooze(): produced invalid time_t; not queueing alarm!");
- return;
- }
-
- ai.uid = ico->uid;
- ai.type = audio ? ALARM_AUDIO : ALARM_DISPLAY;
- ai.trigger = trigger;
- ai.occur = occur;
-
- setup_alarm (gcal, &ai);
-}
-
-/* Edits an appointment from the alarm notification dialog */
-static void
-edit (GnomeCalendar *gcal, iCalObject *ico)
-{
- gnome_calendar_edit_object (gcal, ico);
-}
-
-struct alarm_notify_closure {
- GnomeCalendar *gcal;
- iCalObject *ico;
- time_t occur;
-};
-
-/* Callback used for the result of the alarm notification dialog */
-static void
-display_notification_cb (AlarmNotifyResult result, int snooze_mins, gpointer data)
-{
- struct alarm_notify_closure *c;
-
- c = data;
-
- switch (result) {
- case ALARM_NOTIFY_CLOSE:
- break;
-
- case ALARM_NOTIFY_SNOOZE:
- snooze (c->gcal, c->ico, c->occur, snooze_mins, FALSE);
- break;
-
- case ALARM_NOTIFY_EDIT:
- edit (c->gcal, c->ico);
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- ical_object_unref (c->ico);
- g_free (c);
-}
-
-/* Present a display notification of an alarm trigger */
-static void
-display_notification (time_t trigger, time_t occur, iCalObject *ico, GnomeCalendar *gcal)
-{
- gboolean result;
- struct alarm_notify_closure *c;
-
- ical_object_ref (ico);
-
- c = g_new (struct alarm_notify_closure, 1);
- c->gcal = gcal;
- c->ico = ico;
- c->occur = occur;
-
- result = alarm_notify_dialog (trigger, occur, ico, display_notification_cb, c);
- if (!result) {
- g_message ("display_notification(): could not display the alarm notification dialog");
- g_free (c);
- ical_object_unref (ico);
- }
-}
-
-/* Present an audible notification of an alarm trigger */
-static void
-audio_notification (time_t trigger, time_t occur, iCalObject *ico, GnomeCalendar *gcal)
-{
- g_message ("AUDIO NOTIFICATION!");
- /* FIXME */
-}
-
-struct trigger_alarm_closure {
- GnomeCalendar *gcal;
- char *uid;
- enum AlarmType type;
- time_t occur;
-};
-
-/* Callback function used when an alarm is triggered */
-static void
-trigger_alarm_cb (gpointer alarm_id, time_t trigger, gpointer data)
-{
- struct trigger_alarm_closure *c;
- iCalObject *ico;
- CalClientGetStatus status;
- ObjectAlarms *oa;
- GList *l;
-
- c = data;
-
- /* Fetch the object */
-
- status = cal_client_get_object (c->gcal->client, c->uid, &ico);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* Go on */
- break;
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- case CAL_CLIENT_GET_NOT_FOUND:
- g_message ("trigger_alarm_cb(): syntax error in fetched object");
- return;
- }
-
- g_assert (ico != NULL);
-
- /* Present notification */
-
- switch (c->type) {
- case ALARM_MAIL:
- g_assert (ico->malarm.enabled);
- mail_notification (ico->malarm.data, ico->summary, c->occur);
- break;
-
- case ALARM_PROGRAM:
- g_assert (ico->palarm.enabled);
- program_notification (ico->palarm.data, FALSE);
- break;
-
- case ALARM_DISPLAY:
- g_assert (ico->dalarm.enabled);
- display_notification (trigger, c->occur, ico, c->gcal);
- break;
-
- case ALARM_AUDIO:
- g_assert (ico->aalarm.enabled);
- audio_notification (trigger, c->occur, ico, c->gcal);
- break;
- }
-
- /* Remove the alarm from the hash table */
-
- oa = g_hash_table_lookup (c->gcal->alarms, ico->uid);
- g_assert (oa != NULL);
-
- l = g_list_find (oa->alarm_ids, alarm_id);
- g_assert (l != NULL);
-
- oa->alarm_ids = g_list_remove_link (oa->alarm_ids, l);
- g_list_free_1 (l);
-
- if (!oa->alarm_ids) {
- g_hash_table_remove (c->gcal->alarms, ico->uid);
- g_free (oa->uid);
- g_free (oa);
- }
-
- ical_object_unref (ico);
-}
-
-/* Frees a struct trigger_alarm_closure */
-static void
-free_trigger_alarm_closure (gpointer data)
-{
- struct trigger_alarm_closure *c;
-
- c = data;
- g_free (c->uid);
- g_free (c);
-}
-
-/* Queues the specified alarm */
-static void
-setup_alarm (GnomeCalendar *cal, CalAlarmInstance *ai)
-{
- struct trigger_alarm_closure *c;
- gpointer alarm;
- ObjectAlarms *oa;
-
- c = g_new (struct trigger_alarm_closure, 1);
- c->gcal = cal;
- c->uid = g_strdup (ai->uid);
- c->type = ai->type;
- c->occur = ai->occur;
-
- alarm = alarm_add (ai->trigger, trigger_alarm_cb, c, free_trigger_alarm_closure);
- if (!alarm) {
- g_message ("setup_alarm(): Could not set up alarm");
- g_free (c->uid);
- g_free (c);
- return;
- }
-
- oa = g_hash_table_lookup (cal->alarms, ai->uid);
- if (oa)
- oa->alarm_ids = g_list_prepend (oa->alarm_ids, alarm);
- else {
- oa = g_new (ObjectAlarms, 1);
- oa->uid = g_strdup (ai->uid);
- oa->alarm_ids = g_list_prepend (NULL, alarm);
-
- g_hash_table_insert (cal->alarms, oa->uid, oa);
- }
-}
-
-static void load_alarms (GnomeCalendar *cal);
-
-/* Called nightly to refresh the day's alarms */
-static void
-midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data)
-{
- GnomeCalendar *cal;
-
- cal = GNOME_CALENDAR (data);
- cal->midnight_alarm_refresh_id = NULL;
-
- load_alarms (cal);
-}
-
-/* Loads and queues the alarms from the current time up to midnight. */
-static void
-load_alarms (GnomeCalendar *gcal)
-{
- time_t now;
- time_t end_of_day;
- GList *alarms, *l;
-
- now = time (NULL);
- end_of_day = time_day_end (now);
-
- /* Queue alarms */
-
- alarms = cal_client_get_alarms_in_range (gcal->client, now, end_of_day);
-
- for (l = alarms; l; l = l->next)
- setup_alarm (gcal, l->data);
-
- cal_alarm_instance_list_free (alarms);
-
- /* Queue the midnight alarm refresh */
-
- gcal->midnight_alarm_refresh_id = alarm_add (end_of_day, midnight_refresh_cb, gcal, NULL);
- if (!gcal->midnight_alarm_refresh_id) {
- g_message ("load_alarms(): Could not set up the midnight refresh alarm!");
- /* FIXME: what to do? */
- }
-}
-
-/* This tells all components to reload all calendar objects. */
-static void
-gnome_calendar_update_all (GnomeCalendar *cal)
-{
- load_alarms (cal);
-
- e_day_view_update_all_events (E_DAY_VIEW (cal->day_view));
- e_day_view_update_all_events (E_DAY_VIEW (cal->work_week_view));
- e_week_view_update_all_events (E_WEEK_VIEW (cal->week_view));
- e_week_view_update_all_events (E_WEEK_VIEW (cal->month_view));
-
-#if 0
- gncal_todo_update (GNCAL_TODO (cal->todo), NULL, TRUE);
-#endif
- gnome_calendar_tag_calendar (cal, cal->gtk_calendar);
-}
-
-/* Removes any queued alarms for the specified UID */
-static void
-remove_alarms_for_object (GnomeCalendar *gcal, const char *uid)
-{
- ObjectAlarms *oa;
- GList *l;
-
- oa = g_hash_table_lookup (gcal->alarms, uid);
- if (!oa)
- return;
-
- for (l = oa->alarm_ids; l; l = l->next) {
- gpointer alarm_id;
-
- alarm_id = l->data;
- alarm_remove (alarm_id);
- }
-
- g_hash_table_remove (gcal->alarms, uid);
-
- g_free (oa->uid);
- g_list_free (oa->alarm_ids);
- g_free (oa);
-}
-
-/* Adds today's alarms for the specified object */
-static void
-add_alarms_for_object (GnomeCalendar *gcal, const char *uid)
-{
- GList *alarms;
- gboolean result;
- time_t now, end_of_day;
- GList *l;
-
- now = time (NULL);
- end_of_day = time_day_end (now);
-
- result = cal_client_get_alarms_for_object (gcal->client, uid, now, end_of_day, &alarms);
- if (!result) {
- /* FIXME: should we warn here, or is it OK if the object
- * disappeared in the meantime?
- */
- return;
- }
-
- for (l = alarms; l; l = l->next)
- setup_alarm (gcal, l->data);
-
- cal_alarm_instance_list_free (alarms);
-}
-
-static void
-gnome_calendar_object_updated_cb (GtkWidget *cal_client,
- const char *uid,
- GnomeCalendar *gcal)
-{
- g_message ("gnome-cal: got object changed_cb, uid='%s'",
- uid?uid:"<NULL>");
-
- remove_alarms_for_object (gcal, uid);
- add_alarms_for_object (gcal, uid);
-
- /* FIXME: do we really want each view to reload the event itself?
- Maybe we should keep track of events globally, maybe with ref
- counts. We also need to sort out where they get freed. */
- e_day_view_update_event (E_DAY_VIEW (gcal->day_view), uid);
- e_day_view_update_event (E_DAY_VIEW (gcal->work_week_view), uid);
- e_week_view_update_event (E_WEEK_VIEW (gcal->week_view), uid);
- e_week_view_update_event (E_WEEK_VIEW (gcal->month_view), uid);
-
-#if 0
- gncal_todo_update (GNCAL_TODO (gcal->todo), NULL, TRUE);
-#endif
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
-}
-
-
-static void
-gnome_calendar_object_removed_cb (GtkWidget *cal_client,
- const char *uid,
- GnomeCalendar *gcal)
-{
- g_message ("gnome-cal: got object removed _cb, uid='%s'",
- uid?uid:"<NULL>");
-
- remove_alarms_for_object (gcal, uid);
-
- e_day_view_remove_event (E_DAY_VIEW (gcal->day_view), uid);
- e_day_view_remove_event (E_DAY_VIEW (gcal->work_week_view), uid);
- e_week_view_remove_event (E_WEEK_VIEW (gcal->week_view), uid);
- e_week_view_remove_event (E_WEEK_VIEW (gcal->month_view), uid);
-
-#if 0
- gncal_todo_update (GNCAL_TODO (gcal->todo), NULL, CHANGE_ALL);
-#endif
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
-}
-
-
-GtkWidget *
-gnome_calendar_new (char *title)
-{
- GtkWidget *retval;
- GnomeCalendar *gcal;
-
- retval = gtk_type_new (gnome_calendar_get_type ());
-
- gcal = GNOME_CALENDAR (retval);
-
- gcal->selection_start_time = time_day_begin (time (NULL));
- gcal->selection_end_time = time_add_day (gcal->selection_start_time, 1);
- gcal->client = cal_client_new ();
-
- setup_widgets (gcal);
-
- gnome_calendar_set_view (gcal, "dayview");
-
- gtk_signal_connect (GTK_OBJECT (gcal->client), "obj_updated",
- gnome_calendar_object_updated_cb, gcal);
- gtk_signal_connect (GTK_OBJECT (gcal->client), "obj_removed",
- gnome_calendar_object_removed_cb, gcal);
-
- return retval;
-}
-
-typedef struct
-{
- GnomeCalendar *gcal;
- char *uri;
- GnomeCalendarOpenMode gcom;
- guint signal_handle;
-} load_or_create_data;
-
-
-static void
-gnome_calendar_load_cb (CalClient *cal_client,
- CalClientLoadStatus status,
- load_or_create_data *locd)
-{
- g_return_if_fail (locd);
- g_return_if_fail (GNOME_IS_CALENDAR (locd->gcal));
-
- switch (status) {
- case CAL_CLIENT_LOAD_SUCCESS:
- gnome_calendar_update_all (locd->gcal);
- g_message ("gnome_calendar_load_cb: success");
- break;
-
- case CAL_CLIENT_LOAD_ERROR:
- g_message ("gnome_calendar_load_cb: load error");
- if (locd->gcom == CALENDAR_OPEN_OR_CREATE) {
- g_message ("gnome_calendar_load_cb: trying create...");
- /* FIXME: connect to the cal_loaded signal of the
- * CalClient and get theasynchronous notification
- * properly! */
- /*gtk_signal_connect (GTK_OBJECT (gcal->client),
- "cal_loaded",
- gnome_calendar_create_cb, gcal);*/
-
- gtk_signal_disconnect (GTK_OBJECT (locd->gcal->client),
- locd->signal_handle);
-
- cal_client_create_calendar (locd->gcal->client,
- locd->uri);
- gnome_calendar_update_all (locd->gcal);
- }
- break;
-
- case CAL_CLIENT_LOAD_IN_USE:
- /* FIXME: what to do? */
- g_message ("gnome_calendar_load_cb: in use");
- break;
-
- case CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED:
- /* FIXME: what to do? */
- g_message ("gnome_calendar_load_cb(): method not supported");
- break;
-
- default:
- g_message ("gnome_calendar_load_cb(): unhandled result code %d!", (int) status);
- g_assert_not_reached ();
- }
-
- g_free (locd->uri);
- g_free (locd);
-}
-
-
-int
-gnome_calendar_open (GnomeCalendar *gcal,
- char *file,
- GnomeCalendarOpenMode gcom)
-{
- load_or_create_data *locd;
-
- g_return_val_if_fail (gcal != NULL, 0);
- g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0);
- g_return_val_if_fail (file != NULL, 0);
-
- locd = g_new0 (load_or_create_data, 1);
- locd->gcal = gcal;
- locd->uri = g_strdup (file);
- locd->gcom = gcom;
-
- locd->signal_handle = gtk_signal_connect (GTK_OBJECT (gcal->client),
- "cal_loaded",
- gnome_calendar_load_cb,
- locd);
-
- if (cal_client_load_calendar (gcal->client, file) == FALSE){
- g_message ("Error loading calendar: %s", file);
- return 0;
- }
-
- return 1;
-}
-
-static void
-stop_beeping (GtkObject* object, gpointer data)
-{
- guint timer_tag, beep_tag;
- timer_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "timer_tag"));
- beep_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "beep_tag"));
-
- if (beep_tag > 0) {
- gtk_timeout_remove (beep_tag);
- gtk_object_set_data (object, "beep_tag", GINT_TO_POINTER (0));
- }
- if (timer_tag > 0) {
- gtk_timeout_remove (timer_tag);
- gtk_object_set_data (object, "timer_tag", GINT_TO_POINTER (0));
- }
-}
-
-static gint
-start_beeping (gpointer data)
-{
- gdk_beep ();
-
- return TRUE;
-}
-
-static gint
-timeout_beep (gpointer data)
-{
- stop_beeping (data, NULL);
- return FALSE;
-}
-
-#if 0
-
-void
-calendar_notify (time_t activation_time, CalendarAlarm *which, void *data)
-{
- iCalObject *ico = data;
- guint beep_tag, timer_tag;
- int ret;
- gchar* snooze_button = (enable_snooze ? _("Snooze") : NULL);
- time_t now, diff;
-
- if (&ico->aalarm == which){
- time_t app = ico->aalarm.trigger + ico->aalarm.offset;
- GtkWidget *w;
- char *msg;
-
- msg = g_strconcat (_("Reminder of your appointment at "),
- ctime (&app), "`",
- ico->summary, "'", NULL);
-
- /* Idea: we need Snooze option :-) */
- w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, _("Ok"), snooze_button, NULL);
- beep_tag = gtk_timeout_add (1000, start_beeping, NULL);
- if (enable_aalarm_timeout)
- timer_tag = gtk_timeout_add (audio_alarm_timeout*1000,
- timeout_beep, w);
- else
- timer_tag = 0;
- gtk_object_set_data (GTK_OBJECT (w), "timer_tag",
- GINT_TO_POINTER (timer_tag));
- gtk_object_set_data (GTK_OBJECT (w), "beep_tag",
- GINT_TO_POINTER (beep_tag));
- gtk_widget_ref (w);
- gtk_window_set_modal (GTK_WINDOW (w), FALSE);
- ret = gnome_dialog_run (GNOME_DIALOG (w));
- switch (ret) {
- case 1:
- stop_beeping (GTK_OBJECT (w), NULL);
- now = time (NULL);
- diff = now - which->trigger;
- which->trigger = which->trigger + diff + snooze_secs;
- which->offset = which->offset - diff - snooze_secs;
- alarm_add (which, &calendar_notify, data);
- break;
- default:
- stop_beeping (GTK_OBJECT (w), NULL);
- break;
- }
-
- gtk_widget_unref (w);
- return;
- }
-
- if (&ico->palarm == which){
- execute (ico->palarm.data, 0);
- return;
- }
-
- if (&ico->malarm == which){
- time_t app = ico->malarm.trigger + ico->malarm.offset;
-
- mail_notify (ico->malarm.data, ico->summary, app);
- return;
- }
-
- if (&ico->dalarm == which){
- time_t app = ico->dalarm.trigger + ico->dalarm.offset;
- GtkWidget *w;
- char *msg;
-
- if (beep_on_display)
- gdk_beep ();
- msg = g_strconcat (_("Reminder of your appointment at "),
- ctime (&app), "`",
- ico->summary, "'", NULL);
- w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO,
- _("Ok"), snooze_button, NULL);
- gtk_window_set_modal (GTK_WINDOW (w), FALSE);
- ret = gnome_dialog_run (GNOME_DIALOG (w));
- switch (ret) {
- case 1:
- now = time (NULL);
- diff = now - which->trigger;
- which->trigger = which->trigger + diff + snooze_secs;
- which->offset = which->offset - diff - snooze_secs;
- alarm_add (which, &calendar_notify, data);
- break;
- default:
- break;
- }
-
- return;
- }
-}
-
-#endif
-
-/* Marks the specified range in a GtkCalendar */
-static void
-mark_gtk_calendar_day (GtkCalendar *calendar, time_t start, time_t end)
-{
- time_t t;
-
- t = time_day_begin (start);
-
- do {
- struct tm tm;
-
- tm = *localtime (&t);
- gtk_calendar_mark_day (calendar, tm.tm_mday);
-
- t = time_day_end (t);
- } while (t < end);
-}
-
-/*
- * Tags the dates with appointments in a GtkCalendar based on the
- * GnomeCalendar contents
- */
-void
-gnome_calendar_tag_calendar (GnomeCalendar *cal, GtkCalendar *gtk_cal)
-{
- time_t month_begin, month_end;
- GList *cois, *l;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (cal));
- g_return_if_fail (gtk_cal != NULL);
- g_return_if_fail (GTK_IS_CALENDAR (gtk_cal));
-
- /* If the GtkCalendar isn't visible, we just return. */
- if (!GTK_WIDGET_VISIBLE (cal->gtk_calendar))
- return;
-
- month_begin = time_from_day (gtk_cal->year, gtk_cal->month, 1);
- if (month_begin == -1) {
- g_message ("gnome_calendar_tag_calendar(): Generated invalid month begin!");
- return;
- }
-
- month_end = time_month_end (month_begin);
- if (month_end == -1) {
- g_message ("gnome_calendar_tag_calendar(): Generated invalid month end!");
- return;
- }
-
- gtk_calendar_freeze (gtk_cal);
- gtk_calendar_clear_marks (gtk_cal);
-
- cois = cal_client_get_events_in_range (cal->client, month_begin,
- month_end);
-
- for (l = cois; l; l = l->next) {
- CalObjInstance *coi = l->data;
- time_t start, end;
-
- start = MAX (coi->start, month_begin);
- end = MIN (coi->end, month_end);
-
- if (start > end)
- continue;
-
- /* Clip the occurrence's start and end times to the month's limits */
- mark_gtk_calendar_day (gtk_cal, start, end);
- }
-
- cal_obj_instance_list_free (cois);
-
- gtk_calendar_thaw (gtk_cal);
-}
-
-/* This is called when the day begin & end times, the AM/PM flag, or the
- week_starts_on_monday flags are changed.
- FIXME: Which of these options do we want the new views to support? */
-void
-gnome_calendar_time_format_changed (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gtk_calendar_display_options (gcal->gtk_calendar,
- (week_starts_on_monday
- ? (gcal->gtk_calendar->display_flags
- | GTK_CALENDAR_WEEK_START_MONDAY)
- : (gcal->gtk_calendar->display_flags
- & ~GTK_CALENDAR_WEEK_START_MONDAY)));
-}
-
-/* This is called when any of the color settings are changed.
- FIXME: Need to update for the new views. */
-void
-gnome_calendar_colors_changed (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- todo_style_changed = 1;
-#if 0
- gncal_todo_update (GNCAL_TODO (gcal->todo), NULL, 0);
-#endif
-}
-
-void
-gnome_calendar_todo_properties_changed (GnomeCalendar *gcal)
-{
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- todo_style_changed = 1;
-#if 0
- gncal_todo_update (GNCAL_TODO (gcal->todo), NULL, 0);
-#endif
-}
-
-
-void
-gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
- time_t start_time,
- time_t end_time)
-{
- gcal->selection_start_time = start_time;
- gcal->selection_end_time = end_time;
-
- gnome_calendar_update_gtk_calendar (gcal);
-}
-
-/* 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);
-}
-
-/* Callback used when an event editor dialog is closed */
-static void
-editor_closed_cb (EventEditor *ee, gpointer data)
-{
- gtk_object_unref (GTK_OBJECT (ee));
-}
-
-/* Callback used when an event editor requests that an object be saved */
-static void
-save_ical_object_cb (EventEditor *ee, iCalObject *ico, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
- if (!cal_client_update_object (gcal->client, ico))
- g_message ("save_ical_object_cb(): Could not update the object!");
-}
-
-void
-gnome_calendar_edit_object (GnomeCalendar *gcal, iCalObject *ico)
-{
- EventEditor *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 ();
- 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);
-
- gtk_signal_connect (GTK_OBJECT (ee), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), gcal);
-
- gtk_signal_connect (GTK_OBJECT (ee), "save_ical_object",
- GTK_SIGNAL_FUNC (save_ical_object_cb), gcal);
-
- event_editor_set_ical_object (EVENT_EDITOR (ee), ico);
- }
-
- event_editor_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
- this or choose a more appropriate time. */
-void
-gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
- time_t *start_time,
- time_t *end_time)
-{
- GtkWidget *page;
-
- page = get_current_page (gcal);
-
- if (page == gcal->day_view
- || page == gcal->work_week_view)
- e_day_view_get_selected_time_range (E_DAY_VIEW (page),
- start_time, end_time);
- else if (page == gcal->week_view
- || page == gcal->month_view)
- e_week_view_get_selected_time_range (E_WEEK_VIEW (page),
- start_time, end_time);
- else {
- g_warning ("My penguin is gone!");
- g_assert_not_reached ();
- }
-}
-
-
-
-/* This updates the month shown and the day selected in the calendar, if
- necessary. */
-static void
-gnome_calendar_update_gtk_calendar (GnomeCalendar *gcal)
-{
- GDate date;
- guint current_year, current_month, current_day;
- guint new_year, new_month, new_day;
- gboolean set_day = FALSE;
-
- /* If the GtkCalendar isn't visible, we just return. */
- if (!GTK_WIDGET_VISIBLE (gcal->gtk_calendar))
- return;
-
- gtk_calendar_get_date (gcal->gtk_calendar, &current_year,
- &current_month, &current_day);
-
- g_date_clear (&date, 1);
- g_date_set_time (&date, gcal->selection_start_time);
- new_year = g_date_year (&date);
- new_month = g_date_month (&date) - 1;
- new_day = g_date_day (&date);
-
- /* Block the "day_selected" signal while we update the calendar. */
- gtk_signal_handler_block (GTK_OBJECT (gcal->gtk_calendar),
- gcal->day_selected_id);
-
- /* If the year & month don't match, update it. */
- if (new_year != current_year || new_month != current_month) {
- /* FIXME: GtkCalendar bug workaround. If we select a month
- which has less days than the currently selected day, it
- causes a problem next time we set the day. */
- if (current_day > 28) {
- gtk_calendar_select_day (gcal->gtk_calendar, 28);
- set_day = TRUE;
- }
- gtk_calendar_select_month (gcal->gtk_calendar, new_month,
- new_year);
- }
-
- /* If the day doesn't match, update it. */
- if (new_day != current_day || set_day)
- gtk_calendar_select_day (gcal->gtk_calendar, new_day);
-
- gtk_signal_handler_unblock (GTK_OBJECT (gcal->gtk_calendar),
- gcal->day_selected_id);
-}
-
-static void
-gnome_calendar_on_day_selected (GtkCalendar *calendar,
- GnomeCalendar *gcal)
-{
- gint y, m, d;
- struct tm tm;
-
- gtk_calendar_get_date (calendar, &y, &m, &d);
-
- tm.tm_year = y - 1900;
- tm.tm_mon = m;
- tm.tm_mday = d;
- tm.tm_hour = 5; /* for daylight savings time fix */
- tm.tm_min = 0;
- tm.tm_sec = 0;
-
- gnome_calendar_goto (gcal, mktime (&tm));
-}
-
-
-static void
-gnome_calendar_on_month_changed (GtkCalendar *calendar,
- GnomeCalendar *gcal)
-{
- gnome_calendar_tag_calendar (gcal, gcal->gtk_calendar);
-}