Updating branch refs/heads/master to f0cbd5803f2337ccde785bf361418dbf95cb157e (commit) from ad5e9499b3a7b0b9a3cfc42d8c3b2c99ba39e19f (commit)
commit f0cbd5803f2337ccde785bf361418dbf95cb157e Author: Juha Kautto <j...@xfce.org> Date: Fri Nov 15 10:04:58 2013 +0200 4.9.8.0 Enhancement 9291 detect external changes orage file Orage now accepts external changes to all calendar files. Previously only foreign files could be refreshed externally. configure.in.in | 2 +- src/appointment.c | 59 +++++++++++++++++++++++++++------------- src/ical-code.c | 77 +++++++++++++++++++++++++++++++++++++++++------------ src/interface.c | 51 ++++++++++++++++++++++------------- src/interface.h | 2 +- src/main.c | 5 ++-- src/parameters.h | 2 ++ 7 files changed, 138 insertions(+), 60 deletions(-) diff --git a/configure.in.in b/configure.in.in index df604f8..f9c2f5d 100644 --- a/configure.in.in +++ b/configure.in.in @@ -9,7 +9,7 @@ dnl Written for Xfce by Juha Kautto <j...@xfce.org> dnl dnl Version information -m4_define([orage_version], [4.9.7.3-git]) +m4_define([orage_version], [4.9.8.0-git]) m4_define([gtk_minimum_version], [2.14.0]) m4_define([xfce_minimum_version], [4.8.0]) diff --git a/src/appointment.c b/src/appointment.c index bdbc14b..87eaae8 100644 --- a/src/appointment.c +++ b/src/appointment.c @@ -87,7 +87,7 @@ static void read_default_alarm(xfical_appt *appt); /* * these are the main functions in this file: */ -static void fill_appt_window(appt_win *apptw, char *action, char *par); +static gboolean fill_appt_window(appt_win *apptw, char *action, char *par); static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw); @@ -1122,13 +1122,18 @@ static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw) static gboolean save_xfical_from_appt_win(appt_win *apptw) { +#undef P_N +#define P_N "save_xfical_from_appt_win: " + gint result; 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)) + if (!xfical_file_open(TRUE)) { + orage_message(150, P_N "file open and update failed: %s", apptw->xf_uid); return(FALSE); + } if (apptw->appointment_add) { apptw->xf_uid = g_strdup(xfical_appt_add(appt)); ok = (apptw->xf_uid ? TRUE : FALSE); @@ -1138,15 +1143,23 @@ static gboolean save_xfical_from_appt_win(appt_win *apptw) 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 { + orage_message(150, P_N "Addition failed: %s", apptw->xf_uid); + result = orage_error_dialog(GTK_WINDOW(apptw->Window) + , _("Appointment addition failed.") + , _("Error happened when adding appointment. Look more details from the log file.")); } + } 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); + else { + orage_message(150, P_N "Modification failed: %s", apptw->xf_uid); + result = orage_error_dialog(GTK_WINDOW(apptw->Window) + , _("Appointment update failed.") + , _("Look more details from the log file. (Perhaps file was updated external from Orage?)")); + } } xfical_file_close(TRUE); if (ok) { @@ -1188,7 +1201,10 @@ static void on_appSaveClose_clicked_cb(GtkButton *b, gpointer user_data) static void delete_xfical_from_appt_win(appt_win *apptw) { +#undef P_N +#define P_N "delete_xfical_from_appt_win: " gint result; + gboolean ok = FALSE; result = orage_warning_dialog(GTK_WINDOW(apptw->Window) , _("This appointment will be permanently removed.") @@ -1198,13 +1214,15 @@ static void delete_xfical_from_appt_win(appt_win *apptw) if (result == GTK_RESPONSE_YES) { if (!apptw->appointment_add) { - if (!xfical_file_open(TRUE)) - return; - result = xfical_appt_del(apptw->xf_uid); - if (result) + if (!xfical_file_open(TRUE)) { + orage_message(150, P_N "file open and removal failed: %s", apptw->xf_uid); + return; + } + ok = xfical_appt_del(apptw->xf_uid); + if (ok) orage_message(10, "Removed: %s", apptw->xf_uid); else - g_warning("Removal failed: %s", apptw->xf_uid); + orage_message(150, P_N "Removal failed: %s", apptw->xf_uid); xfical_file_close(TRUE); } @@ -1237,8 +1255,10 @@ static void duplicate_xfical_from_appt_win(appt_win *apptw) /* 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); + if (apptw2) { + 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 @@ -2310,7 +2330,7 @@ static void fill_appt_window_recurrence(appt_win *apptw, xfical_appt *appt) } /* Fill appointment window with data */ -static void fill_appt_window(appt_win *apptw, char *action, char *par) +static gboolean fill_appt_window(appt_win *apptw, char *action, char *par) { xfical_appt *appt; struct tm *t; @@ -2318,8 +2338,7 @@ static void fill_appt_window(appt_win *apptw, char *action, char *par) /********************* INIT *********************/ orage_message(10, "%s appointment: %s", action, par); if ((appt = fill_appt_window_get_appt(apptw, action, par)) == NULL) { - apptw->xf_appt = NULL; - return; + return(FALSE); } apptw->xf_appt = appt; @@ -2345,7 +2364,9 @@ static void fill_appt_window(appt_win *apptw, char *action, char *par) } else { g_error("fill_appt_window: unknown parameter\n"); - return; + g_free(appt); + apptw->xf_appt = NULL; + return(FALSE); } if (!appt->completed) { /* some nice default */ t = orage_localtime(); /* probably completed today? */ @@ -2381,6 +2402,7 @@ static void fill_appt_window(appt_win *apptw, char *action, char *par) set_notify_sensitivity(apptw); set_proc_sensitivity(apptw); mark_appointment_unchanged(apptw); + return(TRUE); } static void build_menu(appt_win *apptw) @@ -3537,8 +3559,7 @@ appt_win *create_appt_win(char *action, char *par) 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 */ + if (fill_appt_window(apptw, action, par)) { /* all fine */ enable_general_page_signals(apptw); enable_alarm_page_signals(apptw); enable_recurrence_page_signals(apptw); diff --git a/src/ical-code.c b/src/ical-code.c index cf88623..0679fad 100644 --- a/src/ical-code.c +++ b/src/ical-code.c @@ -47,6 +47,7 @@ #include <time.h> #include <math.h> +#include <glib.h> #include <gdk/gdk.h> #include <gtk/gtk.h> #include <glib/gprintf.h> @@ -359,6 +360,7 @@ gboolean ic_internal_file_open(icalcomponent **p_ical } } } + ic_file_modified = FALSE; return(TRUE); } @@ -369,12 +371,27 @@ gboolean xfical_file_open(gboolean foreign) #define P_N "xfical_file_open: " gboolean ok; gint i; + struct stat s; #ifdef ORAGE_DEBUG orage_message(-100, P_N); #endif + /* make sure there are no external updates or they will be overwritten */ + if (g_par.latest_file_change) + orage_external_update_check(NULL); ok = ic_internal_file_open(&ic_ical, &ic_fical, g_par.orage_file, FALSE , FALSE); + /* store last access time */ + if (ok) + if (g_stat(g_par.orage_file, &s) < 0) { + orage_message(150, P_N "stat of %s failed: %d (%s)", + g_par.orage_file, errno, strerror(errno)); + g_par.latest_file_change = (time_t)0; + } + else { + g_par.latest_file_change = s.st_mtime; + } + if (ok && foreign) /* let's open foreign files */ for (i = 0; i < g_par.foreign_count; i++) { ok = ic_internal_file_open(&(ic_f_ical[i].ical) @@ -383,8 +400,21 @@ gboolean xfical_file_open(gboolean foreign) if (!ok) { ic_f_ical[i].ical = NULL; ic_f_ical[i].fical = NULL; + g_par.foreign_data[i].latest_file_change = (time_t)0; + } + else { + /* store last access time */ + if (g_stat(g_par.foreign_data[i].file, &s) < 0) { + orage_message(150, P_N "stat of %s failed: %d (%s)", + g_par.foreign_data[i].file, errno, strerror(errno)); + g_par.foreign_data[i].latest_file_change = (time_t)0; + } + else { + g_par.foreign_data[i].latest_file_change = s.st_mtime; + } } } + return(ok); } @@ -426,6 +456,7 @@ void xfical_file_close(gboolean foreign) #undef P_N #define P_N "xfical_file_close: " gint i; + struct stat s; #ifdef ORAGE_DEBUG orage_message(-100, P_N); @@ -446,8 +477,16 @@ void xfical_file_close(gboolean foreign) #ifdef ORAGE_DEBUG orage_message(-10, P_N "closing file now"); #endif - icalset_free(ic_fical); - ic_fical = NULL; + delayed_file_close(NULL); + /* store last access time */ + if (g_stat(g_par.orage_file, &s) < 0) { + orage_message(150, P_N "stat of %s failed: %d (%s)", + g_par.orage_file, errno, strerror(errno)); + g_par.latest_file_change = (time_t)0; + } + else { + g_par.latest_file_change = s.st_mtime; + } } else { /* close it later = after 10 minutes (to save time) */ #ifdef ORAGE_DEBUG @@ -465,6 +504,15 @@ void xfical_file_close(gboolean foreign) else { icalset_free(ic_f_ical[i].fical); ic_f_ical[i].fical = NULL; + /* store last access time */ + if (g_stat(g_par.foreign_data[i].file, &s) < 0) { + orage_message(150, P_N "stat of %s failed: %d (%s)", + g_par.foreign_data[i].file, errno, strerror(errno)); + g_par.foreign_data[i].latest_file_change = (time_t)0; + } + else { + g_par.foreign_data[i].latest_file_change = s.st_mtime; + } } } } @@ -477,16 +525,8 @@ void xfical_file_close_force(void) #ifdef ORAGE_DEBUG orage_message(-100, P_N); #endif - if (file_close_timer) { - /* We are closing main ical file and delayed close is in progress. - * Closing must be cancelled since we are now closing the file. */ - g_source_remove(file_close_timer); - file_close_timer = 0; -#ifdef ORAGE_DEBUG - orage_message(-10, P_N "canceling delayed close"); -#endif - } - delayed_file_close(NULL); + ic_file_modified = TRUE; + xfical_file_close(TRUE); } char *ic_get_char_timezone(icalproperty *p) @@ -2452,6 +2492,7 @@ gboolean xfical_appt_del(char *ical_uid) icalset *fbase; char *uid, *int_uid; int i; + struct stat s; #ifdef ORAGE_DEBUG orage_message(-100, P_N); @@ -2484,10 +2525,7 @@ gboolean xfical_appt_del(char *ical_uid) orage_message(260, P_N "unknown file type %s", ical_uid); return(FALSE); } - if (ical_uid == NULL) { - orage_message(130, P_N "Got NULL uid. doing nothing"); - return(FALSE); - } + for (c = icalcomponent_get_first_component(base, ICAL_ANY_COMPONENT); c != 0; c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) { @@ -3138,7 +3176,12 @@ static void xfical_alarm_build_list_internal_real(gboolean first_list_today } } /* COMPONENT */ if (first_list_today) { - orage_message(60, _("Build alarm list: Added %d alarms. Processed %d events.") + if (strcmp(file_type, "O00.") == 0) + orage_message(60, _("Created alarm list for main Orage file:")); + else + orage_message(60, _("Created alarm list for foreign file: %s") + , file_type); + orage_message(60, _("\tAdded %d alarms. Processed %d events.") , cnt_alarm_add, cnt_event); orage_message(60, _("\tFound %d alarms of which %d are active. (Searched %d recurring alarms.)") , cnt_alarm, cnt_act_alarm, cnt_repeat); diff --git a/src/interface.c b/src/interface.c index b3c623c..9fcbea9 100644 --- a/src/interface.c +++ b/src/interface.c @@ -70,39 +70,52 @@ static gboolean interface_lock = FALSE; static void refresh_foreign_files(intf_win *intf_w, gboolean first); -gboolean orage_foreign_files_check(gpointer user_data) +gboolean orage_external_update_check(gpointer user_data) { - static time_t latest_foreign_file_change = (time_t)0; +#undef P_N +#define P_N "orage_external_update_check: " struct stat s; gint i; - gboolean changes_present = FALSE; + gboolean external_changes_present = FALSE; - if (!latest_foreign_file_change) - latest_foreign_file_change = time(NULL); + /* check main Orage file */ + if (g_stat(g_par.orage_file, &s) < 0) { + orage_message(150, P_N "stat of %s failed: %d (%s)", + g_par.orage_file, errno, strerror(errno)); + } + else { + if (s.st_mtime > g_par.latest_file_change) { + g_par.latest_file_change = s.st_mtime; + orage_message(10, _("Found external update on file %s.") + , g_par.orage_file); + external_changes_present = TRUE; + } + } - /* check foreign files */ + /* check also foreign files */ for (i = 0; i < g_par.foreign_count; i++) { if (g_stat(g_par.foreign_data[i].file, &s) < 0) { - g_warning("stat of %s failed: %d (%s)", + orage_message(150, P_N "stat of %s failed: %d (%s)", g_par.foreign_data[i].file, errno, strerror(errno)); } - else if (s.st_mtime > latest_foreign_file_change) { - latest_foreign_file_change = s.st_mtime; - orage_message(40, "updating %s", g_par.foreign_data[i].file); - changes_present = TRUE; + else { + if (s.st_mtime > g_par.foreign_data[i].latest_file_change) { + g_par.foreign_data[i].latest_file_change = s.st_mtime; + orage_message(10, _("Found external update on file %s.") + , g_par.foreign_data[i].file); + external_changes_present = TRUE; + } } } - if (changes_present == TRUE) { + if (external_changes_present) { + orage_message(80, _("Refreshing alarms and calendar due to external file update.")); + xfical_file_close_force(); xfical_alarm_build_list(FALSE); orage_mark_appointments(); } - /* keep running ? */ - if (g_par.foreign_count) - return(TRUE); - else /* no need to check changes if we do not have any files */ - return(FALSE); + return(TRUE); /* keep running */ } static void orage_file_entry_changed(GtkWidget *dialog, gpointer user_data) @@ -543,6 +556,7 @@ static void orage_foreign_file_remove_line(gint del_line) for (i = del_line; i < g_par.foreign_count; i++) { g_par.foreign_data[i].file = g_par.foreign_data[i+1].file; g_par.foreign_data[i].read_only = g_par.foreign_data[i+1].read_only; + g_par.foreign_data[i].latest_file_change = g_par.foreign_data[i+1].latest_file_change; } g_par.foreign_data[i].file = NULL; @@ -666,13 +680,12 @@ static gboolean orage_foreign_file_add_internal(gchar *filename, gboolean read_o g_par.foreign_data[g_par.foreign_count].file = g_strdup(filename); g_par.foreign_data[g_par.foreign_count].read_only = read_only; + g_par.foreign_data[g_par.foreign_count].latest_file_change = (time_t)0; g_par.foreign_count++; write_parameters(); orage_mark_appointments(); xfical_alarm_build_list(FALSE); - if (g_par.foreign_count == 1) /* we just added our first foreign file */ - g_timeout_add_seconds(30, (GtkFunction)orage_foreign_files_check, NULL); return(TRUE); } diff --git a/src/interface.h b/src/interface.h index dc42b15..679a564 100644 --- a/src/interface.h +++ b/src/interface.h @@ -96,7 +96,7 @@ typedef struct _intf_win void orage_external_interface(CalWin *xfcal); -gboolean orage_foreign_files_check(gpointer user_data); +gboolean orage_external_update_check(gpointer user_data); gboolean orage_foreign_file_add(gchar *filename, gboolean read_only); gboolean orage_foreign_file_remove(gchar *filename); gboolean orage_import_file(gchar *entry_filename); diff --git a/src/main.c b/src/main.c index 089069b..08da96e 100644 --- a/src/main.c +++ b/src/main.c @@ -619,9 +619,8 @@ int main(int argc, char *argv[]) mCalendar_month_changed_cb( (GtkCalendar *)((CalWin *)g_par.xfcal)->mCalendar, NULL); - /* start monitoring foreign file updates if we have foreign files */ - if (g_par.foreign_count) - g_timeout_add_seconds(30, (GtkFunction)orage_foreign_files_check, NULL); + /* start monitoring external file updates */ + g_timeout_add_seconds(30, (GtkFunction)orage_external_update_check, NULL); /* let's check if I got filename as a parameter */ initialized = TRUE; diff --git a/src/parameters.h b/src/parameters.h index 443dd09..849ef2e 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -29,6 +29,7 @@ typedef struct _foreign_file { char *file; gboolean read_only; + time_t latest_file_change; } foreign_file; @@ -69,6 +70,7 @@ typedef struct _parameters /* other */ char *orage_file; + time_t latest_file_change; char *sound_application; /* List of active alarms */ _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits