Author: juha
Date: 2007-12-02 21:27:59 +0000 (Sun, 02 Dec 2007)
New Revision: 26429

Modified:
   xfcalendar/trunk/configure.in.in
   xfcalendar/trunk/src/appointment.c
   xfcalendar/trunk/src/appointment.h
   xfcalendar/trunk/src/ical-code.c
   xfcalendar/trunk/src/ical-code.h
   xfcalendar/trunk/src/interface.c
   xfcalendar/trunk/src/interface.h
   xfcalendar/trunk/src/main.c
   xfcalendar/trunk/src/mainbox.c
   xfcalendar/trunk/src/reminder.c
   xfcalendar/trunk/src/reminder.h
Log:
Bug 3643: implemented persistent alarms.
It is now possible to define alarms which are raised after Orage is started
even if they were timed to happen while Orage was not running.


Modified: xfcalendar/trunk/configure.in.in
===================================================================
--- xfcalendar/trunk/configure.in.in    2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/configure.in.in    2007-12-02 21:27:59 UTC (rev 26429)
@@ -9,7 +9,7 @@
 dnl
 
 dnl Version information
-m4_define([orage_version], [4.5.11.1-svn])
+m4_define([orage_version], [4.5.11.2-svn])
 
 m4_define([gtk_minimum_version], [2.6.0])
 m4_define([xfce_minimum_version], [4.4.0])

Modified: xfcalendar/trunk/src/appointment.c
===================================================================
--- xfcalendar/trunk/src/appointment.c  2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/appointment.c  2007-12-02 21:27:59 UTC (rev 26429)
@@ -61,6 +61,10 @@
 
 
 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 void combo_box_append_array(GtkWidget *combo_box, char *text[], int 
size)
@@ -920,6 +924,10 @@
             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));
@@ -1533,7 +1541,7 @@
     /*
     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);
@@ -1545,6 +1553,11 @@
         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)

Modified: xfcalendar/trunk/src/appointment.h
===================================================================
--- xfcalendar/trunk/src/appointment.h  2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/appointment.h  2007-12-02 21:27:59 UTC (rev 26429)
@@ -111,6 +111,8 @@
     GtkWidget *Alarm_spin_mm;
     GtkWidget *Alarm_spin_mm_label;
     GtkWidget *Alarm_when_cb;
+    GtkWidget *Per_hbox;
+    GtkWidget *Per_checkbutton;
     GtkWidget *Sound_label;
     GtkWidget *Sound_hbox;
     GtkWidget *Sound_checkbutton;
@@ -136,8 +138,6 @@
     GtkWidget *Proc_hbox;
     GtkWidget *Proc_checkbutton;
     GtkWidget *Proc_entry;
-    GtkWidget *Per_hbox;
-    GtkWidget *Per_checkbutton;
 
     GtkWidget *Recur_notebook_page;
     GtkWidget *Recur_tab_label;

Modified: xfcalendar/trunk/src/ical-code.c
===================================================================
--- xfcalendar/trunk/src/ical-code.c    2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/ical-code.c    2007-12-02 21:27:59 UTC (rev 26429)
@@ -62,6 +62,7 @@
 #include "event-list.h"
 #include "appointment.h"
 #include "parameters.h"
+#include "interface.h"
 
 static void xfical_alarm_build_list_internal(gboolean first_list_today);
 
@@ -1419,6 +1420,9 @@
                 , icalproperty_vanew_trigger(trg
                         , icalparameter_new_related(ICAL_RELATED_END)
                         , 0));
+    if (appt->alarm_persistent)
+        icalcomponent_add_property(ialarm
+                , 
icalproperty_new_from_string("X-ORAGE-PERSISTENT-ALARM:YES"));
     return(ialarm);
 }
 
@@ -1751,13 +1755,13 @@
                         , icalproperty_new_completed(wtime));
             }
         }
-        if (appt->freq != XFICAL_FREQ_NONE) { /* journal has no recurrency. */
+        if (appt->freq != XFICAL_FREQ_NONE) {
             /* NOTE: according to standard VJOURNAL _has_ recurrency, 
              * but I can't understand how it coud be usefull, 
              * so Orage takes it away */
             appt_add_recur_internal(appt, icmp);
         }
-        if (appt->alarmtime != 0) { /* journal has no alarms */
+        if (appt->alarmtime != 0) {
             appt_add_alarm_internal(appt, icmp);
         }
     }
@@ -1844,16 +1848,55 @@
     return(TRUE);
 }
 
-static gboolean get_alarm_data(icalcomponent *ca,  xfical_appt *appt)
+static void get_alarm_data_x(icalcomponent *ca,  xfical_appt *appt)
 {
 #undef P_N
+#define P_N "get_alarm_data_x: "
+    icalproperty *p = NULL;
+    char *text;
+    int i;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    for (p = icalcomponent_get_first_property(ca, ICAL_X_PROPERTY);
+         p != 0;
+         p = icalcomponent_get_next_property(ca, ICAL_X_PROPERTY)) {
+        text = (char *)icalproperty_get_x_name(p);
+        if (!strcmp(text, "X-ORAGE-PERSISTENT-ALARM")) {
+            text = (char *)icalproperty_get_value_as_string(p);
+            if (!strcmp(text, "YES"))
+                appt->alarm_persistent = TRUE;
+        }
+        else if (!strcmp(text, "X-ORAGE-DISPLAY-ALARM")) {
+            text = (char *)icalproperty_get_value_as_string(p);
+            if (!strcmp(text, "ORAGE")) {
+                appt->display_alarm_orage = TRUE;
+            }
+            else if (!strcmp(text, "NOTIFY")) {
+                appt->display_alarm_notify = TRUE;
+            }
+        }
+        else if (!strcmp(text, "X-ORAGE-NOTIFY-ALARM-TIMEOUT")) {
+            text = (char *)icalproperty_get_value_as_string(p);
+            sscanf(text, "%d", &i);
+            appt->display_notify_timeout = i;
+        }
+        else {
+            g_warning(P_N "unknown X property %s", text);
+        }
+    }
+}
+
+static void get_alarm_data(icalcomponent *ca,  xfical_appt *appt)
+{
+#undef P_N
 #define P_N "get_alarm_data: "
     icalproperty *p = NULL;
     enum icalproperty_action act;
     icalattach *attach;
     struct icaldurationtype duration;
     char *text;
-    int i;
 
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
@@ -1861,39 +1904,20 @@
     p = icalcomponent_get_first_property(ca, ICAL_ACTION_PROPERTY);
     if (!p) {
         g_warning(P_N "No ACTION in alarm. Ignoring this ALARM.");
-        return(FALSE);
+        return;
     }
     act = icalproperty_get_action(p);
     if (act == ICAL_ACTION_DISPLAY) {
+        get_alarm_data_x(ca, appt);
         p = icalcomponent_get_first_property(ca, ICAL_DESCRIPTION_PROPERTY);
         if (p)
             appt->note = (char *)icalproperty_get_description(p);
-        for (p = icalcomponent_get_first_property(ca, ICAL_X_PROPERTY);
-             p != 0;
-             p = icalcomponent_get_next_property(ca, ICAL_X_PROPERTY)) {
-            text = (char *)icalproperty_get_x_name(p);
-            if (!strcmp(text, "X-ORAGE-DISPLAY-ALARM")) {
-                text = (char *)icalproperty_get_value_as_string(p);
-                if (!strcmp(text, "ORAGE")) {
-                    appt->display_alarm_orage = TRUE;
-                }
-                else if (!strcmp(text, "NOTIFY")) {
-                    appt->display_alarm_notify = TRUE;
-                }
-            }
-            else if (!strcmp(text, "X-ORAGE-NOTIFY-ALARM-TIMEOUT")) {
-                text = (char *)icalproperty_get_value_as_string(p);
-                sscanf(text, "%d", &i);
-                appt->display_notify_timeout = i;
-            }
-            else {
-                g_warning(P_N "unknown X property %s", text);
-            }
-        }
+        /* default display alarm is orage if none is set */
         if (!appt->display_alarm_orage && !appt->display_alarm_notify) 
             appt->display_alarm_orage = TRUE;
     }
     else if (act == ICAL_ACTION_AUDIO) {
+        get_alarm_data_x(ca, appt);
         p = icalcomponent_get_first_property(ca, ICAL_ATTACH_PROPERTY);
         if (p) {
             appt->sound_alarm = TRUE;
@@ -1912,6 +1936,7 @@
         }
     }
     else if (act == ICAL_ACTION_PROCEDURE) {
+        get_alarm_data_x(ca, appt);
         p = icalcomponent_get_first_property(ca, ICAL_ATTACH_PROPERTY);
         if (p) {
             appt->procedure_alarm = TRUE;
@@ -2196,15 +2221,14 @@
             /* we found our uid (=component) */
             key_found = TRUE;
         /********** Component type ********/
-            if (icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT) {
+            /* we want isolate all libical calls and features into this file,
+             * so need to remap component type to our own defines */
+            if (icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT)
                 appt.type = XFICAL_TYPE_EVENT;
-            }
-            else if (icalcomponent_isa(c) == ICAL_VTODO_COMPONENT) {
+            else if (icalcomponent_isa(c) == ICAL_VTODO_COMPONENT)
                 appt.type = XFICAL_TYPE_TODO;
-            }
-            else if (icalcomponent_isa(c) == ICAL_VJOURNAL_COMPONENT) {
+            else if (icalcomponent_isa(c) == ICAL_VJOURNAL_COMPONENT)
                 appt.type = XFICAL_TYPE_JOURNAL;
-            }
             else {
                 g_warning(P_N "Unknown component");
                 key_found = FALSE;
@@ -2228,12 +2252,18 @@
             appt.completed = FALSE;
             appt.completedtime[0] = '\0';
             appt.completed_tz_loc = NULL;
+            appt.availability = -1;
             appt.priority = 0;
             appt.note = NULL;
             appt.alarmtime = 0;
+            appt.alarm_before = TRUE;
+            appt.alarm_related_start = TRUE;
+            appt.alarm_persistent = FALSE;
             appt.sound_alarm = FALSE;
             appt.sound = NULL;
             appt.soundrepeat = FALSE;
+            appt.soundrepeat_cnt = 500;
+            appt.soundrepeat_len = 2;
             appt.display_alarm_orage = FALSE;
             appt.display_alarm_notify = FALSE;
             appt.display_notify_timeout = 0;
@@ -2242,6 +2272,7 @@
             appt.procedure_params = NULL;
             appt.starttimecur[0] = '\0';
             appt.endtimecur[0] = '\0';
+            appt.freq = XFICAL_FREQ_NONE;
             appt.recur_limit = 0;
             appt.recur_count = 0;
             appt.recur_until[0] = '\0';
@@ -2249,12 +2280,6 @@
             appt.email_alarm = FALSE;
             appt.email_attendees = NULL;
 */
-            appt.alarm_before = TRUE;
-            appt.alarm_related_start = TRUE;
-            appt.availability = -1;
-            appt.soundrepeat_cnt = 500;
-            appt.soundrepeat_len = 2;
-            appt.freq = XFICAL_FREQ_NONE;
             for (i=0; i <= 6; i++) {
                 appt.recur_byday[i] = TRUE;
                 appt.recur_byday_cnt[i] = 0;
@@ -2641,21 +2666,21 @@
 {
 #undef P_N
 #define P_N "alarm_free: "
-    alarm_struct *alarm = (alarm_struct *)galarm;;
+    alarm_struct *alarm = (alarm_struct *)galarm;
 
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
 #endif
     g_free(alarm->alarm_time);
-    g_string_free(alarm->uid, TRUE);
+    g_free(alarm->uid);
     if (alarm->title != NULL)
-        g_string_free(alarm->title, TRUE);
+        g_free(alarm->title);
     if (alarm->description != NULL)
-        g_string_free(alarm->description, TRUE);
+        g_free(alarm->description);
     if (alarm->sound != NULL)
-        g_string_free(alarm->sound, TRUE);
+        g_free(alarm->sound);
     if (alarm->cmd != NULL)
-        g_string_free(alarm->cmd, TRUE);
+        g_free(alarm->cmd);
     g_free(alarm);
 }
 
@@ -2821,17 +2846,18 @@
     appt = xfical_appt_alloc();
     get_alarm_data(ca, appt);
 
+    new_alarm->persistent = appt->alarm_persistent;
     if (appt->display_alarm_orage ||  appt->display_alarm_notify) {
         new_alarm->display_orage = appt->display_alarm_orage;
         new_alarm->display_notify = appt->display_alarm_notify;
         new_alarm->notify_timeout = appt->display_notify_timeout;
         if (ORAGE_STR_EXISTS(appt->note))
-            new_alarm->description = g_string_new(appt->note);
+            new_alarm->description = g_strdup(appt->note);
     }
     else if (appt->sound_alarm) {
         new_alarm->audio = appt->sound_alarm;
         if (ORAGE_STR_EXISTS(appt->sound))
-            new_alarm->sound = g_string_new(appt->sound);
+            new_alarm->sound = g_strdup(appt->sound);
         if (appt->soundrepeat) {
             new_alarm->repeat_cnt = appt->soundrepeat_cnt;
             new_alarm->repeat_delay = appt->soundrepeat_len;
@@ -2840,11 +2866,14 @@
     else if(appt->procedure_alarm) {
         new_alarm->procedure = appt->procedure_alarm;
         if (ORAGE_STR_EXISTS(appt->procedure_cmd)) {
-            new_alarm->cmd = g_string_new(appt->procedure_cmd);
+            new_alarm->cmd = g_strconcat(appt->procedure_cmd
+                    , appt->procedure_params, NULL);
+            /*
             if (ORAGE_STR_EXISTS(appt->procedure_params)) {
                 new_alarm->cmd = 
                         g_string_append(new_alarm->cmd, 
appt->procedure_params);
             }
+            */
         }
     }
 
@@ -2964,10 +2993,14 @@
                 new_alarm = process_alarm_trigger(c, ca, cur_time, 
&cnt_repeat);
                 if (new_alarm) {
                     trg_active = TRUE;
-                    new_alarm->uid = g_string_new(file_type);
+                    /*
+                    new_alarm->uid = g_strdup(file_type);
                     suid = (char *)icalcomponent_get_uid(c);
                     new_alarm->uid = g_string_append(new_alarm->uid, suid);
-                    new_alarm->title = g_string_new(
+                    */
+                    suid = (char *)icalcomponent_get_uid(c);
+                    new_alarm->uid = g_strconcat(file_type, suid, NULL);
+                    new_alarm->title = g_strdup(
                             (char *)icalcomponent_get_summary(c));
                 }
             }
@@ -2984,7 +3017,7 @@
         }  /* ALARM */
         if (trg_active) {
             if (!new_alarm->description)
-                new_alarm->description = g_string_new(
+                new_alarm->description = g_strdup(
                         (char *)icalcomponent_get_description(c));
             g_par.alarm_list = g_list_append(g_par.alarm_list, new_alarm);
             cnt_alarm_add++;
@@ -3023,8 +3056,11 @@
         xfical_alarm_build_list_internal_real(first_list_today, f_ical[i].ical
                 , file_type);
     }
-    setup_orage_alarm_clock();
-    build_mainbox_info();
+    setup_orage_alarm_clock(); /* keep reminders upto date */
+    build_mainbox_info();      /* refresh main calendar window todo list */
+    /* moved to reminder in setup_orage_alarm_clock
+    store_persistent_alarms(); / * keep track of alarms when orage is down * /
+    */
 }
 
 void xfical_alarm_build_list(gboolean first_list_today)
@@ -3341,7 +3377,7 @@
          c != 0;
          c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) {
         per = get_period(c);
-        if (per.ikind == ICAL_VEVENT_COMPONENT && 0 == 1) {
+        if (per.ikind == ICAL_VEVENT_COMPONENT) {
             xfical_mark_calendar_days(gtkcal, year, month
                     , per.stime.year, per.stime.month, per.stime.day
                     , per.etime.year, per.etime.month, per.etime.day);

Modified: xfcalendar/trunk/src/ical-code.h
===================================================================
--- xfcalendar/trunk/src/ical-code.h    2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/ical-code.h    2007-12-02 21:27:59 UTC (rev 26429)
@@ -44,6 +44,7 @@
 
 typedef struct _xfical_appt
 {
+    xfical_type type;
     /* note that version 4.5.9 changed uid format.
      * new format starts with 3 char source id (plus separator '.'), 
      * which tells the file where the id is found:
@@ -52,8 +53,6 @@
      * "F10." = Foreign file number 10
      */
     gchar *uid; 
-
-    xfical_type type;
     gchar *title;
     gchar *location;
 

Modified: xfcalendar/trunk/src/interface.c
===================================================================
--- xfcalendar/trunk/src/interface.c    2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/interface.c    2007-12-02 21:27:59 UTC (rev 26429)
@@ -24,6 +24,10 @@
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
 #include <string.h>
 #include <time.h>
 #include <errno.h>
@@ -43,8 +47,8 @@
 #include "parameters.h"
 
 #define FILETYPE_SIZE 2
+#define ORAGE_PERSISTENT_ALARMS "orage_persistent_alarms.txt"
 
-
 /*
 enum {
   TARGET_STRING,
@@ -80,6 +84,28 @@
 
 static void refresh_foreign_files(intf_win *intf_w, gboolean first);
 
+int orage_persistent_file_open(gboolean write)
+{
+    int p_file;
+    char *file_name;
+
+    file_name = xfce_resource_save_location(XFCE_RESOURCE_DATA
+            , ORAGE_DIR ORAGE_PERSISTENT_ALARMS, TRUE);
+    if (!file_name) {
+        g_warning("orage_persistent_file_open: Persistent alarms filename 
build failed, alarms not saved (%s)\n", file_name);
+        return(-1);
+    }
+    if (write)
+        p_file = g_open(file_name, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC
+                , S_IRUSR|S_IWUSR);
+    else
+        p_file = g_open(file_name, O_RDONLY|O_CREAT, S_IRUSR|S_IWUSR);
+    g_free(file_name);
+    if (p_file == -1) 
+        g_warning("orage_persistent_file_open: Persistent alarms file open 
failed, alarms not saved (%s)\n", file_name);
+    return(p_file);
+}
+
 gboolean orage_foreign_files_check(gpointer user_data)
 {
     static time_t latest_foreign_file_change = (time_t)0;

Modified: xfcalendar/trunk/src/interface.h
===================================================================
--- xfcalendar/trunk/src/interface.h    2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/interface.h    2007-12-02 21:27:59 UTC (rev 26429)
@@ -98,5 +98,6 @@
 gboolean orage_foreign_files_check(gpointer user_data);
 gboolean orage_foreign_file_add(gchar *filename, gboolean read_only);
 gboolean orage_foreign_file_remove(gchar *filename);
+int orage_persistent_file_open(gboolean write);
 
 #endif /* !__INTERFACE_H__ */

Modified: xfcalendar/trunk/src/main.c
===================================================================
--- xfcalendar/trunk/src/main.c 2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/main.c 2007-12-02 21:27:59 UTC (rev 26429)
@@ -488,6 +488,7 @@
     */
     mCalendar_month_changed_cb(g_par.xfcal->mCalendar, NULL);
     g_par.day_timer = 0;
+    alarm_read();
     orage_day_change(NULL); /* first day change after we start */
 
     /* start monitoring foreign file updates if we have foreign files */

Modified: xfcalendar/trunk/src/mainbox.c
===================================================================
--- xfcalendar/trunk/src/mainbox.c      2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/mainbox.c      2007-12-02 21:27:59 UTC (rev 26429)
@@ -287,8 +287,10 @@
 {
     gchar *uid;
 
-    uid = g_object_get_data(G_OBJECT(widget), "UID");
-    create_appt_win("UPDATE", uid, NULL);
+    if (event->type==GDK_2BUTTON_PRESS) {
+        uid = g_object_get_data(G_OBJECT(widget), "UID");
+        create_appt_win("UPDATE", uid, NULL);
+    }
 }
 
 static void add_info_row(xfical_appt *appt)

Modified: xfcalendar/trunk/src/reminder.c
===================================================================
--- xfcalendar/trunk/src/reminder.c     2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/reminder.c     2007-12-02 21:27:59 UTC (rev 26429)
@@ -57,8 +57,30 @@
 void create_notify_reminder(alarm_struct *alarm);
 gboolean orage_alarm_clock(gpointer user_data);
 gboolean orage_tooltip_update(gpointer user_data);
+void create_reminders(alarm_struct *alarm);
 
+/* this is almost the same than in ical-code.c.
+ * Perhaps these can be combined */
+static void alarm_free(alarm_struct *alarm)
+{
+#undef P_N
+#define P_N "alarm_free: "
 
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    g_free(alarm->uid);
+    if (alarm->title != NULL)
+        g_free(alarm->title);
+    if (alarm->description != NULL)
+        g_free(alarm->description);
+    if (alarm->sound != NULL)
+        g_free(alarm->sound);
+    if (alarm->cmd != NULL)
+        g_free(alarm->cmd);
+    g_free(alarm);
+}
+
 static void alarm_free_memory(alarm_struct *alarm)
 {
     /*
@@ -70,21 +92,248 @@
         alarm->repeat_cnt = 0;
     if (!alarm->display_orage && !alarm->display_notify && !alarm->audio) {
         /* all gone, need to clean memory */
-        g_string_free(alarm->uid, TRUE);
+        alarm_free(alarm);
+/*
+        g_free(alarm->uid);
         if (alarm->title != NULL)
-            g_string_free(alarm->title, TRUE);
+            g_free(alarm->title);
         if (alarm->description != NULL)
-            g_string_free(alarm->description, TRUE);
+            g_free(alarm->description);
         if (alarm->sound != NULL)
-            g_string_free(alarm->sound, TRUE);
+            g_free(alarm->sound);
         g_free(alarm->active_alarm);
         g_free(alarm);
+*/
         /*
     g_print("alarm_free_memory: freed %d %d\n",  alarm->audio, 
alarm->display_notify);
     */
     }
 }
 
+static gboolean alarm_read_next_value(int p_file, char *buf)
+{
+#undef P_N
+#define P_N "alarm_read_next_value: "
+    int len;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    if (read(p_file, buf, 3) == 0)
+        return(FALSE);
+    buf[3] = '\0';
+/*    g_print(P_N "read cnt %s\n", buf); */
+    len = atoi(buf);
+/*    g_print(P_N "read len %d\n", len); */
+    for (read(p_file, buf, 1); buf[0] != '='; read(p_file, buf, 1))
+        ; /* skip until =, which starts the value */
+    read(p_file, buf, len);
+    buf[len] = '\0';
+/*    g_print(P_N "read data %s\n", buf); */
+    lseek(p_file, 1, SEEK_CUR); /* skip new line */
+    return(TRUE);
+}
+
+static gboolean alarm_read_boolean(char *buf)
+{
+    if (!strncmp(buf, "TRUE", 4))
+        return(TRUE);
+    else
+        return(FALSE);
+}
+
+static alarm_struct *alarm_read_next_alarm(int p_file, char *buf)
+{
+#undef P_N
+#define P_N "alarm_read_next_alarm: "
+    alarm_struct *new_alarm;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+
+    /* We trust here that the order is the same than what we used in writing */
+    if (!alarm_read_next_value(p_file, buf))
+        return(NULL);
+    new_alarm = g_new0(alarm_struct, 1);
+
+    new_alarm->alarm_time = strdup(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->uid = strdup(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->title = strdup(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->description = strdup(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->persistent = TRUE; /* this must be */
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->display_orage = alarm_read_boolean(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->display_notify = alarm_read_boolean(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->notify_refresh = alarm_read_boolean(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->notify_timeout = atoi(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->audio = alarm_read_boolean(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->sound = strdup(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->repeat_cnt = atoi(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->repeat_delay = atoi(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->procedure = alarm_read_boolean(buf);
+
+    alarm_read_next_value(p_file, buf);
+    new_alarm->cmd = strdup(buf);
+    return(new_alarm);
+}
+
+void alarm_read()
+{
+#undef P_N
+#define P_N "alarm_read: "
+    int p_file;
+    char buf[1000];
+    alarm_struct *new_alarm;
+    struct tm *t;
+    gchar *time_now;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+
+    if ((p_file = orage_persistent_file_open(FALSE)) == -1)
+        return;
+    t = orage_localtime();
+    time_now = orage_tm_time_to_icaltime(t);
+    for (new_alarm = alarm_read_next_alarm(p_file, buf);
+            new_alarm;
+            new_alarm = alarm_read_next_alarm(p_file, buf)) {
+        if (strcmp(time_now, new_alarm->alarm_time) > 0) {
+            create_reminders(new_alarm);
+            alarm_free(new_alarm);
+        }
+    }
+    close(p_file);
+}
+
+static void alarm_store(gpointer galarm, gpointer gfile)
+{
+#undef P_N
+#define P_N "alarm_store: "
+    alarm_struct *alarm = (alarm_struct *)galarm;
+    int file = (int)gfile;
+    char buf[1000], *s_boolean, s_num[20];
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    if (!alarm->persistent)
+        return; /* only store persistent alarms */
+
+    g_sprintf(buf, "%03dALARM_TIME=%s\n"
+            , strlen(alarm->alarm_time), alarm->alarm_time);
+    write(file, buf, strlen(buf));
+
+    g_snprintf(buf, 999, "%03dUID=%s\n"
+            , strlen(alarm->uid), alarm->uid);
+    write(file, buf, strlen(buf));
+
+    g_snprintf(buf, 999, "%03dTITLE=%s\n"
+            , strlen(alarm->title), alarm->title);
+    write(file, buf, strlen(buf));
+
+    g_snprintf(buf, 999, "%03dDESCRIPTION=%s\n"
+            , strlen(alarm->description), alarm->description);
+    write(file, buf, strlen(buf));
+
+    /* this is TRUE since we are here */
+    g_sprintf(buf, "%03dPERSISTENT=%s\n", strlen("TRUE"), "TRUE");
+    write(file, buf, strlen(buf));
+
+    /*
+ *     if (alarm->display_orage)
+ *             s_boolean="TRUE";
+ *                 else
+ *                         s_boolean="FALSE";
+ *                             */
+    s_boolean = alarm->display_orage ? "TRUE" : "FALSE";
+    g_sprintf(buf, "%03dDISPLAY_ORAGE=%s\n", strlen(s_boolean), s_boolean);
+    write(file, buf, strlen(buf));
+
+    s_boolean = alarm->display_notify ? "TRUE" : "FALSE";
+    g_sprintf(buf, "%03dDISPLAY_NOTIFY=%s\n", strlen(s_boolean), s_boolean);
+    write(file, buf, strlen(buf));
+
+    s_boolean = alarm->notify_refresh ? "TRUE" : "FALSE";
+    g_sprintf(buf, "%03dNOTIFY_REFRESH=%s\n", strlen(s_boolean), s_boolean);
+    write(file, buf, strlen(buf));
+
+    g_sprintf(s_num, "%d", alarm->notify_timeout);
+    g_sprintf(buf, "%03dNOTIFY_TIMEOUT=%s\n", strlen(s_num), s_num);
+    write(file, buf, strlen(buf));
+
+    s_boolean = alarm->audio ? "TRUE" : "FALSE";
+    g_sprintf(buf, "%03dAUDIO=%s\n", strlen(s_boolean), s_boolean);
+    write(file, buf, strlen(buf));
+
+    if (alarm->audio)
+        g_snprintf(buf, 999, "%03dSOUND=%s\n"
+                , strlen(alarm->sound), alarm->sound);
+    else
+        g_sprintf(buf, "000SOUND=\n");
+    write(file, buf, strlen(buf));
+
+    g_sprintf(s_num, "%d", alarm->repeat_cnt);
+    g_sprintf(buf, "%03dREPEAT_CNT=%s\n", strlen(s_num), s_num);
+    write(file, buf, strlen(buf));
+
+    g_sprintf(s_num, "%d", alarm->repeat_delay);
+    g_sprintf(buf, "%03dREPEAT_DELAY=%s\n", strlen(s_num), s_num);
+    write(file, buf, strlen(buf));
+
+    s_boolean = alarm->procedure ? "TRUE" : "FALSE";
+    g_sprintf(buf, "%03dPROCEDURE=%s\n", strlen(s_boolean), s_boolean);
+    write(file, buf, strlen(buf));
+
+    if (alarm->procedure)
+        g_snprintf(buf, 999, "%03dCMD=%s\n"
+                , strlen(alarm->cmd), alarm->cmd);
+    else
+        g_sprintf(buf, "000CMD=\n");
+    write(file, buf, strlen(buf));
+}
+
+static void store_persistent_alarms()
+{
+#undef P_N
+#define P_N "store_persistent_alarms: "
+    int p_file;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    if ((p_file = orage_persistent_file_open(TRUE)) == -1)
+        return;
+    g_list_foreach(g_par.alarm_list, alarm_store, (gpointer)p_file);
+    close(p_file);
+}
+
 static void notify_action_open(NotifyNotification *n, const char *action
         , gpointer par)
 {
@@ -97,7 +346,7 @@
     alarm->notify_refresh = TRUE;
     create_notify_reminder(alarm);
     */
-    create_appt_win("UPDATE", alarm->uid->str, NULL);
+    create_appt_win("UPDATE", alarm->uid, NULL);
 }
 
 static gboolean sound_alarm(gpointer data)
@@ -112,10 +361,10 @@
         if (alarm->active_alarm->sound_active) {
             return(TRUE);
         }
-        status = orage_exec(alarm->sound->str
+        status = orage_exec(alarm->sound
                 , &alarm->active_alarm->sound_active, &error);
         if (!status) {
-            g_warning("reminder: play failed (%s)", alarm->sound->str);
+            g_warning("reminder: play failed (%s)", alarm->sound);
             alarm->repeat_cnt = 0; /* one warning is enough */
         }
         else if (alarm->repeat_cnt > 0)
@@ -147,9 +396,12 @@
 
 static void create_sound_reminder(alarm_struct *alarm)
 {
+    /* done in initialisation 
     g_string_prepend(alarm->sound, " \"");
     g_string_prepend(alarm->sound, g_par.sound_application);
     g_string_append(alarm->sound, "\"");
+    */
+
     alarm->active_alarm->sound_active = FALSE;
     if (alarm->repeat_cnt == 0) {
         alarm->repeat_cnt++; /* need to do it once */
@@ -208,8 +460,8 @@
     }
 
     strncpy(heading,  _("Reminder "), 199);
-    strncat(heading, alarm->title->str, 50);
-    n = notify_notification_new(heading, alarm->description->str, NULL, NULL);
+    strncat(heading, alarm->title, 50);
+    n = notify_notification_new(heading, alarm->description, NULL, NULL);
     alarm->active_alarm->active_notify = n;
     if (g_par.trayIcon && NETK_IS_TRAY_ICON(g_par.trayIcon->tray)) 
         notify_notification_attach_to_widget(n, g_par.trayIcon->image);
@@ -269,7 +521,7 @@
 {
     alarm_struct *alarm = (alarm_struct *)user_data;
 
-    create_appt_win("UPDATE", alarm->uid->str, NULL);
+    create_appt_win("UPDATE", alarm->uid, NULL);
 }
 
 static void create_orage_reminder(alarm_struct *alarm)
@@ -294,7 +546,7 @@
 
     vbReminder = GTK_DIALOG(wReminder)->vbox;
 
-    hdReminder = gtk_label_new(alarm->title->str);
+    hdReminder = gtk_label_new(alarm->title);
     gtk_box_pack_start(GTK_BOX(vbReminder), hdReminder, FALSE, TRUE, 0);
 
     swReminder = gtk_scrolled_window_new(NULL, NULL);
@@ -304,7 +556,7 @@
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swReminder)
             , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
-    lbReminder = gtk_label_new(alarm->description->str);
+    lbReminder = gtk_label_new(alarm->description);
     gtk_label_set_line_wrap(GTK_LABEL(lbReminder), TRUE);
     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swReminder)
             , lbReminder);
@@ -346,9 +598,9 @@
     gboolean status, active; /* active not used */
     GError *error = NULL;
 
-    status = orage_exec(alarm->cmd->str, &active, &error);
+    status = orage_exec(alarm->cmd, &active, &error);
     if (!status)
-        g_warning("create_procedure_reminder: cmd failed(%s)", 
alarm->cmd->str);
+        g_warning("create_procedure_reminder: cmd failed(%s)", alarm->cmd);
 }
 
 void create_reminders(alarm_struct *alarm)
@@ -361,21 +613,26 @@
     n_alarm = g_new0(alarm_struct, 1);
     /* alarm_time is not copied. It was only used to find out when alarm
      * happens and while we are here, it happened already */
-    n_alarm->uid = g_string_new(alarm->uid->str);
-    n_alarm->title = g_string_new(alarm->title->str);
-    n_alarm->description = g_string_new(alarm->description->str);
+    n_alarm->uid = g_strdup(alarm->uid);
+    n_alarm->title = g_strdup(alarm->title);
+    n_alarm->description = g_strdup(alarm->description);
     n_alarm->notify_timeout = alarm->notify_timeout;
     n_alarm->display_orage = alarm->display_orage;
     n_alarm->display_notify = alarm->display_notify;
     n_alarm->notify_timeout = alarm->notify_timeout;
     n_alarm->audio = alarm->audio;
     if (alarm->sound != NULL)
+        /* note that this changes here !*/
+        /*
         n_alarm->sound = g_string_new(alarm->sound->str);
+        */
+        n_alarm->sound = g_strconcat(g_par.sound_application, " \""
+                , alarm->sound, "\"", NULL);
     n_alarm->repeat_cnt = alarm->repeat_cnt;
     n_alarm->repeat_delay = alarm->repeat_delay;
     n_alarm->procedure = alarm->procedure;
     if (alarm->cmd != NULL)
-        n_alarm->cmd = g_string_new(alarm->cmd->str);
+        n_alarm->cmd = g_strdup(alarm->cmd);
     n_alarm->active_alarm = g_new0(active_alarm_struct, 1);
 
     if (n_alarm->audio)
@@ -535,6 +792,7 @@
     gchar *time_now;
                                                                                
 
     t = orage_localtime();
+    time_now = orage_tm_time_to_icaltime(t);
   /* Check if there are any alarms to show */
     alarm_l = g_par.alarm_list;
     for (alarm_l = g_list_first(alarm_l);
@@ -542,7 +800,6 @@
          alarm_l = g_list_next(alarm_l)) {
         /* remember that it is sorted list */
         cur_alarm = (alarm_struct *)alarm_l->data;
-        time_now = orage_tm_time_to_icaltime(t);
         if (strcmp(time_now, cur_alarm->alarm_time) > 0) {
             create_reminders(cur_alarm);
             alarm_raised = TRUE;
@@ -550,9 +807,8 @@
         else /* sorted so scan can be stopped */
             more_alarms = FALSE; 
     }
-    if (alarm_raised) { /* at least one alarm processed, need new list */
+    if (alarm_raised)  /* at least one alarm processed, need new list */
         xfical_alarm_build_list(FALSE); /* this calls reset_orage_alarm_clock 
*/
-    }
     else
         reset_orage_alarm_clock(); /* need to setup next timer */
     return(FALSE); /* only once */
@@ -640,7 +896,7 @@
             }
             g_string_append_printf(tooltip, 
                     _("\n%02d d %02d h %02d min to: %s"),
-                    dd, hh, min, cur_alarm->title->str);
+                    dd, hh, min, cur_alarm->title);
             alarm_cnt++;
         }
         else /* sorted so scan can be stopped */
@@ -656,6 +912,7 @@
 gboolean setup_orage_alarm_clock()
 {
     reset_orage_alarm_clock();
+    store_persistent_alarms(); /* keep track of alarms when orage is down */
     /* We need to use timer since for some reason it does not work if we
      * do it here directly. Ugly, I know, but it works. */
     g_timeout_add(1*1000, (GtkFunction) reset_orage_tooltip_update, NULL);

Modified: xfcalendar/trunk/src/reminder.h
===================================================================
--- xfcalendar/trunk/src/reminder.h     2007-12-02 16:49:00 UTC (rev 26428)
+++ xfcalendar/trunk/src/reminder.h     2007-12-02 21:27:59 UTC (rev 26429)
@@ -36,9 +36,9 @@
 typedef struct _alarm_struct
 {
     gchar   *alarm_time;
-    GString *uid;
-    GString *title;
-    GString *description;
+    gchar   *uid;
+    gchar   *title;
+    gchar   *description;
     gboolean persistent;
 
     gboolean display_orage;
@@ -47,12 +47,12 @@
     gint     notify_timeout;
 
     gboolean audio;
-    GString *sound;
+    gchar   *sound;
     gint     repeat_cnt;
     gint     repeat_delay;
 
     gboolean procedure;
-    GString *cmd;
+    gchar   *cmd;
     /*
     gboolean email;
     */
@@ -62,5 +62,6 @@
 
 gboolean orage_day_change(gpointer user_data);
 gboolean setup_orage_alarm_clock(void);
+void alarm_read();
 
 #endif /* !__REMINDER_H__ */

_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to