/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ #include #include #include #include #include typedef struct { GladeXML *gui; GtkWidget *dialog; GnomeCalendar *gnome_cal; iCalObject *ical; } EventEditorDialog; extern int day_begin, day_end; extern char *user_name; extern int am_pm_flag; extern int week_starts_on_monday; static void fill_in_dialog_from_ical (EventEditorDialog *dialog) { iCalObject *ical = dialog->ical; GladeXML *gui = dialog->gui; store_to_editable (gui, "general-owner", dialog->ical->organizer->addr ? dialog->ical->organizer->addr : _("?")); store_to_editable (gui, "general-summary", ical->summary); /* start and end time */ store_to_gnome_dateedit (gui, "start-time", ical->dtstart); store_to_gnome_dateedit (gui, "end-time", ical->dtend); /* all day event checkbox */ if (get_time_t_hour (ical->dtstart) <= day_begin && get_time_t_hour (ical->dtend) >= day_end) store_to_toggle (gui, "all-day-event", TRUE); else store_to_toggle (gui, "all-day-event", FALSE); /* alarms */ store_to_toggle (gui, "alarm-display", ical->dalarm.enabled); store_to_toggle (gui, "alarm-program", ical->palarm.enabled); store_to_toggle (gui, "alarm-audio", ical->aalarm.enabled); store_to_toggle (gui, "alarm-mail", ical->malarm.enabled); /* alarm counts */ store_to_spin (gui, "alarm-display-amount", ical->dalarm.count); store_to_spin (gui, "alarm-audio-amount", ical->aalarm.count); store_to_spin (gui, "alarm-program-amount", ical->palarm.count); store_to_spin (gui, "alarm-mail-amount", ical->malarm.count); store_to_alarm_unit (gui, "alarm-display-unit", ical->dalarm.units); store_to_alarm_unit (gui, "alarm-audio-unit", ical->aalarm.units); store_to_alarm_unit (gui, "alarm-program-unit", ical->palarm.units); store_to_alarm_unit (gui, "alarm-mail-unit", ical->malarm.units); store_to_editable (gui, "run-program", ical->palarm.data); store_to_editable (gui, "mail-to", ical->malarm.data); /* classification */ if (strcmp (ical->class, "PUBLIC") == 0) store_to_toggle (gui, "classification-public", TRUE); if (strcmp (ical->class, "PRIVATE") == 0) store_to_toggle (gui, "classification-private", TRUE); if (strcmp (ical->class, "CONFIDENTIAL") == 0) store_to_toggle (gui, "classification-confidential", TRUE); /* recurrence rules */ if (! ical->recur) return; switch (ical->recur->type) { case RECUR_DAILY: store_to_toggle (gui, "recurrence-rule-daily", TRUE); store_to_spin (gui, "recurrence-rule-daily-days", ical->recur->interval); break; case RECUR_WEEKLY: store_to_toggle (gui, "recurrence-rule-weekly", TRUE); store_to_spin (gui, "recurrence-rule-weekly-weeks", ical->recur->interval); if (ical->recur->weekday & (1 << 0)) store_to_toggle (gui, "recurrence-rule-weekly-sun", TRUE); if (ical->recur->weekday & (1 << 1)) store_to_toggle (gui, "recurrence-rule-weekly-mon", TRUE); if (ical->recur->weekday & (1 << 2)) store_to_toggle (gui, "recurrence-rule-weekly-tue", TRUE); if (ical->recur->weekday & (1 << 3)) store_to_toggle (gui, "recurrence-rule-weekly-wed", TRUE); if (ical->recur->weekday & (1 << 4)) store_to_toggle (gui, "recurrence-rule-weekly-thu", TRUE); if (ical->recur->weekday & (1 << 5)) store_to_toggle (gui, "recurrence-rule-weekly-fri", TRUE); if (ical->recur->weekday & (1 << 6)) store_to_toggle (gui, "recurrence-rule-weekly-sat", TRUE); break; case RECUR_MONTHLY_BY_DAY: store_to_toggle (gui, "recurrence-rule-monthly", TRUE); store_to_toggle (gui, "recurrence-rule-monthly-on-day", TRUE); store_to_spin (gui, "recurrence-rule-monthly-day", ical->recur->u.month_day); store_to_spin (gui, "recurrence-rule-monthly-every-n-months", ical->recur->interval); break; case RECUR_MONTHLY_BY_POS: store_to_toggle (gui, "recurrence-rule-monthly", TRUE); store_to_toggle (gui, "recurrence-rule-monthly-weekday", TRUE); store_to_option (gui, "recurrence-rule-monthly-week", ical->recur->u.month_pos); store_to_option (gui, "recurrence-rule-monthly-day", ical->recur->weekday); store_to_spin (gui, "recurrence-rule-monthly-every-n-months", ical->recur->interval); break; case RECUR_YEARLY_BY_DAY: case RECUR_YEARLY_BY_MONTH: store_to_toggle (gui, "recurrence-rule-yearly", TRUE); store_to_spin (gui, "recurrence-rule-yearly-every-n-years", ical->recur->interval); break; } /* recurrence ending date */ if (ical->recur->duration != 0) { store_to_toggle (gui, "recurrence-ending-date-end-after", TRUE); store_to_spin (gui, "recurrence-ending-date-end-after-count", ical->recur->duration); } else if (ical->recur->enddate != 0) { store_to_toggle (gui, "recurrence-ending-date-end-on", TRUE); /* Shorten by one day, as we store end-on date a day ahead */ store_to_gnome_dateedit (gui, "recurrence-ending-date-end-on-date", ical->recur->enddate - 86400); } /* else repeat forever */ } static void fill_in_dialog_from_defaults (EventEditorDialog *dialog) { time_t now = time (NULL); time_t soon = time_add_minutes (now, 30); store_to_editable (dialog->gui, "general-owner", "?"); /* start and end time */ store_to_gnome_dateedit (dialog->gui, "start-time", now); store_to_gnome_dateedit (dialog->gui, "end-time", soon); } static void dialog_to_ical (EventEditorDialog *dialog) { iCalObject *ical = dialog->ical; gboolean all_day_event; GladeXML *gui = dialog->gui; /* general event information */ if (ical->summary) g_free (ical->summary); ical->summary = extract_from_editable (gui, "general-summary"); ical->dtstart = extract_from_gnome_dateedit (gui, "start-time"); ical->dtend = extract_from_gnome_dateedit (gui, "end-time"); all_day_event = extract_from_toggle (gui, "all-day-event"); ical->dalarm.enabled = extract_from_toggle (gui, "alarm-display"); ical->aalarm.enabled = extract_from_toggle (gui, "alarm-program"); ical->palarm.enabled = extract_from_toggle (gui, "alarm-audio"); ical->malarm.enabled = extract_from_toggle (gui, "alarm-mail"); ical->dalarm.count = extract_from_spin (gui, "alarm-display-amount"); ical->aalarm.count = extract_from_spin (gui, "alarm-audio-amount"); ical->palarm.count = extract_from_spin (gui, "alarm-program-amount"); ical->malarm.count = extract_from_spin (gui, "alarm-mail-amount"); ical->dalarm.units = extract_from_alarm_unit (gui, "alarm-display-unit"); ical->aalarm.units = extract_from_alarm_unit (gui, "alarm-audio-unit"); ical->palarm.units = extract_from_alarm_unit (gui, "alarm-program-unit"); ical->malarm.units = extract_from_alarm_unit (gui, "alarm-mail-unit"); ical->palarm.data = g_strdup (extract_from_editable (gui, "run-program")); ical->malarm.data = g_strdup (extract_from_editable (gui, "mail-to")); if (extract_from_toggle (gui, "classification-public")) ical->class = g_strdup ("PUBLIC"); else if (extract_from_toggle (gui, "classification-private")) ical->class = g_strdup ("PRIVATE"); else /* "classification-confidential" */ ical->class = g_strdup ("CONFIDENTIAL"); /* recurrence information */ if (extract_from_toggle (gui, "recurrence-rule-none")) return; /* done */ if (!ical->recur) ical->recur = g_new0 (Recurrence, 1); if (extract_from_toggle (gui, "recurrence-rule-daily")) { ical->recur->type = RECUR_DAILY; ical->recur->interval = extract_from_spin (gui, "recurrence-rule-daily-days"); } if (extract_from_toggle (gui, "recurrence-rule-weekly")) { ical->recur->type = RECUR_WEEKLY; ical->recur->interval = extract_from_spin (gui, "recurrence-rule-weekly-weeks"); ical->recur->weekday = 0; if (extract_from_toggle (gui, "recurrence-rule-weekly-sun")) ical->recur->weekday |= 1 << 0; if (extract_from_toggle (gui, "recurrence-rule-weekly-mon")) ical->recur->weekday |= 1 << 1; if (extract_from_toggle (gui, "recurrence-rule-weekly-tue")) ical->recur->weekday |= 1 << 2; if (extract_from_toggle (gui, "recurrence-rule-weekly-wed")) ical->recur->weekday |= 1 << 3; if (extract_from_toggle (gui, "recurrence-rule-weekly-thu")) ical->recur->weekday |= 1 << 4; if (extract_from_toggle (gui, "recurrence-rule-weekly-fri")) ical->recur->weekday |= 1 << 5; if (extract_from_toggle (gui, "recurrence-rule-weekly-sat")) ical->recur->weekday |= 1 << 6; } if (extract_from_toggle (gui, "recurrence-rule-monthly")) { if (extract_from_toggle (gui, "recurrence-rule-monthly-on-day")) { /* by day of in the month (ex: the 5th) */ ical->recur->type = RECUR_MONTHLY_BY_DAY; ical->recur->u.month_day = extract_from_spin (gui, "recurrence-rule-monthly-day"); } else { /* "recurrence-rule-monthly-weekday" is TRUE */ /* by position on the calender (ex: 2nd monday) */ ical->recur->type = RECUR_MONTHLY_BY_POS; ical->recur->u.month_pos = extract_from_option (gui, "recurrence-rule-monthly-week"); ical->recur->weekday = extract_from_option (gui, "recurrence-rule-monthly-day"); } ical->recur->interval = extract_from_spin (gui, "recurrence-rule-monthly-every-n-months"); } if (extract_from_toggle (gui, "recurrence-rule-yearly")) { ical->recur->type = RECUR_YEARLY_BY_DAY; ical->recur->interval = extract_from_spin (gui, "recurrence-rule-yearly-every-n-years"); /* FIXME: need to specify anything else? I am assuming the code will look at the dtstart * to figure out when to recur. - Federico */ } /* recurrence ending date */ if (extract_from_toggle (gui, "recurrence-ending-date-repeat-forever")) { ical->recur->_enddate = 0; ical->recur->enddate = 0; ical->recur->duration = 0; } if (extract_from_toggle (gui, "recurrence-ending-date-end-on")) { /* 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 = extract_from_gnome_dateedit (gui, "recurrence-ending-date-end-on-date") + 86400; ical->recur->enddate = ical->recur->_enddate; ical->recur->duration = 0; } if (extract_from_toggle (gui, "recurrence-ending-date-end-after")) { ical->recur->duration = extract_from_spin (gui, "recurrence-ending-date-end-after-count"); ical_object_compute_end (ical); } } static void ee_ok (GtkWidget *widget, EventEditorDialog *dialog) { dialog_to_ical (dialog); if (dialog->ical->new) gnome_calendar_add_object (dialog->gnome_cal, dialog->ical); else gnome_calendar_object_changed (dialog->gnome_cal, dialog->ical, CHANGE_ALL); dialog->ical->new = 0; } static void ee_cancel (GtkWidget *widget, EventEditorDialog *dialog) { if (dialog->ical) { ical_object_unref (dialog->ical); dialog->ical = NULL; } } static void recurrence_toggled (GtkWidget *radio, EventEditorDialog *dialog) { GtkWidget *recurrence_rule_notebook = glade_xml_get_widget (dialog->gui, "recurrence-rule-notebook"); GtkWidget *recurrence_rule_none = glade_xml_get_widget (dialog->gui, "recurrence-rule-none"); GtkWidget *recurrence_rule_daily = glade_xml_get_widget (dialog->gui, "recurrence-rule-daily"); GtkWidget *recurrence_rule_weekly = glade_xml_get_widget (dialog->gui, "recurrence-rule-weekly"); GtkWidget *recurrence_rule_monthly = glade_xml_get_widget (dialog->gui, "recurrence-rule-monthly"); GtkWidget *recurrence_rule_yearly = glade_xml_get_widget (dialog->gui, "recurrence-rule-yearly"); if (radio == recurrence_rule_none) gtk_notebook_set_page (GTK_NOTEBOOK (recurrence_rule_notebook), 0); if (radio == recurrence_rule_daily) gtk_notebook_set_page (GTK_NOTEBOOK (recurrence_rule_notebook), 1); if (radio == recurrence_rule_weekly) gtk_notebook_set_page (GTK_NOTEBOOK (recurrence_rule_notebook), 2); if (radio == recurrence_rule_monthly) gtk_notebook_set_page (GTK_NOTEBOOK (recurrence_rule_notebook), 3); if (radio == recurrence_rule_yearly) gtk_notebook_set_page (GTK_NOTEBOOK (recurrence_rule_notebook), 4); } GtkWidget *event_editor_new (GnomeCalendar *gcal, iCalObject *ical) { EventEditorDialog *dialog = g_new0 (EventEditorDialog, 1); dialog->ical = ical; dialog->gnome_cal = gcal; printf ("glade_xml_new (%s, NULL)\n", EVOLUTION_GLADEDIR "/event-editor-dialog.glade"); dialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/event-editor-dialog.glade", NULL); dialog->dialog = glade_xml_get_widget (dialog->gui, "event-editor-dialog"); gnome_dialog_button_connect (GNOME_DIALOG (dialog->dialog), 0, GTK_SIGNAL_FUNC(ee_ok), dialog); gnome_dialog_button_connect (GNOME_DIALOG (dialog->dialog), 1, GTK_SIGNAL_FUNC(ee_cancel), dialog); { GtkWidget *recurrence_rule_none = glade_xml_get_widget (dialog->gui, "recurrence-rule-none"); GtkWidget *recurrence_rule_daily = glade_xml_get_widget (dialog->gui, "recurrence-rule-daily"); GtkWidget *recurrence_rule_weekly = glade_xml_get_widget (dialog->gui, "recurrence-rule-weekly"); GtkWidget *recurrence_rule_monthly = glade_xml_get_widget (dialog->gui, "recurrence-rule-monthly"); GtkWidget *recurrence_rule_yearly = glade_xml_get_widget (dialog->gui, "recurrence-rule-yearly"); gtk_signal_connect (GTK_OBJECT (recurrence_rule_none), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), dialog); gtk_signal_connect (GTK_OBJECT (recurrence_rule_daily), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), dialog); gtk_signal_connect (GTK_OBJECT (recurrence_rule_weekly), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), dialog); gtk_signal_connect (GTK_OBJECT (recurrence_rule_monthly), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), dialog); gtk_signal_connect (GTK_OBJECT (recurrence_rule_yearly), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), dialog); } if (ical->new) fill_in_dialog_from_defaults (dialog); else fill_in_dialog_from_ical (dialog); gnome_dialog_run (GNOME_DIALOG(dialog->dialog)); gnome_dialog_close (GNOME_DIALOG(dialog->dialog)); return dialog->dialog; } void event_editor_new_whole_day (GnomeCalendar *owner, time_t day) { } GtkWidget *make_date_edit (void) { return date_edit_new (time (NULL), TRUE); } 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))); } 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; } /* todo build some of the recur stuff by hand to take into account the start-on-monday preference? make the alarm controls insensitive until you enable them get reading and storing of all_day_event to work if you set the start time and it is after the end time, change the end time get the apply button to work right make the properties stuff unglobal figure out why alarm units aren't sticking between edits extract from and store to the ending date in the recurrence rule stuff finish the recurrence rule exceptions */