[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