/* * EventEditor widget * Copyright (C) 1998 the Free Software Foundation * * Authors: Miguel de Icaza (miguel@kernel.org) * Federico Mena (quartic@gimp.org) */ #include #include #include #include "calendar.h" #include "eventedit.h" #include "main.h" #include "timeutil.h" static void event_editor_class_init (EventEditorClass *class); static void event_editor_init (EventEditor *ee); static void event_editor_destroy (GtkObject *object); /* 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 * adjust (GtkWidget *w, gfloat x, gfloat y, gfloat xs, gfloat ys) { GtkWidget *a = gtk_alignment_new (x, y, xs, ys); gtk_container_add (GTK_CONTAINER (a), w); return a; } static 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) static void ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y) { GtkWidget *entry; alarm->w_enabled = gtk_check_button_new_with_label (str); gtk_signal_connect (GTK_OBJECT (alarm->w_enabled), "toggled", GTK_SIGNAL_FUNC (alarm_toggle), alarm); 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); gtk_table_attach (table, alarm->w_count, 1, 2, y, y+1, FS, FS, 0, 0); alarm->w_timesel = timesel_new (); 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 : ""); 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); break; default: break; } gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (alarm->w_enabled), alarm->enabled); ee_alarm_setting (alarm, alarm->enabled); } 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); ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->aalarm, ALARM_AUDIO, 2); ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->palarm, ALARM_PROGRAM, 3); ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->malarm, ALARM_MAIL, 4); 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 */ ical->recur->_enddate = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ed_end_on)); 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, CHANGE_ALL); save_default_calendar (ee->gnome_cal); ee->ical->new = 0; } static void ee_cancel (GtkWidget *widget, EventEditor *ee) { if (ee->ical->new) { ical_object_destroy (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_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; } /* * Load the contents in a delayed fashion, as the GtkText widget needs it */ static void ee_fill_summary (GtkWidget *widget, EventEditor *ee) { int pos = 0; gtk_editable_insert_text (GTK_EDITABLE (ee->general_summary), ee->ical->summary, strlen (ee->ical->summary), &pos); gtk_text_thaw (GTK_TEXT (ee->general_summary)); } enum { OWNER_LINE, DESC_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 ? ee->ical->organizer : _("?")); 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); l = gtk_label_new (_("Summary:")); gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, DESC_LINE, DESC_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); ee->general_summary = gtk_text_new (NULL, NULL); gtk_text_freeze (GTK_TEXT (ee->general_summary)); gtk_signal_connect (GTK_OBJECT (ee->general_summary), "realize", GTK_SIGNAL_FUNC (ee_fill_summary), ee); gtk_widget_set_usize (ee->general_summary, 0, 60); gtk_text_set_editable (GTK_TEXT (ee->general_summary), 1); gtk_table_attach (GTK_TABLE (ee->general_table), ee->general_summary, 0, 1, SUMMARY_LINE, SUMMARY_LINE+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); 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); gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), 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); gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("Every")), 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); gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("Every")), 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); gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), 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_append_page (notebook, none, gtk_label_new ("")); gtk_notebook_append_page (notebook, daily, gtk_label_new ("")); gtk_notebook_append_page (notebook, weekly, gtk_label_new ("")); gtk_notebook_append_page (notebook, monthly, gtk_label_new ("")); gtk_notebook_append_page (notebook, yearly, gtk_label_new ("")); gtk_notebook_set_show_tabs (notebook, FALSE); 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) enddate = ee->ical->recur->enddate; 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; gtk_window_set_title (GTK_WINDOW (ee), _("Create new appointment")); 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) ee->ical->user_data = NULL; /* we are no longer editing it */ } 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; } 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); 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); gtk_widget_show (ee); }