/* Orage - Calendar and alarm handler * * Copyright (c) 2005-2008 Juha Kautto (juha at xfce.org) * Copyright (c) 2004-2005 Mickael Graf (korbinus at xfce.org) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation 51 Franklin Street, 5th Floor Boston, MA 02110-1301 USA */ #ifdef HAVE_CONFIG_H # include #endif #define _XOPEN_SOURCE /* glibc2 needs this */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "functions.h" #include "mainbox.h" #include "ical-code.h" #include "event-list.h" #include "day-view.h" #include "appointment.h" #include "parameters.h" #define BORDER_SIZE 20 #define FILETYPE_SIZE 38 typedef struct _orage_category_win { GtkWidget *window; GtkWidget *vbox; GtkWidget *new_frame; GtkWidget *new_entry; GtkWidget *new_color_button; GtkWidget *new_add_button; GtkWidget *cur_frame; GtkWidget *cur_frame_vbox; GtkTooltips *tooltips; GtkAccelGroup *accelgroup; gpointer *apptw; } category_win_struct; static void refresh_categories(category_win_struct *catw); static void read_default_alarm(xfical_appt *appt); static void fill_appt_window(appt_win *apptw, char *action, char *par); /* * the previous and the following are the main functions in this file static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw) */ static GtkWidget *datetime_hbox_new(GtkWidget *date_button , GtkWidget *spin_hh, GtkWidget *spin_mm , GtkWidget *timezone_button) { GtkWidget *hbox, *space_label; hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), date_button, FALSE, FALSE, 0); space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_hh), TRUE); gtk_widget_set_size_request(spin_hh, 40, -1); gtk_box_pack_start(GTK_BOX(hbox), spin_hh, FALSE, FALSE, 0); space_label = gtk_label_new(":"); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_mm), TRUE); gtk_widget_set_size_request(spin_mm, 40, -1); gtk_box_pack_start(GTK_BOX(hbox), spin_mm, FALSE, FALSE, 0); space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), timezone_button, TRUE, TRUE, 0); return(hbox); } static GtkWidget *period_hbox_new(gboolean head_space, gboolean tail_space , GtkWidget *spin_dd, GtkWidget *dd_label , GtkWidget *spin_hh, GtkWidget *hh_label , GtkWidget *spin_mm, GtkWidget *mm_label) { GtkWidget *hbox, *space_label; hbox = gtk_hbox_new(FALSE, 0); if (head_space) { space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); } gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_dd), TRUE); gtk_box_pack_start(GTK_BOX(hbox), spin_dd, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), dd_label, FALSE, FALSE, 5); space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_hh), TRUE); gtk_widget_set_size_request(spin_hh, 40, -1); gtk_box_pack_start(GTK_BOX(hbox), spin_hh, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), hh_label, FALSE, FALSE, 5); space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spin_mm), TRUE); gtk_widget_set_size_request(spin_mm, 40, -1); gtk_box_pack_start(GTK_BOX(hbox), spin_mm, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), mm_label, FALSE, FALSE, 5); if (tail_space) { space_label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0); } return hbox; } static void mark_appointment_changed(appt_win *apptw) { if (!apptw->appointment_changed) { apptw->appointment_changed = TRUE; gtk_widget_set_sensitive(apptw->Revert, TRUE); gtk_widget_set_sensitive(apptw->File_menu_revert, TRUE); } } static void mark_appointment_unchanged(appt_win *apptw) { if (apptw->appointment_changed) { apptw->appointment_changed = FALSE; gtk_widget_set_sensitive(apptw->Revert, FALSE); gtk_widget_set_sensitive(apptw->File_menu_revert, FALSE); } } static void set_time_sensitivity(appt_win *apptw) { gboolean dur_act, allDay_act, comp_act, due_act; dur_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Dur_checkbutton)); allDay_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->AllDay_checkbutton)); comp_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Completed_checkbutton)); /* todo can be without due date, but event always has end date. * Journal has none, but we show it similarly than event */ if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_todo_rb))) due_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->End_checkbutton)); else due_act = TRUE; gtk_widget_set_sensitive(apptw->Dur_checkbutton, due_act); if (allDay_act) { gtk_widget_set_sensitive(apptw->StartTime_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->StartTime_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->StartTimezone_button, FALSE); gtk_widget_set_sensitive(apptw->EndTime_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->EndTime_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->EndTimezone_button, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_hh_label, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_mm_label, FALSE); gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->CompletedTimezone_button, FALSE); gtk_widget_set_sensitive(apptw->CompletedDate_button, comp_act); if (dur_act) { gtk_widget_set_sensitive(apptw->EndDate_button, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_dd, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_dd_label, due_act); } else { gtk_widget_set_sensitive(apptw->EndDate_button, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_dd, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_dd_label, FALSE); } } else { gtk_widget_set_sensitive(apptw->StartTime_spin_hh, TRUE); gtk_widget_set_sensitive(apptw->StartTime_spin_mm, TRUE); gtk_widget_set_sensitive(apptw->StartTimezone_button, TRUE); if (dur_act) { gtk_widget_set_sensitive(apptw->EndDate_button, FALSE); gtk_widget_set_sensitive(apptw->EndTime_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->EndTime_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->EndTimezone_button, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_dd, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_dd_label, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_hh, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_hh_label, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_mm, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_mm_label, due_act); } else { gtk_widget_set_sensitive(apptw->EndDate_button, due_act); gtk_widget_set_sensitive(apptw->EndTime_spin_hh, due_act); gtk_widget_set_sensitive(apptw->EndTime_spin_mm, due_act); gtk_widget_set_sensitive(apptw->EndTimezone_button, due_act); gtk_widget_set_sensitive(apptw->Dur_spin_dd, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_dd_label, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_hh, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_hh_label, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_mm, FALSE); gtk_widget_set_sensitive(apptw->Dur_spin_mm_label, FALSE); } gtk_widget_set_sensitive(apptw->CompletedDate_button, comp_act); gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, comp_act); gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, comp_act); gtk_widget_set_sensitive(apptw->CompletedTimezone_button, comp_act); } } static void set_repeat_sensitivity(appt_win *apptw) { gint freq, i; freq = gtk_combo_box_get_active(GTK_COMBO_BOX(apptw->Recur_freq_cb)); if (freq == XFICAL_FREQ_NONE) { gtk_widget_set_sensitive(apptw->Recur_limit_rb, FALSE); gtk_widget_set_sensitive(apptw->Recur_count_rb, FALSE); gtk_widget_set_sensitive(apptw->Recur_count_spin, FALSE); gtk_widget_set_sensitive(apptw->Recur_count_label, FALSE); gtk_widget_set_sensitive(apptw->Recur_until_rb, FALSE); gtk_widget_set_sensitive(apptw->Recur_until_button, FALSE); for (i=0; i <= 6; i++) { gtk_widget_set_sensitive(apptw->Recur_byday_cb[i], FALSE); gtk_widget_set_sensitive(apptw->Recur_byday_spin[i], FALSE); } gtk_widget_set_sensitive(apptw->Recur_int_spin, FALSE); gtk_widget_set_sensitive(apptw->Recur_int_spin_label1, FALSE); gtk_widget_set_sensitive(apptw->Recur_int_spin_label2, FALSE); } else { gtk_widget_set_sensitive(apptw->Recur_limit_rb, TRUE); gtk_widget_set_sensitive(apptw->Recur_count_rb, TRUE); if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_count_rb))) { gtk_widget_set_sensitive(apptw->Recur_count_spin, TRUE); gtk_widget_set_sensitive(apptw->Recur_count_label, TRUE); } else { gtk_widget_set_sensitive(apptw->Recur_count_spin, FALSE); gtk_widget_set_sensitive(apptw->Recur_count_label, FALSE); } gtk_widget_set_sensitive(apptw->Recur_until_rb, TRUE); if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_until_rb))) { gtk_widget_set_sensitive(apptw->Recur_until_button, TRUE); } else { gtk_widget_set_sensitive(apptw->Recur_until_button, FALSE); } for (i=0; i <= 6; i++) { gtk_widget_set_sensitive(apptw->Recur_byday_cb[i], TRUE); } if (freq == XFICAL_FREQ_MONTHLY || freq == XFICAL_FREQ_YEARLY) { for (i=0; i <= 6; i++) { gtk_widget_set_sensitive(apptw->Recur_byday_spin[i], TRUE); } } else { for (i=0; i <= 6; i++) { gtk_widget_set_sensitive(apptw->Recur_byday_spin[i], FALSE); } } gtk_widget_set_sensitive(apptw->Recur_int_spin, TRUE); gtk_widget_set_sensitive(apptw->Recur_int_spin_label1, TRUE); gtk_widget_set_sensitive(apptw->Recur_int_spin_label2, TRUE); } } static void recur_hide_show(appt_win *apptw) { if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_feature_normal_rb))) { gtk_widget_hide(apptw->Recur_byday_label); gtk_widget_hide(apptw->Recur_byday_hbox); gtk_widget_hide(apptw->Recur_byday_spin_label); gtk_widget_hide(apptw->Recur_byday_spin_hbox); } else { gtk_widget_show(apptw->Recur_byday_label); gtk_widget_show(apptw->Recur_byday_hbox); gtk_widget_show(apptw->Recur_byday_spin_label); gtk_widget_show(apptw->Recur_byday_spin_hbox); } } static void type_hide_show(appt_win *apptw) { if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_event_rb))) { gtk_label_set_text(GTK_LABEL(apptw->End_label), _("End")); gtk_widget_show(apptw->Availability_label); gtk_widget_show(apptw->Availability_cb); gtk_widget_hide(apptw->End_checkbutton); gtk_widget_hide(apptw->Completed_label); gtk_widget_hide(apptw->Completed_hbox); gtk_widget_set_sensitive(apptw->Alarm_notebook_page, TRUE); gtk_widget_set_sensitive(apptw->Alarm_tab_label, TRUE); gtk_widget_set_sensitive(apptw->Recur_notebook_page, TRUE); gtk_widget_set_sensitive(apptw->Recur_tab_label, TRUE); gtk_widget_set_sensitive(apptw->Location_label, TRUE); gtk_widget_set_sensitive(apptw->Location_entry, TRUE); gtk_widget_set_sensitive(apptw->End_label, TRUE); gtk_widget_set_sensitive(apptw->EndTime_hbox, TRUE); gtk_widget_set_sensitive(apptw->Dur_hbox, TRUE); } else if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_todo_rb))) { gtk_label_set_text(GTK_LABEL(apptw->End_label), _("Due")); gtk_widget_hide(apptw->Availability_label); gtk_widget_hide(apptw->Availability_cb); gtk_widget_show(apptw->End_checkbutton); gtk_widget_show(apptw->Completed_label); gtk_widget_show(apptw->Completed_hbox); gtk_widget_set_sensitive(apptw->Alarm_notebook_page, TRUE); gtk_widget_set_sensitive(apptw->Alarm_tab_label, TRUE); gtk_widget_set_sensitive(apptw->Recur_notebook_page, TRUE); gtk_widget_set_sensitive(apptw->Recur_tab_label, TRUE); gtk_widget_set_sensitive(apptw->Location_label, TRUE); gtk_widget_set_sensitive(apptw->Location_entry, TRUE); gtk_widget_set_sensitive(apptw->End_label, TRUE); gtk_widget_set_sensitive(apptw->EndTime_hbox, TRUE); gtk_widget_set_sensitive(apptw->Dur_hbox, TRUE); } else /* if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_journal_rb))) */ { gtk_label_set_text(GTK_LABEL(apptw->End_label), _("End")); gtk_widget_hide(apptw->Availability_label); gtk_widget_hide(apptw->Availability_cb); gtk_widget_hide(apptw->End_checkbutton); gtk_widget_hide(apptw->Completed_label); gtk_widget_hide(apptw->Completed_hbox); gtk_widget_set_sensitive(apptw->Alarm_notebook_page, FALSE); gtk_widget_set_sensitive(apptw->Alarm_tab_label, FALSE); gtk_widget_set_sensitive(apptw->Recur_notebook_page, FALSE); gtk_widget_set_sensitive(apptw->Recur_tab_label, FALSE); gtk_widget_set_sensitive(apptw->Location_label, FALSE); gtk_widget_set_sensitive(apptw->Location_entry, FALSE); gtk_widget_set_sensitive(apptw->End_label, FALSE); gtk_widget_set_sensitive(apptw->EndTime_hbox, FALSE); gtk_widget_set_sensitive(apptw->Dur_hbox, FALSE); } set_time_sensitivity(apptw); /* todo has different settings */ } static void set_sound_sensitivity(appt_win *apptw) { gboolean sound_act, repeat_act; sound_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Sound_checkbutton)); repeat_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->SoundRepeat_checkbutton)); if (sound_act) { gtk_widget_set_sensitive(apptw->Sound_entry, TRUE); gtk_widget_set_sensitive(apptw->Sound_button, TRUE); gtk_widget_set_sensitive(apptw->SoundRepeat_hbox, TRUE); gtk_widget_set_sensitive(apptw->SoundRepeat_checkbutton, TRUE); if (repeat_act) { gtk_widget_set_sensitive(apptw->SoundRepeat_spin_cnt, TRUE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_cnt_label, TRUE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_len, TRUE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_len_label, TRUE); } else { gtk_widget_set_sensitive(apptw->SoundRepeat_spin_cnt, FALSE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_cnt_label, FALSE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_len, FALSE); gtk_widget_set_sensitive(apptw->SoundRepeat_spin_len_label, FALSE); } } else { gtk_widget_set_sensitive(apptw->Sound_entry, FALSE); gtk_widget_set_sensitive(apptw->Sound_button, FALSE); gtk_widget_set_sensitive(apptw->SoundRepeat_hbox, FALSE); /* enough */ } } static void set_notify_sensitivity(appt_win *apptw) { #ifdef HAVE_NOTIFY gboolean notify_act, expire_act; notify_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_notify)); expire_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_expire_notify)); if (notify_act) { gtk_widget_set_sensitive(apptw->Display_checkbutton_expire_notify , TRUE); if (expire_act) { gtk_widget_set_sensitive(apptw->Display_spin_expire_notify, TRUE); gtk_widget_set_sensitive(apptw->Display_spin_expire_notify_label , TRUE); } else { gtk_widget_set_sensitive(apptw->Display_spin_expire_notify, FALSE); gtk_widget_set_sensitive(apptw->Display_spin_expire_notify_label , FALSE); } } else { gtk_widget_set_sensitive(apptw->Display_checkbutton_expire_notify , FALSE); gtk_widget_set_sensitive(apptw->Display_spin_expire_notify, FALSE); gtk_widget_set_sensitive(apptw->Display_spin_expire_notify_label , FALSE); } #endif } static void set_proc_sensitivity(appt_win *apptw) { gboolean proc_act; proc_act = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Proc_checkbutton)); if (proc_act) { gtk_widget_set_sensitive(apptw->Proc_entry, TRUE); } else { gtk_widget_set_sensitive(apptw->Proc_entry, FALSE); } } static void app_type_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { type_hide_show((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void on_appTitle_entry_changed_cb(GtkEditable *entry , gpointer user_data) { gchar *title, *application_name; const gchar *appointment_name; appt_win *apptw = (appt_win *)user_data; appointment_name = gtk_entry_get_text((GtkEntry *)apptw->Title_entry); application_name = _("Orage"); if (ORAGE_STR_EXISTS(appointment_name)) title = g_strdup_printf("%s - %s", appointment_name, application_name); else title = g_strdup_printf("%s", application_name); gtk_window_set_title(GTK_WINDOW(apptw->Window), (const gchar *)title); g_free(title); mark_appointment_changed((appt_win *)user_data); } static void app_time_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { set_time_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void app_recur_checkbutton_clicked_cb(GtkCheckButton *checkbutton , gpointer user_data) { set_repeat_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void app_recur_feature_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { recur_hide_show((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void app_sound_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { set_sound_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } #ifdef HAVE_NOTIFY static void app_notify_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { set_notify_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } #endif static void app_proc_checkbutton_clicked_cb(GtkCheckButton *cb , gpointer user_data) { set_proc_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void app_checkbutton_clicked_cb(GtkCheckButton *cb, gpointer user_data) { mark_appointment_changed((appt_win *)user_data); } static void refresh_dependent_data(appt_win *apptw) { if (apptw->el != NULL) refresh_el_win((el_win *)apptw->el); if (apptw->dw != NULL) refresh_day_win((day_win *)apptw->dw); orage_mark_appointments(); } static void on_appNote_buffer_changed_cb(GtkTextBuffer *b, gpointer user_data) { appt_win *apptw = (appt_win *)user_data; GtkTextIter start, end, match_start, match_end; GtkTextBuffer *tb; gchar *cdate, ctime[6], *cdatetime; struct tm *tm; tb = apptw->Note_buffer; gtk_text_buffer_get_bounds(tb, &start, &end); if (gtk_text_iter_forward_search(&start, "" , GTK_TEXT_SEARCH_TEXT_ONLY , &match_start, &match_end, &end)) { /* found it */ cdate = orage_localdate_i18(); gtk_text_buffer_delete(tb, &match_start, &match_end); gtk_text_buffer_insert(tb, &match_start, cdate, -1); } else if (gtk_text_iter_forward_search(&start, "" , GTK_TEXT_SEARCH_TEXT_ONLY , &match_start, &match_end, &end)) { /* found it */ tm = orage_localtime(); g_sprintf(ctime, "%02d:%02d", tm->tm_hour, tm->tm_min); gtk_text_buffer_delete(tb, &match_start, &match_end); gtk_text_buffer_insert(tb, &match_start, ctime, -1); } else if (gtk_text_iter_forward_search(&start, "
" , GTK_TEXT_SEARCH_TEXT_ONLY , &match_start, &match_end, &end)) { /* found it */ tm = orage_localtime(); cdate = orage_tm_date_to_i18_date(tm); g_sprintf(ctime, "%02d:%02d", tm->tm_hour, tm->tm_min); cdatetime = g_strconcat(cdate, " ", ctime, NULL); gtk_text_buffer_delete(tb, &match_start, &match_end); gtk_text_buffer_insert(tb, &match_start, cdatetime, -1); g_free(cdatetime); } mark_appointment_changed((appt_win *)user_data); } static void on_app_entry_changed_cb(GtkEditable *entry, gpointer user_data) { mark_appointment_changed((appt_win *)user_data); } static void on_freq_combobox_changed_cb(GtkComboBox *cb, gpointer user_data) { set_repeat_sensitivity((appt_win *)user_data); mark_appointment_changed((appt_win *)user_data); } static void on_app_combobox_changed_cb(GtkComboBox *cb, gpointer user_data) { mark_appointment_changed((appt_win *)user_data); } static void on_app_spin_button_changed_cb(GtkSpinButton *sb, gpointer user_data) { mark_appointment_changed((appt_win *)user_data); } static void on_appSound_button_clicked_cb(GtkButton *button, gpointer user_data) { appt_win *apptw = (appt_win *)user_data; GtkWidget *file_chooser; GtkFileFilter *filter; gchar *appSound_entry_filename; gchar *sound_file; const gchar *filetype[FILETYPE_SIZE] = { "*.aiff", "*.al", "*.alsa", "*.au", "*.auto", "*.avr", "*.cdr", "*.cvs", "*.dat", "*.vms", "*.gsm", "*.hcom", "*.la", "*.lu", "*.maud", "*.mp3", "*.nul", "*.ogg", "*.ossdsp", "*.prc", "*.raw", "*.sb", "*.sf", "*.sl", "*.smp", "*.sndt", "*.sph", "*.8svx", "*.sw", "*.txw", "*.ub", "*.ul", "*.uw", "*.voc", "*.vorbis", "*.vox", "*.wav", "*.wve"}; register int i; appSound_entry_filename = g_strdup(gtk_entry_get_text( (GtkEntry *)apptw->Sound_entry)); file_chooser = gtk_file_chooser_dialog_new(_("Select a file..."), GTK_WINDOW(apptw->Window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("Sound Files")); for (i = 0; i < FILETYPE_SIZE; i++) { gtk_file_filter_add_pattern(filter, filetype[i]); } gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter); filter = gtk_file_filter_new(); gtk_file_filter_set_name(filter, _("All Files")); gtk_file_filter_add_pattern(filter, "*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_chooser), filter); gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(file_chooser) , PACKAGE_DATA_DIR "/orage/sounds", NULL); if (strlen(appSound_entry_filename) > 0) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_chooser) , (const gchar *) appSound_entry_filename); else gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser) , PACKAGE_DATA_DIR "/orage/sounds"); if (gtk_dialog_run(GTK_DIALOG(file_chooser)) == GTK_RESPONSE_ACCEPT) { sound_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser)); if (sound_file) { gtk_entry_set_text(GTK_ENTRY(apptw->Sound_entry), sound_file); gtk_editable_set_position(GTK_EDITABLE(apptw->Sound_entry), -1); } } gtk_widget_destroy(file_chooser); g_free(appSound_entry_filename); } static void app_free_memory(appt_win *apptw) { /* remove myself from event list appointment monitoring list */ if (apptw->el) ((el_win *)apptw->el)->apptw_list = g_list_remove(((el_win *)apptw->el)->apptw_list, apptw); /* remove myself from day list appointment monitoring list */ else if (apptw->dw) ((day_win *)apptw->dw)->apptw_list = g_list_remove(((day_win *)apptw->dw)->apptw_list, apptw); gtk_widget_destroy(apptw->Window); gtk_object_destroy(GTK_OBJECT(apptw->Tooltips)); g_free(apptw->xf_uid); g_free(apptw->par); xfical_appt_free((xfical_appt *)apptw->xf_appt); g_free(apptw); } static gboolean appWindow_check_and_close(appt_win *apptw) { gint result; if (apptw->appointment_changed == TRUE) { result = xfce_message_dialog(GTK_WINDOW(apptw->Window) , _("Warning") , GTK_STOCK_DIALOG_WARNING , _("The appointment information has been modified.") , _("Do you want to continue?") , GTK_STOCK_NO, GTK_RESPONSE_CANCEL , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT , NULL); if (result == GTK_RESPONSE_ACCEPT) { app_free_memory(apptw); } } else { app_free_memory(apptw); } return(TRUE); } static gboolean on_appWindow_delete_event_cb(GtkWidget *widget, GdkEvent *event , gpointer user_data) { return(appWindow_check_and_close((appt_win *)user_data)); } static gboolean orage_validate_datetime(appt_win *apptw, xfical_appt *appt) { gint result; /* Journal does not have end time so no need to check */ if (appt->type == XFICAL_TYPE_JOURNAL) return(TRUE); if (xfical_compare_times(appt) > 0) { result = xfce_message_dialog(GTK_WINDOW(apptw->Window) , _("Error") , GTK_STOCK_DIALOG_ERROR , _("The end of this appointment is earlier than the beginning.") , NULL , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT , NULL); return(FALSE); } else { return(TRUE); } } static void fill_appt_from_apptw_alarm(xfical_appt *appt, appt_win *apptw) { gint i, j, k; gchar *tmp; /* reminder time */ appt->alarmtime = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Alarm_spin_dd)) * 24*60*60 + gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Alarm_spin_hh)) * 60*60 + gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Alarm_spin_mm)) * 60 ; appt->display_alarm_orage = appt->alarmtime ? TRUE : FALSE; /* reminder before/after related to start/end */ /* char *when_array[4] = {_("Before Start"), _("Before End") , _("After Start"), _("After End")}; */ switch (gtk_combo_box_get_active(GTK_COMBO_BOX(apptw->Alarm_when_cb))) { case 0: appt->alarm_before = TRUE; appt->alarm_related_start = TRUE; break; case 1: appt->alarm_before = TRUE; appt->alarm_related_start = FALSE; break; case 2: appt->alarm_before = FALSE; appt->alarm_related_start = TRUE; break; case 3: appt->alarm_before = FALSE; appt->alarm_related_start = FALSE; break; default: appt->alarm_before = TRUE; appt->alarm_related_start = TRUE; break; } /* Do we use persistent alarm */ appt->alarm_persistent = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Per_checkbutton)); /* Do we use audio alarm */ appt->sound_alarm = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Sound_checkbutton)); /* Which sound file will be played */ if (appt->sound) { g_free(appt->sound); appt->sound = NULL; } appt->sound = g_strdup(gtk_entry_get_text(GTK_ENTRY(apptw->Sound_entry))); /* the alarm will repeat until someone shuts it off * or it has been played soundrepeat_cnt times */ appt->soundrepeat = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->SoundRepeat_checkbutton)); appt->soundrepeat_cnt = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_cnt)); appt->soundrepeat_len = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_len)); /* Do we use orage display alarm */ appt->display_alarm_orage = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_orage)); /* Do we use notify display alarm */ #ifdef HAVE_NOTIFY appt->display_alarm_notify = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_notify)); #else appt->display_alarm_notify = FALSE; #endif /* notify display alarm timeout */ #ifdef HAVE_NOTIFY if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_expire_notify))) appt->display_notify_timeout = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Display_spin_expire_notify)); else appt->display_notify_timeout = -1; #else appt->display_notify_timeout = -1; #endif /* Do we use procedure alarm */ appt->procedure_alarm = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Proc_checkbutton)); /* The actual command. * Note that we need to split this into cmd and the parameters * since that is how libical stores it */ if (appt->procedure_cmd) { g_free(appt->procedure_cmd); appt->procedure_cmd = NULL; } if (appt->procedure_params) { g_free(appt->procedure_params); appt->procedure_params = NULL; } tmp = (char *)gtk_entry_get_text(GTK_ENTRY(apptw->Proc_entry)); j = strlen(tmp); for (i = 0; i < j && g_ascii_isspace(tmp[i]); i++) ; /* skip blanks */ for (k = i; k < j && !g_ascii_isspace(tmp[k]); k++) ; /* find first blank after the cmd */ /* now i points to start of cmd and k points to end of cmd */ if (k-i) appt->procedure_cmd = g_strndup(tmp+i, k-i); if (j-k) appt->procedure_params = g_strndup(tmp+k, j-k); } /* * Function fills an appointment with the contents of an appointment * window */ static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw) { GtkTextIter start, end; const char *time_format="%H:%M"; struct tm current_t; gchar starttime[6], endtime[6], completedtime[6]; gint i; gchar *tmp, *tmp2; /* Next line is fix for bug 2811. * We need to make sure spin buttons do not have values which are not * yet updated = visible. * gtk_spin_button_update call would do it, but it seems to cause * crash if done in on_app_spin_button_changed_cb and here we should * either do it for all spin fields, which takes too many lines of code. * if (GTK_WIDGET_HAS_FOCUS(apptw->StartTime_spin_hh)) * gtk_spin_button_update; * So we just change the focus field and then spin button value gets set. * It would be nice to not to have to change the field though. */ gtk_widget_grab_focus(apptw->Title_entry); /*********** GENERAL TAB ***********/ /* type */ if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_event_rb))) appt->type = XFICAL_TYPE_EVENT; else if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_todo_rb))) appt->type = XFICAL_TYPE_TODO; else if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Type_journal_rb))) appt->type = XFICAL_TYPE_JOURNAL; else g_warning("fill_appt_from_apptw: coding error, illegal type"); /* title */ appt->title = g_strdup(gtk_entry_get_text(GTK_ENTRY(apptw->Title_entry))); /* location */ appt->location = g_strdup(gtk_entry_get_text( GTK_ENTRY(apptw->Location_entry))); /* all day */ appt->allDay = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->AllDay_checkbutton)); /* start date and time. * Note that timezone is kept upto date all the time */ current_t = orage_i18_date_to_tm_date(gtk_button_get_label( GTK_BUTTON(apptw->StartDate_button))); g_sprintf(starttime, "%02d:%02d" , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->StartTime_spin_hh)) , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->StartTime_spin_mm))); strptime(starttime, time_format, ¤t_t); g_sprintf(appt->starttime, XFICAL_APPT_TIME_FORMAT , current_t.tm_year + 1900, current_t.tm_mon + 1, current_t.tm_mday , current_t.tm_hour, current_t.tm_min, 0); /* end date and time. * Note that timezone is kept upto date all the time */ appt->use_due_time = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->End_checkbutton)); current_t = orage_i18_date_to_tm_date(gtk_button_get_label( GTK_BUTTON(apptw->EndDate_button))); g_sprintf(endtime, "%02d:%02d" , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->EndTime_spin_hh)) , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->EndTime_spin_mm))); strptime(endtime, time_format, ¤t_t); g_sprintf(appt->endtime, XFICAL_APPT_TIME_FORMAT , current_t.tm_year + 1900, current_t.tm_mon + 1, current_t.tm_mday , current_t.tm_hour, current_t.tm_min, 0); /* duration */ appt->use_duration = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Dur_checkbutton)); if (appt->allDay) appt->duration = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Dur_spin_dd)) * 24*60*60; else appt->duration = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Dur_spin_dd)) * 24*60*60 + gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Dur_spin_hh)) * 60*60 + gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Dur_spin_mm)) * 60; /* Check that end time is after start time. */ if (!orage_validate_datetime(apptw, appt)) return(FALSE); /* completed date and time. * Note that timezone is kept upto date all the time */ appt->completed = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Completed_checkbutton)); current_t = orage_i18_date_to_tm_date(gtk_button_get_label( GTK_BUTTON(apptw->CompletedDate_button))); g_sprintf(completedtime, "%02d:%02d" , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->CompletedTime_spin_hh)) , gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->CompletedTime_spin_mm))); strptime(completedtime, time_format, ¤t_t); g_sprintf(appt->completedtime, XFICAL_APPT_TIME_FORMAT , current_t.tm_year + 1900, current_t.tm_mon + 1, current_t.tm_mday , current_t.tm_hour, current_t.tm_min, 0); /* availability */ appt->availability = gtk_combo_box_get_active( GTK_COMBO_BOX(apptw->Availability_cb)); /* categories */ tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(apptw->Categories_entry))); tmp2 = gtk_combo_box_get_active_text(GTK_COMBO_BOX(apptw->Categories_cb)); if (!strcmp(tmp2, _("Not set"))) { g_free(tmp2); tmp2 = NULL; } if (ORAGE_STR_EXISTS(tmp)) { appt->categories = g_strjoin(",", tmp, tmp2, NULL); g_free(tmp); g_free(tmp2); } else appt->categories = tmp2; /* notes */ gtk_text_buffer_get_bounds(apptw->Note_buffer, &start, &end); appt->note = gtk_text_iter_get_text(&start, &end); /*********** ALARM TAB ***********/ fill_appt_from_apptw_alarm(appt, apptw); /*********** RECURRENCE TAB ***********/ /* recurrence */ appt->freq = gtk_combo_box_get_active(GTK_COMBO_BOX(apptw->Recur_freq_cb)); /* recurrence interval */ appt->interval = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Recur_int_spin)); /* recurrence ending */ if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_limit_rb))) { appt->recur_limit = 0; /* no limit */ appt->recur_count = 0; /* special: means no repeat count limit */ appt->recur_until[0] = 0; /* special: means no until time limit */ } else if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_count_rb))) { appt->recur_limit = 1; /* count limit */ appt->recur_count = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Recur_count_spin)); appt->recur_until[0] = 0; /* special: means no until time limit */ } else if (gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_until_rb))) { appt->recur_limit = 2; /* until limit */ appt->recur_count = 0; /* special: means no repeat count limit */ current_t = orage_i18_date_to_tm_date(gtk_button_get_label( GTK_BUTTON(apptw->Recur_until_button))); g_sprintf(appt->recur_until, XFICAL_APPT_TIME_FORMAT , current_t.tm_year + 1900, current_t.tm_mon + 1 , current_t.tm_mday, 23, 59, 10); } else g_warning("fill_appt_from_apptw: coding error, illegal recurrence"); /* recurrence weekdays */ for (i=0; i <= 6; i++) { appt->recur_byday[i] = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(apptw->Recur_byday_cb[i])); /* recurrence weekday selection for month/yearly case */ appt->recur_byday_cnt[i] = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(apptw->Recur_byday_spin[i])); } return(TRUE); } static gboolean save_xfical_from_appt_win(appt_win *apptw) { gboolean ok = FALSE; xfical_appt *appt = (xfical_appt *)apptw->xf_appt; if (fill_appt_from_apptw(appt, apptw)) { /* Here we try to save the event... */ if (!xfical_file_open(TRUE)) return(FALSE); if (apptw->appointment_add) { apptw->xf_uid = g_strdup(xfical_appt_add(appt)); ok = (apptw->xf_uid ? TRUE : FALSE); if (ok) { apptw->appointment_add = FALSE; gtk_widget_set_sensitive(apptw->Duplicate, TRUE); gtk_widget_set_sensitive(apptw->File_menu_duplicate, TRUE); orage_message(10, "Added: %s", apptw->xf_uid); } else orage_message(150, "Addition failed: %s", apptw->xf_uid); } else { ok = xfical_appt_mod(apptw->xf_uid, appt); if (ok) orage_message(10, "Modified: %s", apptw->xf_uid); else orage_message(150, "Modification failed: %s", apptw->xf_uid); } xfical_file_close(TRUE); if (ok) { apptw->appointment_new = FALSE; mark_appointment_unchanged(apptw); refresh_dependent_data(apptw); } } return(ok); } static void on_appFileSave_menu_activate_cb(GtkMenuItem *mi, gpointer user_data) { save_xfical_from_appt_win((appt_win *)user_data); } static void on_appSave_clicked_cb(GtkButton *b, gpointer user_data) { save_xfical_from_appt_win((appt_win *)user_data); } static void save_xfical_from_appt_win_and_close(appt_win *apptw) { if (save_xfical_from_appt_win(apptw)) { app_free_memory(apptw); } } static void on_appFileSaveClose_menu_activate_cb(GtkMenuItem *mi , gpointer user_data) { save_xfical_from_appt_win_and_close((appt_win *)user_data); } static void on_appSaveClose_clicked_cb(GtkButton *b, gpointer user_data) { save_xfical_from_appt_win_and_close((appt_win *)user_data); } static void delete_xfical_from_appt_win(appt_win *apptw) { gint result; result = xfce_message_dialog(GTK_WINDOW(apptw->Window) , _("Warning") , GTK_STOCK_DIALOG_WARNING , _("This appointment will be permanently removed.") , _("Do you want to continue?") , GTK_STOCK_NO, GTK_RESPONSE_REJECT , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT , NULL); if (result == GTK_RESPONSE_ACCEPT) { if (!apptw->appointment_add) { if (!xfical_file_open(TRUE)) return; result = xfical_appt_del(apptw->xf_uid); if (result) orage_message(10, "Removed: %s", apptw->xf_uid); else g_warning("Removal failed: %s", apptw->xf_uid); xfical_file_close(TRUE); } refresh_dependent_data(apptw); app_free_memory(apptw); } } static void on_appDelete_clicked_cb(GtkButton *b, gpointer user_data) { delete_xfical_from_appt_win((appt_win *)user_data); } static void on_appFileDelete_menu_activate_cb(GtkMenuItem *mi , gpointer user_data) { delete_xfical_from_appt_win((appt_win *)user_data); } static void on_appFileClose_menu_activate_cb(GtkMenuItem *mi , gpointer user_data) { appWindow_check_and_close((appt_win *)user_data); } static void duplicate_xfical_from_appt_win(appt_win *apptw) { gint x, y; appt_win *apptw2; /* do not keep track of appointments created here */ apptw2 = create_appt_win("COPY", apptw->xf_uid); gtk_window_get_position(GTK_WINDOW(apptw->Window), &x, &y); gtk_window_move(GTK_WINDOW(apptw2->Window), x+20, y+20); } static void on_appFileDuplicate_menu_activate_cb(GtkMenuItem *mi , gpointer user_data) { duplicate_xfical_from_appt_win((appt_win *)user_data); } static void on_appDuplicate_clicked_cb(GtkButton *b, gpointer user_data) { duplicate_xfical_from_appt_win((appt_win *)user_data); } static void revert_xfical_to_last_saved(appt_win *apptw) { if (!apptw->appointment_new) { fill_appt_window(apptw, "UPDATE", apptw->xf_uid); } else { fill_appt_window(apptw, "NEW", apptw->par); } } static void on_appFileRevert_menu_activate_cb(GtkMenuItem *mi , gpointer user_data) { revert_xfical_to_last_saved((appt_win *)user_data); } static void on_appRevert_clicked_cb(GtkWidget *b, gpointer *user_data) { revert_xfical_to_last_saved((appt_win *)user_data); } static void on_Date_button_clicked_cb(GtkWidget *button, gpointer *user_data) { appt_win *apptw = (appt_win *)user_data; if (orage_date_button_clicked(button, apptw->Window)) mark_appointment_changed(apptw); } static void on_appStartTimezone_clicked_cb(GtkButton *button , gpointer *user_data) { appt_win *apptw = (appt_win *)user_data; xfical_appt *appt; appt = (xfical_appt *)apptw->xf_appt; if (xfical_timezone_button_clicked(button, GTK_WINDOW(apptw->Window) , &appt->start_tz_loc)) mark_appointment_changed(apptw); } static void on_appEndTimezone_clicked_cb(GtkButton *button , gpointer *user_data) { appt_win *apptw = (appt_win *)user_data; xfical_appt *appt; appt = (xfical_appt *)apptw->xf_appt; if (xfical_timezone_button_clicked(button, GTK_WINDOW(apptw->Window) , &appt->end_tz_loc)) mark_appointment_changed(apptw); } static void on_appCompletedTimezone_clicked_cb(GtkButton *button , gpointer *user_data) { appt_win *apptw = (appt_win *)user_data; xfical_appt *appt; appt = (xfical_appt *)apptw->xf_appt; if (xfical_timezone_button_clicked(button, GTK_WINDOW(apptw->Window) , &appt->completed_tz_loc)) mark_appointment_changed(apptw); } static void fill_appt_window_times(appt_win *apptw, xfical_appt *appt) { char *startdate_to_display, *enddate_to_display, *completeddate_to_display; int days, hours, minutes; struct tm tm_date; /* all day ? */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->AllDay_checkbutton), appt->allDay); /* start time */ if (strlen(appt->starttime) > 6 ) { tm_date = orage_icaltime_to_tm_time(appt->starttime, TRUE); startdate_to_display = orage_tm_date_to_i18_date(&tm_date); gtk_button_set_label(GTK_BUTTON(apptw->StartDate_button) , (const gchar *)startdate_to_display); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->StartTime_spin_hh) , (gdouble)tm_date.tm_hour); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->StartTime_spin_mm) , (gdouble)tm_date.tm_min); if (appt->start_tz_loc) gtk_button_set_label(GTK_BUTTON(apptw->StartTimezone_button) , _(appt->start_tz_loc)); else /* we should never get here */ g_warning("fill_appt_window_times: start_tz_loc is null"); } else g_warning("fill_appt_window_times: starttime wrong %s", appt->uid); /* end time */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( apptw->End_checkbutton), appt->use_due_time); if (strlen(appt->endtime) > 6 ) { tm_date = orage_icaltime_to_tm_time(appt->endtime, TRUE); enddate_to_display = orage_tm_date_to_i18_date(&tm_date); gtk_button_set_label(GTK_BUTTON(apptw->EndDate_button) , (const gchar *)enddate_to_display); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->EndTime_spin_hh) , (gdouble)tm_date.tm_hour); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->EndTime_spin_mm) , (gdouble)tm_date.tm_min); if (appt->end_tz_loc) { gtk_button_set_label(GTK_BUTTON(apptw->EndTimezone_button) , _(appt->end_tz_loc)); } else /* we should never get here */ g_warning("fill_appt_window_times: end_tz_loc is null"); } else g_warning("fill_appt_window_times: endtime wrong %s", appt->uid); /* duration */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(apptw->Dur_checkbutton) , appt->use_duration); days = appt->duration/(24*60*60); hours = (appt->duration-days*(24*60*60))/(60*60); minutes = (appt->duration-days*(24*60*60)-hours*(60*60))/(60); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Dur_spin_dd) , (gdouble)days); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Dur_spin_hh) , (gdouble)hours); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Dur_spin_mm) , (gdouble)minutes); /* completed time (only available for todo) */ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON( apptw->Completed_checkbutton), appt->completed); if (strlen(appt->completedtime) > 6 ) { tm_date = orage_icaltime_to_tm_time(appt->completedtime, TRUE); completeddate_to_display = orage_tm_date_to_i18_date(&tm_date); gtk_button_set_label(GTK_BUTTON(apptw->CompletedDate_button) , (const gchar *)completeddate_to_display); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->CompletedTime_spin_hh) , (gdouble)tm_date.tm_hour); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->CompletedTime_spin_mm) , (gdouble)tm_date.tm_min); if (appt->completed_tz_loc) { gtk_button_set_label(GTK_BUTTON(apptw->CompletedTimezone_button) , _(appt->completed_tz_loc)); } else /* we should never get here */ g_warning("fill_appt_window_times: completed_tz_loc is null"); } else g_warning("fill_appt_window_times: completedtime wrong %s", appt->uid); } static xfical_appt *fill_appt_window_get_appt(appt_win *apptw , char *action, char *par) { xfical_appt *appt=NULL; struct tm *t; gchar today[9]; if (strcmp(action, "NEW") == 0) { /* par contains XFICAL_APPT_DATE_FORMAT (yyyymmdd) date for NEW appointment */ appt = xfical_appt_alloc(); t = orage_localtime(); g_sprintf(today, "%04d%02d%02d", t->tm_year+1900, t->tm_mon+1 , t->tm_mday); /* If we're today, we propose an appointment the next half-hour */ /* hour 24 is wrong, we use 00 */ if (strcmp(par, today) == 0 && t->tm_hour < 23) { if (t->tm_min <= 30) { g_sprintf(appt->starttime,"%sT%02d%02d00" , par, t->tm_hour, 30); g_sprintf(appt->endtime,"%sT%02d%02d00" , par, t->tm_hour + 1, 00); } else { g_sprintf(appt->starttime,"%sT%02d%02d00" , par, t->tm_hour + 1, 00); g_sprintf(appt->endtime,"%sT%02d%02d00" , par, t->tm_hour + 1, 30); } } /* otherwise we suggest it at 09:00 in the morning. */ else { g_sprintf(appt->starttime,"%sT090000", par); g_sprintf(appt->endtime,"%sT093000", par); } if (g_par.local_timezone_utc) appt->start_tz_loc = g_strdup("UTC"); else if (g_par.local_timezone) appt->start_tz_loc = g_strdup(g_par.local_timezone); else appt->start_tz_loc = g_strdup("floating"); appt->end_tz_loc = g_strdup(appt->start_tz_loc); appt->duration = 30*60; /* use duration by default for new appointments */ appt->use_duration = TRUE; g_sprintf(appt->completedtime,"%sT%02d%02d00" , today, t->tm_hour, t->tm_min); appt->completed_tz_loc = g_strdup(appt->start_tz_loc); read_default_alarm(appt); } else if ((strcmp(action, "UPDATE") == 0) || (strcmp(action, "COPY") == 0)) { /* par contains ical uid */ if (!xfical_file_open(TRUE)) return(NULL); if ((appt = xfical_appt_get(par)) == NULL) { xfce_message_dialog(GTK_WINDOW(apptw->Window) , _("Info") , GTK_STOCK_DIALOG_INFO , _("This appointment does not exist.") , _("It was probably removed, please refresh your screen.") , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT , NULL); } xfical_file_close(TRUE); } else { g_error("unknown parameter\n"); } return(appt); } /************************************************************/ /* categories start. */ /************************************************************/ typedef struct _orage_category { gchar *category; GdkColor color; } orage_category_struct; GList *orage_category_list = NULL; static OrageRc *orage_category_file_open(gboolean read_only) { gchar *fpath; OrageRc *orc; fpath = orage_data_file_location(ORAGE_CATEGORIES_FILE); if ((orc = (OrageRc *)orage_rc_file_open(fpath, read_only)) == NULL) { orage_message(150, "orage_category_file_open: category file open failed."); } g_free(fpath); return(orc); } GdkColor *orage_category_list_contains(char *categories) { GList *cat_l; orage_category_struct *cat; if (categories == NULL) return(NULL); cat_l = orage_category_list; for (cat_l = g_list_first(cat_l); cat_l != NULL; cat_l = g_list_next(cat_l)) { cat = (orage_category_struct *)cat_l->data; if (g_str_has_suffix(categories, cat->category)) { return(&cat->color); } } /* not found */ return(NULL); } static void orage_category_free(gpointer gcat, gpointer dummy) { orage_category_struct *cat = (orage_category_struct *)gcat; g_free(cat->category); g_free(cat); } void orage_category_free_list() { g_list_foreach(orage_category_list, orage_category_free, NULL); g_list_free(orage_category_list); orage_category_list = NULL; } void orage_category_get_list() { OrageRc *orc; gchar **cat_groups, *color; gint i; orage_category_struct *cat; GdkColormap *pic1_cmap; unsigned int red, green, blue; if (orage_category_list != NULL) orage_category_free_list(); pic1_cmap = gdk_colormap_get_system(); orc = orage_category_file_open(TRUE); cat_groups = orage_rc_get_groups(orc); for (i=1; cat_groups[i] != NULL; i++) { orage_rc_set_group(orc, cat_groups[i]); color = orage_rc_get_str(orc, "Color", NULL); if (color) { cat = g_new(orage_category_struct, 1); cat->category = g_strdup(cat_groups[i]); /* sscanf(color, ORAGE_COLOR_FORMAT , (unsigned int *)&(cat->color.red) , (unsigned int *)&(cat->color.green) , (unsigned int *)&(cat->color.blue)); */ sscanf(color, ORAGE_COLOR_FORMAT, &red, &green, &blue); cat->color.red = red; cat->color.green = green; cat->color.blue = blue; gdk_colormap_alloc_color(pic1_cmap, &cat->color, FALSE, TRUE); orage_category_list = g_list_prepend(orage_category_list, cat); g_free(color); } } g_strfreev(cat_groups); orage_rc_file_close(orc); } gboolean category_fill_cb(GtkComboBox *cb, char *select) { OrageRc *orc; gchar **cat_gourps; gint i; gboolean found=FALSE; orc = orage_category_file_open(TRUE); cat_gourps = orage_rc_get_groups(orc); /* cat_groups[0] is special [NULL] entry always */ gtk_combo_box_append_text(cb, _("Not set")); gtk_combo_box_set_active(cb, 0); for (i=1; cat_gourps[i] != NULL; i++) { gtk_combo_box_append_text(cb, (const gchar *)cat_gourps[i]); if (!found && select && !strcmp(select, cat_gourps[i])) { gtk_combo_box_set_active(cb, i); found = TRUE; } } g_strfreev(cat_gourps); orage_rc_file_close(orc); return(found); } void orage_category_refill_cb(appt_win *apptw) { gchar *tmp; /* first remember the currently selected value */ tmp = gtk_combo_box_get_active_text(GTK_COMBO_BOX(apptw->Categories_cb)); /* then clear the values by removing the widget and putting it back */ gtk_widget_destroy(apptw->Categories_cb); apptw->Categories_cb = gtk_combo_box_new_text(); gtk_container_add(GTK_CONTAINER(apptw->Categories_cb_event) , apptw->Categories_cb); /* and finally fill it with new values */ category_fill_cb(GTK_COMBO_BOX(apptw->Categories_cb), tmp); g_free(tmp); gtk_widget_show(apptw->Categories_cb); } void fill_category_data(appt_win *apptw, xfical_appt *appt) { gchar *tmp = NULL; /* first search the last entry. which is the special color value */ if (appt->categories) { tmp = g_strrstr(appt->categories, ","); if (!tmp) /* , not found, let's take the whole string */ tmp = appt->categories; while (*(tmp) == ' ' || *(tmp) == ',') /* skip blanks and , */ tmp++; } if (category_fill_cb(GTK_COMBO_BOX(apptw->Categories_cb), tmp)) { /* we found match. Let's try to hide that from the entry text */ while (tmp != appt->categories && (*(tmp-1) == ' ' || *(tmp-1) == ',')) tmp--; *tmp = '\0'; /* note that this goes to appt->categories */ } gtk_entry_set_text(GTK_ENTRY(apptw->Categories_entry) , (appt->categories ? appt->categories : "")); } void orage_category_write_entry(gchar *category, GdkColor *color) { OrageRc *orc; char *color_str; if (!ORAGE_STR_EXISTS(category)) { orage_message(50, "orage_category_write_entry: empty category. Not written"); return; } color_str = g_strdup_printf(ORAGE_COLOR_FORMAT , color->red, color->green, color->blue); orc = orage_category_file_open(FALSE); orage_rc_set_group(orc, category); orage_rc_put_str(orc, "Color", color_str); g_free(color_str); orage_rc_file_close(orc); } static void orage_category_remove_entry(gchar *category) { OrageRc *orc; if (!ORAGE_STR_EXISTS(category)) { orage_message(50, "orage_category_remove_entry: empty category. Not removed"); return; } orc = orage_category_file_open(FALSE); orage_rc_del_group(orc, category); orage_rc_file_close(orc); } static void close_cat_window(gpointer user_data) { category_win_struct *catw = (category_win_struct *)user_data; orage_category_refill_cb((appt_win *)catw->apptw); gtk_widget_destroy(catw->window); gtk_object_destroy(GTK_OBJECT(catw->tooltips)); g_free(catw); } static gboolean on_cat_window_delete_event(GtkWidget *w, GdkEvent *e , gpointer user_data) { close_cat_window(user_data); return(FALSE); } static void cat_add_button_clicked(GtkButton *button, gpointer user_data) { category_win_struct *catw = (category_win_struct *)user_data; gchar *entry_category; GdkColor color; entry_category = g_strdup(gtk_entry_get_text((GtkEntry *)catw->new_entry)); g_strstrip(entry_category); gtk_color_button_get_color((GtkColorButton *)catw->new_color_button , &color); orage_category_write_entry(entry_category, &color); g_free(entry_category); refresh_categories(catw); } static void cat_color_button_changed(GtkColorButton *color_button , gpointer user_data) { gchar *category; GdkColor color; category = g_object_get_data(G_OBJECT(color_button), "CATEGORY"); gtk_color_button_get_color(color_button, &color); orage_category_write_entry(category, &color); } static void cat_del_button_clicked(GtkButton *button, gpointer user_data) { category_win_struct *catw = (category_win_struct *)user_data; gchar *category; category = g_object_get_data(G_OBJECT(button), "CATEGORY"); orage_category_remove_entry(category); refresh_categories(catw); } static void show_category(gpointer elem, gpointer user_data) { orage_category_struct *cat = (orage_category_struct *)elem; category_win_struct *catw = (category_win_struct *)user_data; GtkWidget *label, *hbox, *button, *color_button; hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(cat->category); gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 5); color_button = gtk_color_button_new_with_color(&cat->color); gtk_box_pack_start(GTK_BOX(hbox), color_button, FALSE, FALSE, 5); g_object_set_data_full(G_OBJECT(color_button), "CATEGORY" , g_strdup(cat->category), g_free); g_signal_connect((gpointer)color_button, "color-set" , G_CALLBACK(cat_color_button_changed), catw); button = gtk_button_new_from_stock("gtk-remove"); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); g_object_set_data_full(G_OBJECT(button), "CATEGORY" , g_strdup(cat->category), g_free); g_signal_connect((gpointer)button, "clicked" , G_CALLBACK(cat_del_button_clicked), catw); gtk_box_pack_start(GTK_BOX(catw->cur_frame_vbox), hbox, FALSE, FALSE, 5); } static void refresh_categories(category_win_struct *catw) { GtkWidget *swin; gtk_widget_destroy(catw->cur_frame); catw->cur_frame_vbox = gtk_vbox_new(FALSE, 0); swin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin) , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin) , catw->cur_frame_vbox); catw->cur_frame = xfce_create_framebox_with_content( _("Current categories"), swin); gtk_box_pack_start(GTK_BOX(catw->vbox), catw->cur_frame, TRUE, TRUE, 5); orage_category_get_list(); g_list_foreach(orage_category_list, show_category, catw); gtk_widget_show_all(catw->cur_frame); } static void create_cat_win(category_win_struct *catw) { GtkWidget *label, *hbox, *vbox; /***** New category *****/ vbox = gtk_vbox_new(FALSE, 0); catw->new_frame = xfce_create_framebox_with_content( _("Add new category with color"), vbox); gtk_box_pack_start(GTK_BOX(catw->vbox), catw->new_frame, FALSE, FALSE, 5); hbox = gtk_hbox_new(FALSE, 0); label = gtk_label_new(_("Category:")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5); catw->new_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox), catw->new_entry, TRUE, TRUE, 0); catw->new_color_button = gtk_color_button_new(); gtk_box_pack_start(GTK_BOX(hbox), catw->new_color_button, FALSE, FALSE, 5); catw->new_add_button = gtk_button_new_from_stock("gtk-add"); gtk_box_pack_start(GTK_BOX(hbox), catw->new_add_button, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); g_signal_connect((gpointer)catw->new_add_button, "clicked" , G_CALLBACK(cat_add_button_clicked), catw); /***** Current categories *****/ /* refresh_categories always destroys frame first, so let's create * a dummy for it for the first time */ vbox = gtk_vbox_new(FALSE, 0); catw->cur_frame = xfce_create_framebox_with_content(("dummy"), vbox); refresh_categories(catw); } static void on_categories_button_clicked_cb(GtkWidget *button , gpointer *user_data) { appt_win *apptw = (appt_win *)user_data; category_win_struct *catw; catw = g_new(category_win_struct, 1); catw->apptw = (gpointer)apptw; /* remember the caller */ catw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_modal(GTK_WINDOW(catw->window), TRUE); gtk_window_set_title(GTK_WINDOW(catw->window) , _("Colors of categories - Orage")); gtk_window_set_default_size(GTK_WINDOW(catw->window), 390, 360); catw->tooltips = gtk_tooltips_new(); catw->accelgroup = gtk_accel_group_new(); gtk_window_add_accel_group(GTK_WINDOW(catw->window), catw->accelgroup); catw->vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(catw->window), catw->vbox); create_cat_win(catw); g_signal_connect((gpointer)catw->window, "delete_event", G_CALLBACK(on_cat_window_delete_event), catw); gtk_widget_show_all(catw->window); } /**********************************************************/ /* categories end. */ /**********************************************************/ static void fill_appt_window_alarm(xfical_appt *appt, appt_win *apptw) { int day, hours, minutes; char *tmp; /* alarmtime (comes in seconds) */ day = appt->alarmtime/(24*60*60); hours = (appt->alarmtime-day*(24*60*60))/(60*60); minutes = (appt->alarmtime-day*(24*60*60)-hours*(60*60))/(60); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Alarm_spin_dd) , (gdouble)day); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Alarm_spin_hh) , (gdouble)hours); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Alarm_spin_mm) , (gdouble)minutes); /* alarmrelation */ /* char *when_array[4] = { _("Before Start"), _("Before End"), _("After Start"), _("After End")}; */ if (appt->alarm_before) if (appt->alarm_related_start) gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Alarm_when_cb), 0); else gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Alarm_when_cb), 1); else if (appt->alarm_related_start) gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Alarm_when_cb), 2); else gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Alarm_when_cb), 3); /* persistent */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Per_checkbutton), appt->alarm_persistent); /* sound */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Sound_checkbutton), appt->sound_alarm); gtk_entry_set_text(GTK_ENTRY(apptw->Sound_entry) , (appt->sound ? appt->sound : PACKAGE_DATA_DIR "/orage/sounds/Spo.wav")); /* sound repeat */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->SoundRepeat_checkbutton) , appt->soundrepeat); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_cnt) , (gdouble)appt->soundrepeat_cnt); gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_len) , (gdouble)appt->soundrepeat_len); /* display */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_orage) , appt->display_alarm_orage); /* display:notify */ #ifdef HAVE_NOTIFY gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_notify) , appt->display_alarm_notify); if (!appt->display_alarm_notify || appt->display_notify_timeout == -1) { /* no timeout */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_expire_notify) , FALSE); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Display_spin_expire_notify) , (gdouble)0); } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Display_checkbutton_expire_notify) , TRUE); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Display_spin_expire_notify) , (gdouble)appt->display_notify_timeout); } #endif /* procedure */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Proc_checkbutton), appt->procedure_alarm); tmp = g_strconcat(appt->procedure_cmd, " ", appt->procedure_params, NULL); gtk_entry_set_text(GTK_ENTRY(apptw->Proc_entry), tmp ? tmp : ""); g_free(tmp); } /* Fill appointment window with data */ static void fill_appt_window(appt_win *apptw, char *action, char *par) { xfical_appt *appt; struct tm *t, tm_date; char *untildate_to_display; int i; orage_message(10, "%s appointment: %s", action, par); if ((appt = fill_appt_window_get_appt(apptw, action, par)) == NULL) { apptw->xf_appt = NULL; return; } apptw->xf_appt = appt; /* first flags */ apptw->xf_uid = g_strdup(appt->uid); apptw->par = g_strdup((const gchar *)par); apptw->appointment_changed = FALSE; if (strcmp(action, "NEW") == 0) { apptw->appointment_add = TRUE; apptw->appointment_new = TRUE; } else if (strcmp(action, "UPDATE") == 0) { apptw->appointment_add = FALSE; apptw->appointment_new = FALSE; } else if (strcmp(action, "COPY") == 0) { /* COPY uses old uid as base and adds new, so * add == TRUE && new == FALSE */ apptw->appointment_add = TRUE; apptw->appointment_new = FALSE; } else { g_error("fill_appt_window: unknown parameter\n"); return; } if (!appt->completed) { /* some nice default */ t = orage_localtime(); /* probably completed today? */ g_sprintf(appt->completedtime, XFICAL_APPT_TIME_FORMAT , t->tm_year+1900, t->tm_mon+1 , t->tm_mday , t->tm_hour, t->tm_min, 0); appt->completed_tz_loc = g_strdup(appt->start_tz_loc); } /* we only want to enable duplication if we are working with an old * existing app (=not adding new) */ gtk_widget_set_sensitive(apptw->Duplicate, !apptw->appointment_add); gtk_widget_set_sensitive(apptw->File_menu_duplicate , !apptw->appointment_add); /* window title */ gtk_window_set_title(GTK_WINDOW(apptw->Window) , _("New appointment - Orage")); /********************* GENERAL tab *********************/ /* type */ if (appt->type == XFICAL_TYPE_EVENT) gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Type_event_rb), TRUE); else if (appt->type == XFICAL_TYPE_TODO) gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Type_todo_rb), TRUE); else if (appt->type == XFICAL_TYPE_JOURNAL) gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Type_journal_rb), TRUE); else g_warning("fill_appt_window: Illegal value for type\n"); /* appointment name */ gtk_entry_set_text(GTK_ENTRY(apptw->Title_entry) , (appt->title ? appt->title : "")); if (strcmp(action, "COPY") == 0) { gtk_editable_set_position(GTK_EDITABLE(apptw->Title_entry), -1); i = gtk_editable_get_position(GTK_EDITABLE(apptw->Title_entry)); gtk_editable_insert_text(GTK_EDITABLE(apptw->Title_entry) , _(" *** COPY ***"), strlen(_(" *** COPY ***")), &i); } /* location */ gtk_entry_set_text(GTK_ENTRY(apptw->Location_entry) , (appt->location ? appt->location : "")); /* times */ fill_appt_window_times(apptw, appt); /* availability */ if (appt->availability != -1) { gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Availability_cb) , appt->availability); } /* categories */ fill_category_data(apptw, appt); /* note */ gtk_text_buffer_set_text(apptw->Note_buffer , (appt->note ? (const gchar *) appt->note : ""), -1); /********************* ALARM tab *********************/ fill_appt_window_alarm(appt, apptw); /********************* RECURRENCE tab *********************/ /* recurrence */ gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Recur_freq_cb) , appt->freq); switch(appt->recur_limit) { case 0: /* no limit */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_limit_rb), TRUE); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Recur_count_spin), (gdouble)1); untildate_to_display = orage_localdate_i18(); gtk_button_set_label(GTK_BUTTON(apptw->Recur_until_button) , (const gchar *)untildate_to_display); break; case 1: /* count */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_count_rb), TRUE); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Recur_count_spin) , (gdouble)appt->recur_count); untildate_to_display = orage_localdate_i18(); gtk_button_set_label(GTK_BUTTON(apptw->Recur_until_button) , (const gchar *)untildate_to_display); break; case 2: /* until */ gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_until_rb), TRUE); gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Recur_count_spin), (gdouble)1); tm_date = orage_icaltime_to_tm_time(appt->recur_until, TRUE); untildate_to_display = orage_tm_date_to_i18_date(&tm_date); gtk_button_set_label(GTK_BUTTON(apptw->Recur_until_button) , (const gchar *)untildate_to_display); break; default: /* error */ g_warning("fill_appt_window: Unsupported recur_limit %d", appt->recur_limit); } /* weekdays */ for (i=0; i <= 6; i++) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_byday_cb[i]) , appt->recur_byday[i]); /* which weekday of month / year */ gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Recur_byday_spin[i]) , (gdouble)appt->recur_byday_cnt[i]); } /* interval */ gtk_spin_button_set_value( GTK_SPIN_BUTTON(apptw->Recur_int_spin) , (gdouble)appt->interval); if (appt->interval > 1 || !appt->recur_byday[0] || !appt->recur_byday[1] || !appt->recur_byday[2] || !appt->recur_byday[3] || !appt->recur_byday[4] || !appt->recur_byday[5] || !appt->recur_byday[6]) { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_feature_advanced_rb), TRUE); } else { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(apptw->Recur_feature_normal_rb), TRUE); } set_time_sensitivity(apptw); set_repeat_sensitivity(apptw); set_sound_sensitivity(apptw); set_notify_sensitivity(apptw); set_proc_sensitivity(apptw); mark_appointment_unchanged(apptw); } static void build_menu(appt_win *apptw) { GtkWidget *menu_separator; /* Menu bar */ apptw->Menubar = gtk_menu_bar_new(); gtk_box_pack_start(GTK_BOX(apptw->Vbox), apptw->Menubar, FALSE, FALSE, 0); /* File menu stuff */ apptw->File_menu = orage_menu_new(_("_File"), apptw->Menubar); apptw->File_menu_save = orage_image_menu_item_new_from_stock("gtk-save" , apptw->File_menu, apptw->accel_group); apptw->File_menu_saveclose = orage_menu_item_new_with_mnemonic(_("Sav_e and close") , apptw->File_menu); gtk_widget_add_accelerator(apptw->File_menu_saveclose , "activate", apptw->accel_group , GDK_w, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE); menu_separator = orage_separator_menu_item_new(apptw->File_menu); apptw->File_menu_revert = orage_image_menu_item_new_from_stock("gtk-revert-to-saved" , apptw->File_menu, apptw->accel_group); apptw->File_menu_duplicate = orage_menu_item_new_with_mnemonic(_("D_uplicate") , apptw->File_menu); gtk_widget_add_accelerator(apptw->File_menu_duplicate , "activate", apptw->accel_group , GDK_d, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); menu_separator = orage_separator_menu_item_new(apptw->File_menu); apptw->File_menu_delete = orage_image_menu_item_new_from_stock("gtk-delete" , apptw->File_menu, apptw->accel_group); menu_separator = orage_separator_menu_item_new(apptw->File_menu); apptw->File_menu_close = orage_image_menu_item_new_from_stock("gtk-close" , apptw->File_menu, apptw->accel_group); g_signal_connect((gpointer)apptw->File_menu_save, "activate" , G_CALLBACK(on_appFileSave_menu_activate_cb), apptw); g_signal_connect((gpointer)apptw->File_menu_saveclose, "activate" , G_CALLBACK(on_appFileSaveClose_menu_activate_cb), apptw); g_signal_connect((gpointer)apptw->File_menu_duplicate, "activate" , G_CALLBACK(on_appFileDuplicate_menu_activate_cb), apptw); g_signal_connect((gpointer)apptw->File_menu_revert, "activate" , G_CALLBACK(on_appFileRevert_menu_activate_cb), apptw); g_signal_connect((gpointer)apptw->File_menu_delete, "activate" , G_CALLBACK(on_appFileDelete_menu_activate_cb), apptw); g_signal_connect((gpointer)apptw->File_menu_close, "activate" , G_CALLBACK(on_appFileClose_menu_activate_cb), apptw); } static OrageRc *orage_alarm_file_open(gboolean read_only) { gchar *fpath; OrageRc *orc; fpath = orage_config_file_location(ORAGE_DEFAULT_ALARM_FILE); if (!read_only) /* we need to empty it before each write */ g_remove(fpath); if ((orc = (OrageRc *)orage_rc_file_open(fpath, read_only)) == NULL) { orage_message(150, "orage_alarm_file_open: default alarm file open failed."); } g_free(fpath); return(orc); } static void store_default_alarm(xfical_appt *appt) { OrageRc *orc; orc = orage_alarm_file_open(FALSE); orage_rc_put_int(orc, "TIME", appt->alarmtime); orage_rc_put_bool(orc, "BEFORE", appt->alarm_before); orage_rc_put_bool(orc, "RELATED_START", appt->alarm_related_start); orage_rc_put_bool(orc, "PERSISTENT", appt->alarm_persistent); orage_rc_put_bool(orc, "SOUND_USE", appt->sound_alarm); orage_rc_put_str(orc, "SOUND", appt->sound); orage_rc_put_bool(orc, "SOUND_REPEAT_USE", appt->soundrepeat); orage_rc_put_int(orc, "SOUND_REPEAT_CNT", appt->soundrepeat_cnt); orage_rc_put_int(orc, "SOUND_REPEAT_LEN", appt->soundrepeat_len); orage_rc_put_bool(orc, "DISPLAY_ORAGE_USE", appt->display_alarm_orage); orage_rc_put_bool(orc, "DISPLAY_NOTIFY_USE", appt->display_alarm_notify); orage_rc_put_int(orc, "DISPLAY_NOTIFY_TIMEOUT" , appt->display_notify_timeout); orage_rc_put_bool(orc, "PROCEDURE_USE", appt->procedure_alarm); orage_rc_put_str(orc, "PROCEDURE_CMD", appt->procedure_cmd); orage_rc_put_str(orc, "PROCEDURE_PARAMS", appt->procedure_params); orage_rc_file_close(orc); } static void read_default_alarm(xfical_appt *appt) { OrageRc *orc; orc = orage_alarm_file_open(TRUE); appt->alarmtime = orage_rc_get_int(orc, "TIME", 5*60); /* 5 mins */ appt->alarm_before = orage_rc_get_bool(orc, "BEFORE", TRUE); appt->alarm_related_start = orage_rc_get_bool(orc, "RELATED_START", TRUE); appt->alarm_persistent = orage_rc_get_bool(orc, "PERSISTENT", FALSE); appt->sound_alarm = orage_rc_get_bool(orc, "SOUND_USE", TRUE); if (appt->sound) g_free(appt->sound); appt->sound = orage_rc_get_str(orc, "SOUND" , PACKAGE_DATA_DIR "/orage/sounds/Spo.wav"); appt->soundrepeat = orage_rc_get_bool(orc, "SOUND_REPEAT_USE", FALSE); appt->soundrepeat_cnt = orage_rc_get_int(orc, "SOUND_REPEAT_CNT", 500); appt->soundrepeat_len = orage_rc_get_int(orc, "SOUND_REPEAT_LEN", 2); appt->display_alarm_orage = orage_rc_get_bool(orc, "DISPLAY_ORAGE_USE" , TRUE); appt->display_alarm_notify = orage_rc_get_bool(orc, "DISPLAY_NOTIFY_USE" , FALSE); appt->display_notify_timeout = orage_rc_get_int(orc , "DISPLAY_NOTIFY_TIMEOUT", 0); appt->procedure_alarm = orage_rc_get_bool(orc, "PROCEDURE_USE", FALSE); if (appt->procedure_cmd) g_free(appt->procedure_cmd); appt->procedure_cmd = orage_rc_get_str(orc, "PROCEDURE_CMD", ""); if (appt->procedure_params) g_free(appt->procedure_params); appt->procedure_params = orage_rc_get_str(orc, "PROCEDURE_PARAMS", ""); orage_rc_file_close(orc); } static void on_appDefault_save_button_clicked_cb(GtkButton *button , gpointer user_data) { appt_win *apptw = (appt_win *)user_data; xfical_appt *appt = (xfical_appt *)apptw->xf_appt; fill_appt_from_apptw_alarm(appt, apptw); store_default_alarm(appt); } static void on_appDefault_read_button_clicked_cb(GtkButton *button , gpointer user_data) { appt_win *apptw = (appt_win *)user_data; xfical_appt *appt = (xfical_appt *)apptw->xf_appt; read_default_alarm(appt); fill_appt_window_alarm(appt, apptw); } static void build_toolbar(appt_win *apptw) { GtkWidget *toolbar_separator; gint i = 0; apptw->Toolbar = gtk_toolbar_new(); gtk_box_pack_start(GTK_BOX(apptw->Vbox), apptw->Toolbar, FALSE, FALSE, 0); gtk_toolbar_set_tooltips(GTK_TOOLBAR(apptw->Toolbar), TRUE); /* Add buttons to the toolbar */ apptw->Save = orage_toolbar_append_button(apptw->Toolbar , "gtk-save", apptw->Tooltips, _("Save"), i++); apptw->SaveClose = orage_toolbar_append_button(apptw->Toolbar , "gtk-close", apptw->Tooltips, _("Save and close"), i++); toolbar_separator = orage_toolbar_append_separator(apptw->Toolbar, i++); apptw->Revert = orage_toolbar_append_button(apptw->Toolbar , "gtk-revert-to-saved", apptw->Tooltips, _("Revert"), i++); apptw->Duplicate = orage_toolbar_append_button(apptw->Toolbar , "gtk-copy", apptw->Tooltips, _("Duplicate"), i++); toolbar_separator = orage_toolbar_append_separator(apptw->Toolbar, i++); apptw->Delete = orage_toolbar_append_button(apptw->Toolbar , "gtk-delete", apptw->Tooltips, _("Delete"), i++); g_signal_connect((gpointer)apptw->Save, "clicked" , G_CALLBACK(on_appSave_clicked_cb), apptw); g_signal_connect((gpointer)apptw->SaveClose, "clicked" , G_CALLBACK(on_appSaveClose_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Revert, "clicked" , G_CALLBACK(on_appRevert_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Duplicate, "clicked" , G_CALLBACK(on_appDuplicate_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Delete, "clicked" , G_CALLBACK(on_appDelete_clicked_cb), apptw); } static void build_general_page(appt_win *apptw) { gint row; GtkWidget *label, *event, *hbox; char *availability_array[2] = {_("Free"), _("Busy")}; apptw->TableGeneral = orage_table_new(11, BORDER_SIZE); apptw->General_notebook_page = apptw->TableGeneral; apptw->General_tab_label = gtk_label_new(_("General")); gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook) , apptw->General_notebook_page, apptw->General_tab_label); /* type */ apptw->Type_label = gtk_label_new(_("Type ")); hbox = gtk_hbox_new(FALSE, 0); apptw->Type_event_rb = gtk_radio_button_new_with_label(NULL, _("Event")); gtk_box_pack_start(GTK_BOX(hbox), apptw->Type_event_rb, FALSE, FALSE, 15); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Type_event_rb , _("Event that will happen sometime. For example:\nMeeting or birthday or TV show."), NULL); apptw->Type_todo_rb = gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON(apptw->Type_event_rb) , _("Todo")); gtk_box_pack_start(GTK_BOX(hbox), apptw->Type_todo_rb, FALSE, FALSE, 15); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Type_todo_rb , _("Something that you should do sometime. For example:\nWash your car or test new version of Orage."), NULL); apptw->Type_journal_rb = gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON(apptw->Type_event_rb) , _("Journal")); gtk_box_pack_start(GTK_BOX(hbox), apptw->Type_journal_rb , FALSE, FALSE, 15); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Type_journal_rb , _("Make a note that something happened. For example:\nRemark that your mother called or first snow came."), NULL); orage_table_add_row(apptw->TableGeneral , apptw->Type_label, hbox , row = 0, (GTK_EXPAND | GTK_FILL), (0)); /* title */ apptw->Title_label = gtk_label_new(_("Title ")); apptw->Title_entry = gtk_entry_new(); orage_table_add_row(apptw->TableGeneral , apptw->Title_label, apptw->Title_entry , ++row, (GTK_EXPAND | GTK_FILL), (0)); /* location */ apptw->Location_label = gtk_label_new(_("Location")); apptw->Location_entry = gtk_entry_new(); orage_table_add_row(apptw->TableGeneral , apptw->Location_label, apptw->Location_entry , ++row, (GTK_EXPAND | GTK_FILL), (0)); /* All day */ apptw->AllDay_checkbutton = gtk_check_button_new_with_mnemonic(_("All day event")); orage_table_add_row(apptw->TableGeneral , NULL, apptw->AllDay_checkbutton , ++row, (GTK_EXPAND | GTK_FILL), (0)); /* start time */ apptw->Start_label = gtk_label_new(_("Start")); apptw->StartDate_button = gtk_button_new(); apptw->StartTime_spin_hh = gtk_spin_button_new_with_range(0, 23, 1); apptw->StartTime_spin_mm = gtk_spin_button_new_with_range(0, 59, 1); apptw->StartTimezone_button = gtk_button_new(); apptw->StartTime_hbox = datetime_hbox_new( apptw->StartDate_button, apptw->StartTime_spin_hh, apptw->StartTime_spin_mm, apptw->StartTimezone_button); orage_table_add_row(apptw->TableGeneral , apptw->Start_label, apptw->StartTime_hbox , ++row, (GTK_SHRINK | GTK_FILL), (GTK_SHRINK | GTK_FILL)); /* end time */ apptw->End_label = gtk_label_new(_("End")); apptw->End_hbox = gtk_hbox_new(FALSE, 0); /* translators: leave some spaces after this so that it looks better on * the screen */ apptw->End_checkbutton = gtk_check_button_new_with_mnemonic(_("Set ")); gtk_box_pack_start(GTK_BOX(apptw->End_hbox) , apptw->End_checkbutton, FALSE, FALSE, 0); apptw->EndDate_button = gtk_button_new(); apptw->EndTime_spin_hh = gtk_spin_button_new_with_range(0, 23, 1); apptw->EndTime_spin_mm = gtk_spin_button_new_with_range(0, 59, 1); apptw->EndTimezone_button = gtk_button_new(); apptw->EndTime_hbox = datetime_hbox_new( apptw->EndDate_button, apptw->EndTime_spin_hh, apptw->EndTime_spin_mm, apptw->EndTimezone_button); gtk_box_pack_end(GTK_BOX(apptw->End_hbox) , apptw->EndTime_hbox, TRUE, TRUE, 0); orage_table_add_row(apptw->TableGeneral , apptw->End_label, apptw->End_hbox , ++row, (GTK_SHRINK | GTK_FILL), (GTK_SHRINK | GTK_FILL)); /* duration */ apptw->Dur_hbox = gtk_hbox_new(FALSE, 0); apptw->Dur_checkbutton = gtk_check_button_new_with_mnemonic(_("Duration")); gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), apptw->Dur_checkbutton , FALSE, FALSE, 0); apptw->Dur_spin_dd = gtk_spin_button_new_with_range(0, 1000, 1); apptw->Dur_spin_dd_label = gtk_label_new(_("days")); apptw->Dur_spin_hh = gtk_spin_button_new_with_range(0, 23, 1); apptw->Dur_spin_hh_label = gtk_label_new(_("hours")); apptw->Dur_spin_mm = gtk_spin_button_new_with_range(0, 59, 5); apptw->Dur_spin_mm_label = gtk_label_new(_("mins")); apptw->Dur_time_hbox = period_hbox_new(TRUE, FALSE , apptw->Dur_spin_dd, apptw->Dur_spin_dd_label , apptw->Dur_spin_hh, apptw->Dur_spin_hh_label , apptw->Dur_spin_mm, apptw->Dur_spin_mm_label); gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), apptw->Dur_time_hbox , FALSE, FALSE, 0); orage_table_add_row(apptw->TableGeneral , NULL, apptw->Dur_hbox , ++row, (GTK_FILL), (GTK_FILL)); /* Availability (only for EVENT) */ apptw->Availability_label = gtk_label_new(_("Availability")); apptw->Availability_cb = orage_create_combo_box_with_content( availability_array, 2); orage_table_add_row(apptw->TableGeneral , apptw->Availability_label, apptw->Availability_cb , ++row, (GTK_FILL), (GTK_FILL)); /* completed (only for TODO) */ apptw->Completed_label = gtk_label_new(_("Completed")); apptw->Completed_hbox = gtk_hbox_new(FALSE, 0); apptw->Completed_checkbutton = gtk_check_button_new_with_mnemonic(_("Done")); gtk_box_pack_start(GTK_BOX(apptw->Completed_hbox) , apptw->Completed_checkbutton, FALSE, FALSE, 0); label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(apptw->Completed_hbox), label, FALSE, FALSE, 4); apptw->CompletedDate_button = gtk_button_new(); apptw->CompletedTime_spin_hh = gtk_spin_button_new_with_range(0, 23, 1); apptw->CompletedTime_spin_mm = gtk_spin_button_new_with_range(0, 59, 1); apptw->CompletedTimezone_button = gtk_button_new(); apptw->CompletedTime_hbox = datetime_hbox_new( apptw->CompletedDate_button, apptw->CompletedTime_spin_hh, apptw->CompletedTime_spin_mm, apptw->CompletedTimezone_button); gtk_box_pack_end(GTK_BOX(apptw->Completed_hbox) , apptw->CompletedTime_hbox, TRUE, TRUE, 0); orage_table_add_row(apptw->TableGeneral , apptw->Completed_label, apptw->Completed_hbox , ++row, (GTK_FILL), (GTK_FILL)); /* categories */ apptw->Categories_label = gtk_label_new(_("Categories")); apptw->Categories_hbox = gtk_hbox_new(FALSE, 0); apptw->Categories_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(apptw->Categories_hbox), apptw->Categories_entry , TRUE, TRUE, 0); apptw->Categories_cb = gtk_combo_box_new_text(); apptw->Categories_cb_event = gtk_event_box_new(); /* needed for tooltips */ gtk_container_add(GTK_CONTAINER(apptw->Categories_cb_event) , apptw->Categories_cb); gtk_box_pack_start(GTK_BOX(apptw->Categories_hbox) , apptw->Categories_cb_event, FALSE, FALSE, 4); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Categories_cb_event , _("This is special category, which can be used to color this appointment in list views."), NULL); apptw->Categories_button =gtk_button_new_from_stock(GTK_STOCK_SELECT_COLOR); gtk_box_pack_start(GTK_BOX(apptw->Categories_hbox), apptw->Categories_button , FALSE, FALSE, 0); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Categories_button , _("update colors for categories."), NULL); orage_table_add_row(apptw->TableGeneral , apptw->Categories_label, apptw->Categories_hbox , ++row, (GTK_EXPAND | GTK_FILL), (0)); /* note */ apptw->Note = gtk_label_new(_("Note")); apptw->Note_Scrolledwindow = gtk_scrolled_window_new(NULL, NULL); event = gtk_event_box_new(); /* only needed for tooltips */ gtk_container_add(GTK_CONTAINER(event), apptw->Note_Scrolledwindow); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(apptw->Note_Scrolledwindow) , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(apptw->Note_Scrolledwindow), GTK_SHADOW_IN); apptw->Note_buffer = gtk_text_buffer_new(NULL); apptw->Note_textview = gtk_text_view_new_with_buffer(GTK_TEXT_BUFFER(apptw->Note_buffer)); gtk_container_add(GTK_CONTAINER(apptw->Note_Scrolledwindow) , apptw->Note_textview); orage_table_add_row(apptw->TableGeneral , apptw->Note, event , ++row, (GTK_EXPAND | GTK_FILL), (GTK_EXPAND | GTK_FILL)); gtk_tooltips_set_tip(apptw->Tooltips, event , _(" inserts current date in local date format.\n inserts time and\n
inserts date and time."), NULL); g_signal_connect((gpointer)apptw->Type_event_rb, "clicked" , G_CALLBACK(app_type_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Type_todo_rb, "clicked" , G_CALLBACK(app_type_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Type_journal_rb, "clicked" , G_CALLBACK(app_type_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->AllDay_checkbutton, "clicked" , G_CALLBACK(app_time_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->StartDate_button, "clicked" , G_CALLBACK(on_Date_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->StartTime_spin_hh, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->StartTime_spin_mm, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->StartTimezone_button, "clicked" , G_CALLBACK(on_appStartTimezone_clicked_cb), apptw); g_signal_connect((gpointer)apptw->End_checkbutton, "clicked" , G_CALLBACK(app_time_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->EndDate_button, "clicked" , G_CALLBACK(on_Date_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->EndTime_spin_hh, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->EndTime_spin_mm, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->EndTimezone_button, "clicked" , G_CALLBACK(on_appEndTimezone_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Dur_checkbutton, "clicked" , G_CALLBACK(app_time_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Dur_spin_dd, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Dur_spin_hh, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Dur_spin_mm, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Completed_checkbutton, "clicked" , G_CALLBACK(app_time_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->CompletedDate_button, "clicked" , G_CALLBACK(on_Date_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->CompletedTime_spin_hh, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->CompletedTime_spin_mm, "changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->CompletedTimezone_button, "clicked" , G_CALLBACK(on_appCompletedTimezone_clicked_cb), apptw); /* Take care of the title entry to build the appointment window title */ g_signal_connect((gpointer)apptw->Title_entry, "changed" , G_CALLBACK(on_appTitle_entry_changed_cb), apptw); g_signal_connect((gpointer)apptw->Location_entry, "changed" , G_CALLBACK(on_app_entry_changed_cb), apptw); g_signal_connect((gpointer)apptw->Categories_entry, "changed" , G_CALLBACK(on_app_entry_changed_cb), apptw); g_signal_connect((gpointer)apptw->Categories_cb, "changed" , G_CALLBACK(on_app_combobox_changed_cb), apptw); g_signal_connect((gpointer)apptw->Categories_button, "clicked" , G_CALLBACK(on_categories_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Availability_cb, "changed" , G_CALLBACK(on_app_combobox_changed_cb), apptw); g_signal_connect((gpointer)apptw->Note_buffer, "changed" , G_CALLBACK(on_appNote_buffer_changed_cb), apptw); } static void build_alarm_page(appt_win *apptw) { gint row; GtkWidget *label, *event; char *when_array[4] = {_("Before Start"), _("Before End") , _("After Start"), _("After End")}; /***** Header *****/ apptw->TableAlarm = orage_table_new(8, BORDER_SIZE); apptw->Alarm_notebook_page = apptw->TableAlarm; apptw->Alarm_tab_label = gtk_label_new(_("Alarm")); gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook) , apptw->Alarm_notebook_page, apptw->Alarm_tab_label); /***** ALARM TIME *****/ apptw->Alarm_label = gtk_label_new(_("Alarm time")); apptw->Alarm_hbox = gtk_hbox_new(FALSE, 0); apptw->Alarm_spin_dd = gtk_spin_button_new_with_range(0, 100, 1); apptw->Alarm_spin_dd_label = gtk_label_new(_("days")); apptw->Alarm_spin_hh = gtk_spin_button_new_with_range(0, 23, 1); apptw->Alarm_spin_hh_label = gtk_label_new(_("hours")); apptw->Alarm_spin_mm = gtk_spin_button_new_with_range(0, 59, 5); apptw->Alarm_spin_mm_label = gtk_label_new(_("mins")); apptw->Alarm_time_hbox = period_hbox_new(FALSE, TRUE , apptw->Alarm_spin_dd, apptw->Alarm_spin_dd_label , apptw->Alarm_spin_hh, apptw->Alarm_spin_hh_label , apptw->Alarm_spin_mm, apptw->Alarm_spin_mm_label); gtk_box_pack_start(GTK_BOX(apptw->Alarm_hbox), apptw->Alarm_time_hbox , FALSE, FALSE, 0); apptw->Alarm_when_cb = orage_create_combo_box_with_content(when_array, 4); event = gtk_event_box_new(); /* only needed for tooltips */ gtk_container_add(GTK_CONTAINER(event), apptw->Alarm_when_cb); gtk_box_pack_start(GTK_BOX(apptw->Alarm_hbox) , event, FALSE, FALSE, 0); orage_table_add_row(apptw->TableAlarm , apptw->Alarm_label, apptw->Alarm_hbox , row = 0, (GTK_FILL), (GTK_FILL)); gtk_tooltips_set_tip(apptw->Tooltips, event , _("Often you want to get alarm:\n 1) before Event start\n 2) before Todo end\n 3) after Todo start"), NULL); /***** Persistent Alarm *****/ apptw->Per_hbox = gtk_hbox_new(FALSE, 6); apptw->Per_checkbutton = gtk_check_button_new_with_mnemonic(_("Persistent alarm")); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Per_checkbutton , _("Select this if you want Orage to remind you even if it has not been active when the alarm happened."), NULL); gtk_box_pack_start(GTK_BOX(apptw->Per_hbox), apptw->Per_checkbutton , FALSE, TRUE, 0); orage_table_add_row(apptw->TableAlarm , NULL, apptw->Per_hbox , ++row, (GTK_FILL), (GTK_FILL)); /***** Audio Alarm *****/ apptw->Sound_label = gtk_label_new(_("Sound")); apptw->Sound_hbox = gtk_hbox_new(FALSE, 6); apptw->Sound_checkbutton = gtk_check_button_new_with_mnemonic(_("Use")); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Sound_checkbutton , _("Select this if you want audible alarm"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Sound_hbox), apptw->Sound_checkbutton , FALSE, TRUE, 0); apptw->Sound_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(apptw->Sound_hbox), apptw->Sound_entry , TRUE, TRUE, 0); apptw->Sound_button = gtk_button_new_from_stock("gtk-open"); gtk_box_pack_start(GTK_BOX(apptw->Sound_hbox), apptw->Sound_button , FALSE, TRUE, 0); orage_table_add_row(apptw->TableAlarm , apptw->Sound_label, apptw->Sound_hbox , ++row, (GTK_FILL), (GTK_FILL)); apptw->SoundRepeat_hbox = gtk_hbox_new(FALSE, 0); apptw->SoundRepeat_checkbutton = gtk_check_button_new_with_mnemonic(_("Repeat alarm sound")); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox) , apptw->SoundRepeat_checkbutton , FALSE, FALSE, 0); label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox), label , FALSE, FALSE, 10); apptw->SoundRepeat_spin_cnt = gtk_spin_button_new_with_range(1, 999, 10); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_cnt) , TRUE); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox) , apptw->SoundRepeat_spin_cnt , FALSE, FALSE, 0); apptw->SoundRepeat_spin_cnt_label = gtk_label_new(_("times")); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox) , apptw->SoundRepeat_spin_cnt_label , FALSE, FALSE, 5); label = gtk_label_new(" "); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox), label , FALSE, FALSE, 10); apptw->SoundRepeat_spin_len = gtk_spin_button_new_with_range(1, 250, 1); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->SoundRepeat_spin_len) , TRUE); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox) , apptw->SoundRepeat_spin_len , FALSE, FALSE, 0); apptw->SoundRepeat_spin_len_label = gtk_label_new(_("sec interval")); gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox) , apptw->SoundRepeat_spin_len_label , FALSE, FALSE, 5); orage_table_add_row(apptw->TableAlarm , NULL, apptw->SoundRepeat_hbox , ++row, (GTK_EXPAND | GTK_FILL), (0)); /***** Display Alarm *****/ apptw->Display_label = gtk_label_new(_("Visual")); apptw->Display_hbox_orage = gtk_hbox_new(FALSE, 0); apptw->Display_checkbutton_orage = gtk_check_button_new_with_mnemonic(_("Use Orage window")); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Display_checkbutton_orage , _("Select this if you want Orage window alarm"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Display_hbox_orage) , apptw->Display_checkbutton_orage , FALSE, TRUE, 0); orage_table_add_row(apptw->TableAlarm , apptw->Display_label, apptw->Display_hbox_orage , ++row, (GTK_EXPAND | GTK_FILL), (0)); #ifdef HAVE_NOTIFY apptw->Display_hbox_notify = gtk_hbox_new(FALSE, 0); apptw->Display_checkbutton_notify = gtk_check_button_new_with_mnemonic(_("Use notification")); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Display_checkbutton_notify , _("Select this if you want notification alarm"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Display_hbox_notify) , apptw->Display_checkbutton_notify , FALSE, TRUE, 0); apptw->Display_checkbutton_expire_notify = gtk_check_button_new_with_mnemonic(_("Set timeout")); gtk_tooltips_set_tip(apptw->Tooltips , apptw->Display_checkbutton_expire_notify , _("Select this if you want notification to expire automatically") , NULL); gtk_box_pack_start(GTK_BOX(apptw->Display_hbox_notify) , apptw->Display_checkbutton_expire_notify , FALSE, TRUE, 10); apptw->Display_spin_expire_notify = gtk_spin_button_new_with_range(0, 999, 1); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Display_spin_expire_notify) , TRUE); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Display_spin_expire_notify , _("0 = system default expiration time"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Display_hbox_notify) , apptw->Display_spin_expire_notify , FALSE, TRUE, 10); apptw->Display_spin_expire_notify_label = gtk_label_new(_("seconds")); gtk_box_pack_start(GTK_BOX(apptw->Display_hbox_notify) , apptw->Display_spin_expire_notify_label , FALSE, TRUE, 0); orage_table_add_row(apptw->TableAlarm , NULL, apptw->Display_hbox_notify , ++row, (GTK_EXPAND | GTK_FILL), (0)); #endif /***** Procedure Alarm *****/ apptw->Proc_label = gtk_label_new(_("Procedure")); apptw->Proc_hbox = gtk_hbox_new(FALSE, 6); apptw->Proc_checkbutton = gtk_check_button_new_with_mnemonic(_("Use")); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Proc_checkbutton , _("Select this if you want procedure or script alarm"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Proc_hbox), apptw->Proc_checkbutton , FALSE, TRUE, 0); apptw->Proc_entry = gtk_entry_new(); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Proc_entry , _("You must enter all escape etc characters yourself.\n This string is just given to shell to process"), NULL); gtk_box_pack_start(GTK_BOX(apptw->Proc_hbox), apptw->Proc_entry , TRUE, TRUE, 0); orage_table_add_row(apptw->TableAlarm , apptw->Proc_label, apptw->Proc_hbox , ++row, (GTK_FILL), (GTK_FILL)); /***** Default Alarm Settings *****/ apptw->Default_label = gtk_label_new(_("Default alarm")); apptw->Default_hbox = gtk_hbox_new(FALSE, 6); apptw->Default_savebutton =gtk_button_new_from_stock("gtk-save"); gtk_box_pack_start(GTK_BOX(apptw->Default_hbox), apptw->Default_savebutton , FALSE, FALSE, 0); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Default_savebutton , _("Store current settings as default alarm"), NULL); apptw->Default_readbutton =gtk_button_new_from_stock("gtk-revert-to-saved"); gtk_box_pack_start(GTK_BOX(apptw->Default_hbox), apptw->Default_readbutton , FALSE, TRUE, 0); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Default_readbutton , _("Set current settings from default alarm"), NULL); orage_table_add_row(apptw->TableAlarm , apptw->Default_label, apptw->Default_hbox , ++row, (GTK_FILL), (GTK_FILL)); gtk_table_set_row_spacing(GTK_TABLE(apptw->TableAlarm), row-1, 50); g_signal_connect((gpointer)apptw->Alarm_spin_dd, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Alarm_spin_hh, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Alarm_spin_mm, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Alarm_when_cb, "changed" , G_CALLBACK(on_app_combobox_changed_cb), apptw); g_signal_connect((gpointer)apptw->Sound_checkbutton, "clicked" , G_CALLBACK(app_sound_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Sound_entry, "changed" , G_CALLBACK(on_app_entry_changed_cb), apptw); g_signal_connect((gpointer)apptw->Sound_button, "clicked" , G_CALLBACK(on_appSound_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->SoundRepeat_checkbutton, "clicked" , G_CALLBACK(app_sound_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->SoundRepeat_spin_cnt, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->SoundRepeat_spin_len, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Display_checkbutton_orage, "clicked" , G_CALLBACK(app_checkbutton_clicked_cb), apptw); #ifdef HAVE_NOTIFY g_signal_connect((gpointer)apptw->Display_checkbutton_notify, "clicked" , G_CALLBACK(app_notify_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Display_checkbutton_expire_notify , "clicked" , G_CALLBACK(app_notify_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Display_spin_expire_notify , "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); #endif g_signal_connect((gpointer)apptw->Proc_checkbutton, "clicked" , G_CALLBACK(app_proc_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Proc_entry, "changed" , G_CALLBACK(on_app_entry_changed_cb), apptw); g_signal_connect((gpointer)apptw->Default_savebutton, "clicked" , G_CALLBACK(on_appDefault_save_button_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Default_readbutton, "clicked" , G_CALLBACK(on_appDefault_read_button_clicked_cb), apptw); } static void build_recurrence_page(appt_win *apptw) { gint row, i; char *recur_freq_array[5] = { _("None"), _("Daily"), _("Weekly"), _("Monthly"), _("Yearly")}; char *weekday_array[7] = { _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")}; apptw->TableRecur = orage_table_new(8, BORDER_SIZE); apptw->Recur_notebook_page = apptw->TableRecur; apptw->Recur_tab_label = gtk_label_new(_("Recurrence")); gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook) , apptw->Recur_notebook_page, apptw->Recur_tab_label); apptw->Recur_feature_label = gtk_label_new(_("Complexity")); apptw->Recur_feature_hbox = gtk_hbox_new(FALSE, 0); apptw->Recur_feature_normal_rb = gtk_radio_button_new_with_label(NULL , _("Basic")); gtk_box_pack_start(GTK_BOX(apptw->Recur_feature_hbox) , apptw->Recur_feature_normal_rb, FALSE, FALSE, 15); apptw->Recur_feature_advanced_rb = gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON(apptw->Recur_feature_normal_rb) , _("Advanced")); gtk_box_pack_start(GTK_BOX(apptw->Recur_feature_hbox) , apptw->Recur_feature_advanced_rb, FALSE, FALSE, 15); orage_table_add_row(apptw->TableRecur , apptw->Recur_feature_label, apptw->Recur_feature_hbox , row = 0, (GTK_EXPAND | GTK_FILL), (0)); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_feature_normal_rb , _("Use this if you want regular repeating event"), NULL); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_feature_advanced_rb , _("Use this if you need complex times like:\n Every Saturday and Sunday or \n First Tuesday every month") , NULL); apptw->Recur_freq_label = gtk_label_new(_("Frequency")); apptw->Recur_freq_hbox = gtk_hbox_new(FALSE, 0); apptw->Recur_freq_cb = orage_create_combo_box_with_content( recur_freq_array, 5); gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox) , apptw->Recur_freq_cb, FALSE, FALSE, 15); apptw->Recur_int_spin_label1 = gtk_label_new(_("Each")); gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox) , apptw->Recur_int_spin_label1, FALSE, FALSE, 0); apptw->Recur_int_spin = gtk_spin_button_new_with_range(1, 100, 1); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Recur_int_spin), TRUE); gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox) , apptw->Recur_int_spin, FALSE, FALSE, 5); apptw->Recur_int_spin_label2 = gtk_label_new(_("occurrence")); gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox) , apptw->Recur_int_spin_label2, FALSE, FALSE, 0); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_int_spin , _("Limit frequency to certain interval.\n For example: Every third day:\n Frequency = Daily and Interval = 3") , NULL); orage_table_add_row(apptw->TableRecur , apptw->Recur_freq_label, apptw->Recur_freq_hbox , ++row, (GTK_EXPAND | GTK_FILL), (GTK_FILL)); apptw->Recur_limit_label = gtk_label_new(_("Limit")); apptw->Recur_limit_rb = gtk_radio_button_new_with_label(NULL , _("Repeat forever")); orage_table_add_row(apptw->TableRecur , apptw->Recur_limit_label, apptw->Recur_limit_rb , ++row, (GTK_EXPAND | GTK_FILL), (0)); apptw->Recur_count_hbox = gtk_hbox_new(FALSE, 0); apptw->Recur_count_rb = gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON(apptw->Recur_limit_rb), _("Repeat ")); gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox) , apptw->Recur_count_rb, FALSE, FALSE, 0); apptw->Recur_count_spin = gtk_spin_button_new_with_range(1, 100, 1); gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Recur_count_spin) , TRUE); gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox) , apptw->Recur_count_spin, FALSE, FALSE, 0); apptw->Recur_count_label = gtk_label_new(_("times")); gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox) , apptw->Recur_count_label, FALSE, FALSE, 5); orage_table_add_row(apptw->TableRecur , NULL, apptw->Recur_count_hbox , ++row, (GTK_EXPAND | GTK_FILL), (0)); apptw->Recur_until_hbox = gtk_hbox_new(FALSE, 0); apptw->Recur_until_rb = gtk_radio_button_new_with_mnemonic_from_widget( GTK_RADIO_BUTTON(apptw->Recur_limit_rb), _("Repeat until ")); gtk_box_pack_start(GTK_BOX(apptw->Recur_until_hbox) , apptw->Recur_until_rb, FALSE, FALSE, 0); apptw->Recur_until_button = gtk_button_new(); gtk_box_pack_start(GTK_BOX(apptw->Recur_until_hbox) , apptw->Recur_until_button, FALSE, FALSE, 0); orage_table_add_row(apptw->TableRecur , NULL, apptw->Recur_until_hbox , ++row, (GTK_EXPAND | GTK_FILL), (0)); apptw->Recur_byday_label = gtk_label_new(_("Weekdays")); apptw->Recur_byday_hbox = gtk_hbox_new(TRUE, 0); for (i=0; i <= 6; i++) { apptw->Recur_byday_cb[i] = gtk_check_button_new_with_mnemonic(weekday_array[i]); gtk_box_pack_start(GTK_BOX(apptw->Recur_byday_hbox) , apptw->Recur_byday_cb[i], FALSE, FALSE, 0); } orage_table_add_row(apptw->TableRecur , apptw->Recur_byday_label, apptw->Recur_byday_hbox , ++row, (GTK_EXPAND | GTK_FILL), (0)); apptw->Recur_byday_spin_label = gtk_label_new(_("Which day")); apptw->Recur_byday_spin_hbox = gtk_hbox_new(TRUE, 0); for (i=0; i <= 6; i++) { apptw->Recur_byday_spin[i] = gtk_spin_button_new_with_range(-9, 9, 1); gtk_box_pack_start(GTK_BOX(apptw->Recur_byday_spin_hbox) , apptw->Recur_byday_spin[i], FALSE, FALSE, 0); gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_byday_spin[i] , _("Specify which weekday for monthly and yearly events.\n For example:\n Second Wednesday each month:\n\tFrequency = Monthly,\n\tWeekdays = check only Wednesday,\n\tWhich day = select 2 from the number below Wednesday") , NULL); } orage_table_add_row(apptw->TableRecur , apptw->Recur_byday_spin_label, apptw->Recur_byday_spin_hbox , ++row ,(GTK_EXPAND | GTK_FILL), (0)); g_signal_connect((gpointer)apptw->Recur_feature_normal_rb, "clicked" , G_CALLBACK(app_recur_feature_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_feature_advanced_rb, "clicked" , G_CALLBACK(app_recur_feature_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_freq_cb, "changed" , G_CALLBACK(on_freq_combobox_changed_cb), apptw); g_signal_connect((gpointer)apptw->Recur_int_spin, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Recur_limit_rb, "clicked" , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_count_rb, "clicked" , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_count_spin, "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); g_signal_connect((gpointer)apptw->Recur_until_rb, "clicked" , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_until_button, "clicked" , G_CALLBACK(on_Date_button_clicked_cb), apptw); for (i=0; i <= 6; i++) { g_signal_connect((gpointer)apptw->Recur_byday_cb[i], "clicked" , G_CALLBACK(app_checkbutton_clicked_cb), apptw); g_signal_connect((gpointer)apptw->Recur_byday_spin[i], "value-changed" , G_CALLBACK(on_app_spin_button_changed_cb), apptw); } } appt_win *create_appt_win(char *action, char *par) { appt_win *apptw; GdkWindow *window; /* initialisation + main window + base vbox */ apptw = g_new(appt_win, 1); apptw->xf_uid = NULL; apptw->par = NULL; apptw->xf_appt = NULL; apptw->el = NULL; apptw->dw = NULL; apptw->appointment_changed = FALSE; apptw->Tooltips = gtk_tooltips_new(); apptw->accel_group = gtk_accel_group_new(); apptw->Window = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* gtk_window_set_default_size(GTK_WINDOW(apptw->Window), 450, 325); */ gtk_window_add_accel_group(GTK_WINDOW(apptw->Window), apptw->accel_group); apptw->Vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(apptw->Window), apptw->Vbox); build_menu(apptw); build_toolbar(apptw); /* ********** Here begins tabs ********** */ apptw->Notebook = gtk_notebook_new(); gtk_container_add(GTK_CONTAINER(apptw->Vbox), apptw->Notebook); gtk_container_set_border_width(GTK_CONTAINER (apptw->Notebook), 5); build_general_page(apptw); build_alarm_page(apptw); build_recurrence_page(apptw); g_signal_connect((gpointer)apptw->Window, "delete-event" , G_CALLBACK(on_appWindow_delete_event_cb), apptw); fill_appt_window(apptw, action, par); if (apptw->xf_appt) { /* all fine */ gtk_widget_show_all(apptw->Window); recur_hide_show(apptw); type_hide_show(apptw); gtk_widget_grab_focus(apptw->Title_entry); window = GTK_WIDGET(apptw->Window)->window; gdk_x11_window_set_user_time(window, gdk_x11_get_server_time(window)); gtk_window_present(GTK_WINDOW(apptw->Window)); } else { /* failed to get data */ app_free_memory(apptw); apptw = NULL; } return(apptw); }