[Xfce4-commits] <orage:master> 4.9.8.0 Enhancement 9291 detect external changes orage file

Juha Kautto noreply at xfce.org
Fri Nov 15 09:08:01 CET 2013


Updating branch refs/heads/master
         to f0cbd5803f2337ccde785bf361418dbf95cb157e (commit)
       from ad5e9499b3a7b0b9a3cfc42d8c3b2c99ba39e19f (commit)

commit f0cbd5803f2337ccde785bf361418dbf95cb157e
Author: Juha Kautto <juha at 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 <juha at 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 */


More information about the Xfce4-commits mailing list