[Xfce4-commits] r25721 - in xfcalendar/trunk: . src

Juha Kautto juha at xfce.org
Sat May 19 22:54:25 CEST 2007


Author: juha
Date: 2007-05-19 20:54:25 +0000 (Sat, 19 May 2007)
New Revision: 25721

Modified:
   xfcalendar/trunk/AUTHORS
   xfcalendar/trunk/NEWS
   xfcalendar/trunk/README
   xfcalendar/trunk/TODO
   xfcalendar/trunk/configure.in.in
   xfcalendar/trunk/src/Makefile.am
   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/main.c
   xfcalendar/trunk/src/reminder.c
   xfcalendar/trunk/src/reminder.h
Log:
 Added support for libnotify.
 Actually recoded the whole alarm stuff.
 Bug 2831 - Add support for libnotify


Modified: xfcalendar/trunk/AUTHORS
===================================================================
--- xfcalendar/trunk/AUTHORS	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/AUTHORS	2007-05-19 20:54:25 UTC (rev 25721)
@@ -1,11 +1,3 @@
 Juha Kautto <juha at xfce.org>
-    - maintainer
-    
 Mickael Graf <korbinus at xfce.org>
-    - Projet creator & former maintainer
-
 Benedikt Meurer <benny at xfce.org>
-    - contributor
-
-Edscott Wilson Garcia <edscott at xfce.org>
-    - contributor

Modified: xfcalendar/trunk/NEWS
===================================================================
--- xfcalendar/trunk/NEWS	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/NEWS	2007-05-19 20:54:25 UTC (rev 25721)
@@ -1,42 +1,45 @@
-4.4.0
-=====
-- Fix possible crash in appointment timezone selection.
-- Add missing revert/duplicate menu item sensitiviness settings.
-- Several new and updated translations.
+20070519:
+---------
+        * Orage version 4.5.9.5 released 
+        * libnotify support added.
 
+20070104:
+---------
+        * Orage version 4.5.9 released 
+        * globaltime added. Can show times in several timezones
 
-20061904
-========
-- xfcalendar renamed to orage
-- production version of orage (4.3) available 
-- orageclock panel plugin added. Can use timezone
+20072101:
+---------
+        * Orage version 4.4.0 released together with Xfce 4.4.0
 
+20061904:
+---------
+        * xfcalendar renamed to orage
+        * production version of orage (4.3) available 
+        * orageclock panel plugin added. Can use timezone
 
-20051201
-========
-- beta version of xfcalendar (4.3.2) can use timezones
-  builtin to the libical package
+20051201:
+---------
+        * beta version of xfcalendar (4.3.2) can use timezones
+          builtin to the libical package
 
+20050302:
+---------
+        * beta version of xfcalendar (4.3.0.1) is using libical 
+          instead of the previous dbh.
 
-20050302
-========
-- beta version of xfcalendar (4.3.0.1) is using libical 
-  instead of the previous dbh.
+20050210:
+---------
+        * Position in screen now stored so that xfcalendar stays where 
+          it was put.
+        * More paramaters added: Visibility in Systray, Pager and 
+          Taskbar now configurable from standard parameter screen. 
+          Also xfcalendar visibility when it is started from shell 
+          first time can be configured either visible or hidden.
 
-
-20050210
-========
-- Position in screen now stored so that xfcalendar stays where 
-  it was put.
-- More paramaters added: Visibility in Systray, Pager and 
-  Taskbar now configurable from standard parameter screen. 
-  Also xfcalendar visibility when it is started from shell 
-  first time can be configured either visible or hidden.
-
-
-20030716
-========
-- XfceTrayIcon now both provides "clicked" (a single left button
-  click) and "double_clicked" (double left button click) signals
-- XfceTrayIcon no longer autoconnects, you'll need to call
-  xfce_tray_icon_connect() explicitly
+20030716:
+---------
+	    * XfceTrayIcon now both provides "clicked" (a single left button
+	      click) and "double_clicked" (double left button click) signals
+  	    * XfceTrayIcon no longer autoconnects, you'll need to call
+	      xfce_tray_icon_connect() explicitly

Modified: xfcalendar/trunk/README
===================================================================
--- xfcalendar/trunk/README	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/README	2007-05-19 20:54:25 UTC (rev 25721)
@@ -3,9 +3,9 @@
 Orage 4.3 uses new ical interface instead of old dbh to store and
 utilize calender appointments. 
 
-libical-0.24RC4 version is needed and it comes together with xfcalendar
-package.  It contains some minor fixes so you must use this version instead
-of base libical-0.24RC4.
+libical-0.24RC4 version is needed and it comes together with Orage
+package.  It contains several fixes so you must use this version instead
+of any base libical version.
 
 Note that there is no conversion routine to migrate your old data into 
 the new format, but you will loose all old appointments and start from

Modified: xfcalendar/trunk/TODO
===================================================================
--- xfcalendar/trunk/TODO	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/TODO	2007-05-19 20:54:25 UTC (rev 25721)
@@ -50,6 +50,7 @@
 
 14) Alarm before the end of the event. 
     Needed for TODOs
+*** DONE 4.5 ***
 
 15) Internal: build own message/warning system
 *** DONE 4.5 ***

Modified: xfcalendar/trunk/configure.in.in
===================================================================
--- xfcalendar/trunk/configure.in.in	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/configure.in.in	2007-05-19 20:54:25 UTC (rev 25721)
@@ -9,11 +9,12 @@
 dnl
 
 dnl Version information
-m4_define([orage_version], [4.5.9.4-svn])
+m4_define([orage_version], [4.5.9.5-svn])
 
 m4_define([gtk_minimum_version], [2.6.0])
 m4_define([xfce_minimum_version], [4.4.0])
 m4_define([dbus_minimum_version], [0.34])
+m4_define([notify_minimum_version], [0.3.2])
 m4_define([intltool_minimum_version], [0.31])
 
 
@@ -185,6 +186,14 @@
 XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-glib-1],
                            [dbus_minimum_version], [dbus], [D-BUS support])
 
+
+dnl **************************************
+dnl *** Optional support for libnotify ***
+dnl **************************************
+XDT_CHECK_OPTIONAL_PACKAGE([NOTIFY], [libnotify],
+                           [notify_minimum_version], [libnotify], 
+                           [LIBNOTIFY support])
+
 dnl Check for debugging support
 dnl BM_DEBUG_SUPPORT()
 XDT_FEATURE_DEBUG
@@ -226,3 +235,9 @@
 else
 echo "* D-BUS support:             no"
 fi
+if test x"$NOTIFY_FOUND" = x"yes"; then
+echo "* LIBNOTIFY support:         yes"
+else
+echo "* LIBNOTIFY support:         no"
+fi
+echo

Modified: xfcalendar/trunk/src/Makefile.am
===================================================================
--- xfcalendar/trunk/src/Makefile.am	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/Makefile.am	2007-05-19 20:54:25 UTC (rev 25721)
@@ -72,4 +72,9 @@
 	dbus-binding-tool --prefix=orage --mode=glib-server $(srcdir)/orage-dbus-service.xml > orage-dbus-service.h
 endif
 
+if HAVE_NOTIFY
+orage_LDADD +=							\
+	$(NOTIFY_LIBS)
+endif
+
 # vi:set ts=8 sw=8 noet ai:

Modified: xfcalendar/trunk/src/appointment.c
===================================================================
--- xfcalendar/trunk/src/appointment.c	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/appointment.c	2007-05-19 20:54:25 UTC (rev 25721)
@@ -74,30 +74,29 @@
 }
 
 static GtkWidget *datetime_hbox_new(GtkWidget *date_button
-        , GtkWidget *time_spin_hh, GtkWidget *time_spin_mm
+        , 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);
 
-    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(time_spin_hh), TRUE);
-    gtk_widget_set_size_request(time_spin_hh, 40, -1);
-    gtk_box_pack_start(GTK_BOX(hbox), time_spin_hh, 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(time_spin_mm), TRUE);
-    gtk_widget_set_size_request(time_spin_mm, 40, -1);
-    gtk_box_pack_start(GTK_BOX(hbox), time_spin_mm, 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);
 
@@ -106,6 +105,51 @@
     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) {
@@ -146,9 +190,9 @@
         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->CompletedTime_spin_hh, FALSE);
+        gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, FALSE);
+        gtk_widget_set_sensitive(apptw->CompletedTimezone_button, FALSE);
         if (dur_act) {
             gtk_widget_set_sensitive(apptw->EndDate_button, FALSE);
             gtk_widget_set_sensitive(apptw->Dur_spin_dd, TRUE);
@@ -159,12 +203,12 @@
             gtk_widget_set_sensitive(apptw->Dur_spin_dd, FALSE);
             gtk_widget_set_sensitive(apptw->Dur_spin_dd_label, FALSE);
         }
-	if (completed_act) {
-	    gtk_widget_set_sensitive(apptw->CompletedDate_button, TRUE);
-	}
-	else {
-	    gtk_widget_set_sensitive(apptw->CompletedDate_button, FALSE);
-	}
+        if (completed_act) {
+            gtk_widget_set_sensitive(apptw->CompletedDate_button, TRUE);
+        }
+        else {
+            gtk_widget_set_sensitive(apptw->CompletedDate_button, FALSE);
+        }
     }
     else {
         gtk_widget_set_sensitive(apptw->StartTime_spin_hh, TRUE);
@@ -194,18 +238,18 @@
             gtk_widget_set_sensitive(apptw->Dur_spin_mm, FALSE);
             gtk_widget_set_sensitive(apptw->Dur_spin_mm_label, FALSE);
         }
-	if (completed_act) {
-	    gtk_widget_set_sensitive(apptw->CompletedDate_button, TRUE);
-	    gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, TRUE);
-	    gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, TRUE);
-	    gtk_widget_set_sensitive(apptw->CompletedTimezone_button, TRUE);
-	}
-	else {
-	    gtk_widget_set_sensitive(apptw->CompletedDate_button, 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);
-	}
+        if (completed_act) {
+            gtk_widget_set_sensitive(apptw->CompletedDate_button, TRUE);
+            gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, TRUE);
+            gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, TRUE);
+            gtk_widget_set_sensitive(apptw->CompletedTimezone_button, TRUE);
+        }
+        else {
+            gtk_widget_set_sensitive(apptw->CompletedDate_button, 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);
+        }
     }
 }
 
@@ -340,21 +384,73 @@
     }
 }
 
-/*
-static void app_event_checkbutton_clicked_cb(GtkCheckButton *cb
-        , gpointer user_data)
+static void set_sound_sensitivity(appt_win *apptw)
 {
-    type_hide_show((appt_win *)user_data);
-    mark_appointment_changed((appt_win *)user_data);
+    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 app_todo_checkbutton_clicked_cb(GtkCheckButton *cb
-        , gpointer user_data)
+static void set_notify_sensitivity(appt_win *apptw)
 {
-    type_hide_show((appt_win *)user_data);
-    mark_appointment_changed((appt_win *)user_data);
+#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 app_type_checkbutton_clicked_cb(GtkCheckButton *cb
         , gpointer user_data)
@@ -412,6 +508,22 @@
     recur_hide_show((appt_win *)user_data);
 }
 
+static void app_sound_checkbutton_clicked_cb(GtkCheckButton *cb
+        , gpointer user_data)
+{
+    mark_appointment_changed((appt_win *)user_data);
+    set_sound_sensitivity((appt_win *)user_data);
+}
+
+#ifdef HAVE_NOTIFY
+static void app_notify_checkbutton_clicked_cb(GtkCheckButton *cb
+        , gpointer user_data)
+{
+    mark_appointment_changed((appt_win *)user_data);
+    set_notify_sensitivity((appt_win *)user_data);
+}
+#endif
+
 static void app_checkbutton_clicked_cb(GtkCheckButton *cb, gpointer user_data)
 {
     mark_appointment_changed((appt_win *)user_data);
@@ -729,6 +841,7 @@
                     + 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 */
     /*
@@ -758,6 +871,10 @@
             break;
     }
 
+    /* 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 */
     appt->sound = g_strdup(gtk_entry_get_text(GTK_ENTRY(apptw->Sound_entry)));
 
@@ -770,6 +887,30 @@
     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
+
     /* recurrence */
     appt->freq = gtk_combo_box_get_active(GTK_COMBO_BOX(apptw->Recur_freq_cb));
 
@@ -1214,6 +1355,9 @@
         /* default alarm time is 500 cnt & 2 secs each */
         appt->soundrepeat_cnt = 500;
         appt->soundrepeat_len = 2;
+
+        /* default alarm type is orage window */
+        appt->display_alarm_orage = TRUE;
     }
     else if ((strcmp(action, "UPDATE") == 0) 
           || (strcmp(action, "COPY") == 0)) {
@@ -1307,9 +1451,16 @@
     gtk_entry_set_text(GTK_ENTRY(apptw->Title_entry)
             , (appt->title ? appt->title : ""));
 
-    if (strcmp(action, "COPY") == 0) 
+    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);
+    }
+    /*
         gtk_entry_append_text(GTK_ENTRY(apptw->Title_entry)
                 , _(" *** COPY ***"));
+                */
 
     /* location */
     gtk_entry_set_text(GTK_ENTRY(apptw->Location_entry)
@@ -1342,8 +1493,8 @@
 
     /* alarmrelation */
     /*
-    char *when_array[4] = {_("Before Start"), _("Before End")
-        , _("After Start"), _("After End")};
+    char *when_array[4] = {
+    _("Before Start"), _("Before End"), _("After Start"), _("After End")};
         */
     if (appt->alarm_before)
         if (appt->alarm_related_start)
@@ -1356,11 +1507,15 @@
         else
             gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Alarm_when_cb), 3);
 
-    /* alarm sound */
+    /* 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 : ""));
+            , (appt->sound ? appt->sound : 
+                PACKAGE_DATA_DIR "/orage/sounds/Spo.wav"));
 
-    /* alarm repeat */
+    /* sound repeat */
     gtk_toggle_button_set_active(
             GTK_TOGGLE_BUTTON(apptw->SoundRepeat_checkbutton)
                     , appt->soundrepeat);
@@ -1369,6 +1524,34 @@
     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
+
     /********************* RECURRENCE tab *********************/
     /* recurrence */
     gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Recur_freq_cb)
@@ -1443,6 +1626,8 @@
 
     set_time_sensitivity(apptw);
     set_repeat_sensitivity(apptw);
+    set_sound_sensitivity(apptw);
+    set_notify_sensitivity(apptw);
     mark_appointment_unchanged(apptw);
 }
 
@@ -1648,30 +1833,17 @@
     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);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Dur_spin_dd), TRUE);
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), apptw->Dur_spin_dd
-            , FALSE, FALSE, 5);
     apptw->Dur_spin_dd_label = gtk_label_new(_("days"));
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox)
-            , apptw->Dur_spin_dd_label, FALSE, FALSE, 0);
-    label = gtk_label_new(" ");
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), label, FALSE, FALSE, 5);
     apptw->Dur_spin_hh = gtk_spin_button_new_with_range(0, 23, 1);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Dur_spin_hh), TRUE);
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), apptw->Dur_spin_hh
-            , FALSE, FALSE, 5);
     apptw->Dur_spin_hh_label = gtk_label_new(_("hours"));
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox)
-            , apptw->Dur_spin_hh_label, FALSE, FALSE, 0);
-    label = gtk_label_new(" ");
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), label, FALSE, FALSE, 5);
     apptw->Dur_spin_mm = gtk_spin_button_new_with_range(0, 59, 5);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Dur_spin_mm), TRUE);
-    gtk_box_pack_start(GTK_BOX(apptw->Dur_hbox), apptw->Dur_spin_mm
-            , FALSE, FALSE, 5);
     apptw->Dur_spin_mm_label = gtk_label_new(_("mins"));
-    gtk_box_pack_start(GTK_BOX (apptw->Dur_hbox)
-            , apptw->Dur_spin_mm_label, FALSE, FALSE, 0);
+    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));
@@ -1791,6 +1963,7 @@
     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"));
@@ -1798,52 +1971,52 @@
     gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook)
             , apptw->Alarm_notebook_page, apptw->Alarm_tab_label);
 
-    apptw->Alarm_label = gtk_label_new(_("Alarm"));
+    /***** 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);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Alarm_spin_dd), TRUE);
-    gtk_box_pack_start(GTK_BOX(apptw->Alarm_hbox)
-            , apptw->Alarm_spin_dd, FALSE, FALSE, 0);
-    label = gtk_label_new(_("days"));
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), label, FALSE, FALSE, 5);
-    label = gtk_label_new(" ");
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), label, FALSE, FALSE, 10);
+    apptw->Alarm_spin_dd_label = gtk_label_new(_("days"));
     apptw->Alarm_spin_hh = gtk_spin_button_new_with_range(0, 23, 1);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Alarm_spin_hh), TRUE);
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox)
-            , apptw->Alarm_spin_hh, FALSE, FALSE, 0);
-    label = gtk_label_new(_("hours"));
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), label, FALSE, FALSE, 5);
-    label = gtk_label_new(" ");
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), label, FALSE, FALSE, 10);
+    apptw->Alarm_spin_hh_label = gtk_label_new(_("hours"));
     apptw->Alarm_spin_mm = gtk_spin_button_new_with_range(0, 59, 5);
-    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Alarm_spin_mm), TRUE);
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), apptw->Alarm_spin_mm
+    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);
-    label = gtk_label_new(_("mins"));
-    gtk_box_pack_start(GTK_BOX (apptw->Alarm_hbox), label, FALSE, FALSE, 5);
     apptw->Alarm_when_cb = gtk_combo_box_new_text();
     combo_box_append_array(apptw->Alarm_when_cb
             , 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, 15);
+            , 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);
 
+    /***** Audio Alarm *****/
     apptw->Sound_label = gtk_label_new(_("Sound"));
-    apptw->Sound_hbox = gtk_hbox_new(FALSE, 0);
-    gtk_box_set_spacing(GTK_BOX(apptw->Sound_hbox), 6);
+
+    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));
@@ -1854,52 +2027,133 @@
     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, 1);
+
+    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);
-    label = gtk_label_new(_("times"));
-    gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox), label
+
+    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);
-    label = gtk_label_new(_("sec interval"));
-    gtk_box_pack_start(GTK_BOX(apptw->SoundRepeat_hbox), label
+
+    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
+
     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->SoundRepeat_spin_cnt, "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->SoundRepeat_spin_len, "value-changed"
-            , G_CALLBACK(on_app_spin_button_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
 }
 
 static void build_recurrence_page(appt_win *apptw)
@@ -1935,7 +2189,7 @@
     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 second week or \n Every Saturday and Sunday or \n First Tuesday every month")
+            , _("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"));
@@ -2064,7 +2318,9 @@
     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);

Modified: xfcalendar/trunk/src/appointment.h
===================================================================
--- xfcalendar/trunk/src/appointment.h	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/appointment.h	2007-05-19 20:54:25 UTC (rev 25721)
@@ -76,6 +76,7 @@
     GtkWidget *EndTimezone_button;
     GtkWidget *Dur_hbox;
     GtkWidget *Dur_checkbutton;
+    GtkWidget *Dur_time_hbox;
     GtkWidget *Dur_spin_dd;
     GtkWidget *Dur_spin_dd_label;
     GtkWidget *Dur_spin_hh;
@@ -102,18 +103,35 @@
     GtkWidget *TableAlarm;
     GtkWidget *Alarm_label;
     GtkWidget *Alarm_hbox;
+    GtkWidget *Alarm_time_hbox;
     GtkWidget *Alarm_spin_dd;
+    GtkWidget *Alarm_spin_dd_label;
     GtkWidget *Alarm_spin_hh;
+    GtkWidget *Alarm_spin_hh_label;
     GtkWidget *Alarm_spin_mm;
+    GtkWidget *Alarm_spin_mm_label;
     GtkWidget *Alarm_when_cb;
     GtkWidget *Sound_label;
     GtkWidget *Sound_hbox;
+    GtkWidget *Sound_checkbutton;
     GtkWidget *Sound_entry;
     GtkWidget *Sound_button;
     GtkWidget *SoundRepeat_hbox;
     GtkWidget *SoundRepeat_checkbutton;
     GtkWidget *SoundRepeat_spin_cnt;
+    GtkWidget *SoundRepeat_spin_cnt_label;
     GtkWidget *SoundRepeat_spin_len;
+    GtkWidget *SoundRepeat_spin_len_label;
+    GtkWidget *Display_label;
+    GtkWidget *Display_hbox_orage;
+    GtkWidget *Display_checkbutton_orage;
+#ifdef HAVE_NOTIFY
+    GtkWidget *Display_hbox_notify;
+    GtkWidget *Display_checkbutton_notify;
+    GtkWidget *Display_checkbutton_expire_notify;
+    GtkWidget *Display_spin_expire_notify;
+    GtkWidget *Display_spin_expire_notify_label;
+#endif
 
     GtkWidget *Recur_notebook_page;
     GtkWidget *Recur_tab_label;

Modified: xfcalendar/trunk/src/ical-code.c
===================================================================
--- xfcalendar/trunk/src/ical-code.c	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/ical-code.c	2007-05-19 20:54:25 UTC (rev 25721)
@@ -1136,8 +1136,7 @@
     g_print(P_N "\n");
 #endif
     g_string_free(alarm->uid, TRUE);
-    g_string_free(alarm->alarm_time, TRUE);
-    g_string_free(alarm->event_time, TRUE);
+    g_free(alarm->alarm_time);
     if (alarm->title != NULL)
         g_string_free(alarm->title, TRUE);
     if (alarm->description != NULL)
@@ -1156,12 +1155,13 @@
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
 #endif
-    t1=icaltime_from_string(((alarm_struct *)a)->alarm_time->str);
-    t2=icaltime_from_string(((alarm_struct *)b)->alarm_time->str);
+    t1=icaltime_from_string(((alarm_struct *)a)->alarm_time);
+    t2=icaltime_from_string(((alarm_struct *)b)->alarm_time);
 
     return(icaltime_compare(t1, t2));
 }
 
+    /*
 static void alarm_add(icalproperty_status action
          , char *uid, char *file_type, char *title, char *description
          , char *sound, gint repeat_cnt, gint repeat_delay
@@ -1178,8 +1178,8 @@
     new_alarm->uid = g_string_new(file_type);
     new_alarm->uid = g_string_append(new_alarm->uid, uid);
     new_alarm->title = g_string_new(title);
-    new_alarm->alarm_time = g_string_new(icaltime_as_ical_string(alarm_time));
-    new_alarm->event_time = g_string_new(icaltime_as_ical_string(event_time));
+    new_alarm->alarm_time = g_strdup(icaltime_as_ical_string(alarm_time));
+    new_alarm->event_time = g_strdup(icaltime_as_ical_string(event_time));
     new_alarm->description = g_string_new(description);
     new_alarm->sound = g_string_new(sound);
     new_alarm->repeat_cnt = repeat_cnt;
@@ -1195,28 +1195,196 @@
 
     g_par.alarm_list = g_list_append(g_par.alarm_list, new_alarm);
 }
+    */
 
+/* let's find the trigger and check that it is active.
+ * return new alarm struct if alarm is active and NULL if it is not
+ * FIXME: We assume all alarms have similar trigger, which 
+ * may not be true for other that Orage appointments
+ */
+static  alarm_struct *process_alarm_trigger(icalcomponent *c
+        , icalcomponent *ca, struct icaltimetype cur_time, int *cnt_repeat)
+{
+#undef P_N
+#define P_N "process_alarm_trigger: "
+    icalproperty *p;
+    struct icaltriggertype trg;
+    icalparameter *trg_related_par;
+    icalparameter_related rel;
+    struct icalrecurrencetype rrule;
+    icalrecur_iterator* ri;
+    xfical_period per;
+    struct icaltimetype alarm_time, next_time;
+    gboolean trg_active = FALSE;
+    alarm_struct *new_alarm;;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    p = icalcomponent_get_first_property(ca, ICAL_TRIGGER_PROPERTY);
+    if (!p) {
+        g_warning(P_N "Trigger not found");
+        return(NULL);
+    }
+    trg = icalproperty_get_trigger(p);
+    trg_related_par = icalproperty_get_first_parameter(p
+            , ICAL_RELATED_PARAMETER);
+    if (trg_related_par)
+        rel = icalparameter_get_related(trg_related_par);
+    else
+        rel = ICAL_RELATED_START;
+    per = get_period(c);
+    if (icaltime_is_date(per.stime)) { 
+/* HACK: convert to local time so that we can use time arithmetic
+ * when counting alarm time. */
+        per.stime.is_date       = 0;
+        per.stime.is_utc        = cur_time.is_utc;
+        per.stime.is_daylight   = cur_time.is_daylight;
+        per.stime.zone          = cur_time.zone;
+        per.stime.hour          = 0;
+        per.stime.minute        = 0;
+        per.stime.second        = 0;
+    }
+    if (rel == ICAL_RELATED_END)
+        alarm_time = icaltime_add(per.etime, trg.duration);
+    else /* default is ICAL_RELATED_START */
+        alarm_time = icaltime_add(per.stime, trg.duration);
+    if (icaltime_compare(cur_time, alarm_time) <= 0) { /* active */
+        trg_active = TRUE;
+    }
+    else if ((p = icalcomponent_get_first_property(c
+        , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring EVENTs */                    rrule = icalproperty_get_rrule(p);
+        next_time = icaltime_null_time();
+        ri = icalrecur_iterator_new(rrule, alarm_time);
+        for (next_time = icalrecur_iterator_next(ri);
+            (!icaltime_is_null_time(next_time))
+            && (local_compare(cur_time, next_time) > 0) ;
+            next_time = icalrecur_iterator_next(ri)) {
+            (*cnt_repeat)++;
+        }
+        icalrecur_iterator_free(ri);
+        if (icaltime_compare(cur_time, next_time) <= 0) {
+            trg_active = TRUE;
+            alarm_time = next_time;
+        }
+    }
+    if (trg_active) {
+        new_alarm = g_new0(alarm_struct, 1);
+        new_alarm->alarm_time = g_strdup(icaltime_as_ical_string(alarm_time));
+        return(new_alarm);
+    }
+    else
+        return(NULL);
+}
+
+static void process_alarm_data(icalcomponent *c
+        , icalcomponent *ca, alarm_struct *new_alarm)
+{
+#undef P_N
+#define P_N "process_alarm_data: "
+    icalproperty *p;
+    enum icalproperty_action act;
+    icalattach *attach = NULL;
+    struct icaldurationtype duration;
+    char *text;
+    int i;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    p = icalcomponent_get_first_property(ca, ICAL_ACTION_PROPERTY);
+    if (!p) {
+        g_warning(P_N "No ACTION in alarm. Ignoring this ALARM.");
+        return;
+    }
+    act = icalproperty_get_action(p);
+    if (act == ICAL_ACTION_DISPLAY)
+        new_alarm->display = TRUE;
+    else if (act == ICAL_ACTION_AUDIO)
+        new_alarm->audio = TRUE;
+    for (p = icalcomponent_get_first_property(ca, ICAL_ANY_PROPERTY);
+         p != 0;
+         p = icalcomponent_get_next_property(ca, ICAL_ANY_PROPERTY)) {
+        switch (icalproperty_isa(p)) {
+            case ICAL_DESCRIPTION_PROPERTY:
+                if (new_alarm->description)
+                    g_string_free(new_alarm->description, TRUE);
+                new_alarm->description = g_string_new(
+                        (char *)icalproperty_get_description(p));
+                break;
+            case ICAL_ATTACH_PROPERTY:
+                attach = icalproperty_get_attach(p);
+                text = (char *)icalattach_get_url(attach);
+                if (text)
+                    new_alarm->sound = g_string_new(text);
+                break;
+            case ICAL_REPEAT_PROPERTY:
+                new_alarm->repeat_cnt = icalproperty_get_repeat(p);
+                break;
+            case ICAL_DURATION_PROPERTY:
+                duration = icalproperty_get_duration(p);
+                new_alarm->repeat_delay = icaldurationtype_as_int(duration);
+                break;
+            case ICAL_X_PROPERTY:
+                text = (char *)icalproperty_get_x_name(p);
+                /*
+                g_print(P_N "x-property %s\n", text);
+                */
+                if (!strcmp(text, "X-ORAGE-DISPLAY-ALARM")) {
+                    text = (char *)icalproperty_get_value_as_string(p);
+                /*
+                g_print(P_N "x-value %s\n", text);
+                */
+                    if (!strcmp(text, "ORAGE")) {
+                        new_alarm->display_orage = TRUE;
+                /*
+                g_print(P_N "x-orage %s\n", text);
+                */
+                    }
+                    else if (!strcmp(text, "NOTIFY")) {
+                        new_alarm->display_notify = TRUE;
+                /*
+                g_print(P_N "x-notify %s\n", text);
+                */
+                    }
+                }
+                else if (!strcmp(text, "X-ORAGE-NOTIFY-ALARM-TIMEOUT")) {
+                    text = (char *)icalproperty_get_value_as_string(p);
+                    sscanf(text, "%d", &i);
+                    new_alarm->notify_timeout = i;
+                }
+                else {
+                    g_warning(P_N "unknown X property %s", text);
+                }
+                break;
+            case ICAL_ACTION_PROPERTY:
+            case ICAL_TRIGGER_PROPERTY:
+                /* these are processed already */
+                break;
+            default:
+                g_warning(P_N "Unknown property (%s) in Alarm",
+                    (char *)icalproperty_get_property_name(p));
+                break;
+        } 
+    } 
+}
+
 static void xfical_alarm_build_list_internal_real(gboolean first_list_today
         , icalcomponent *base, char *file_type)
 {
 #undef P_N
 #define P_N "xfical_alarm_build_list_internal_real: "
-    xfical_period per;
-    struct icaltimetype alarm_time, cur_time, next_date;
     icalcomponent *c, *ca;
     icalproperty *p;
     icalproperty_status stat=ICAL_ACTION_DISPLAY;
-    struct icaltriggertype trg;
-    char *suid, *ssummary, *sdescription, *ssound;
-    gboolean trg_found;
-    icalattach *attach = NULL;
-    struct icalrecurrencetype rrule;
-    icalrecur_iterator* ri;
-    gint repeat_cnt, repeat_delay;
-    struct icaldurationtype duration;
-    gint cnt_alarm=0, cnt_repeat=0, cnt_event=0, cnt_act_alarm=0;
-    icalparameter *trg_related_par;
-    icalparameter_related rel;
+    struct icaltimetype cur_time;
+    char *suid, *ssummary, *sdescription, *ssound = NULL;
+    gboolean trg_found = FALSE, trg_active = FALSE;
+    gint repeat_cnt = 0, repeat_delay = 0;
+    gint cnt_alarm=0, cnt_repeat=0, cnt_event=0, cnt_act_alarm=0
+        , cnt_alarm_add=0;
+    icalcompiter ci;
+    alarm_struct *new_alarm = NULL;
 
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
@@ -1224,149 +1392,53 @@
     cur_time = ical_get_current_local_time();
 
     for (c = icalcomponent_get_first_component(base, ICAL_ANY_COMPONENT);
-         c != 0;
-         c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) {
+            c != 0;
+            c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) {
         cnt_event++;
-        suid = (char*)icalcomponent_get_uid(c);
-        /*
-        p = icalcomponent_get_first_property(c, ICAL_SUMMARY_PROPERTY);
-        if (p)
-            ssummary = (char*)icalproperty_get_value_as_string(p);
-        p = icalcomponent_get_first_property(c, ICAL_SUMMARY_PROPERTY);
-        if (p)
-            sdescription = (char*)icalproperty_get_value_as_string(p);
-            */
-        per = get_period(c);
-        if (first_list_today && icaltime_is_date(per.stime)) {
-        /* this is special pre 4.3 xfcalendar compatibility alarm:
-           Send alarm window always for date type events. */
-            ssummary = (char*)icalcomponent_get_summary(c);
-            sdescription = (char*)icalcomponent_get_description(c);
-            if (local_compare_date_only(per.stime, cur_time) == 0) {
-                alarm_add(ICAL_ACTION_DISPLAY
-                        , suid, file_type, ssummary, sdescription
-                        , NULL, 0, 0, per.stime, per.stime);
-                cnt_act_alarm++;
-            }
-            else if ((p = icalcomponent_get_first_property(c
-                , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring EVENTs */
-                next_date = icaltime_null_time();
-                rrule = icalproperty_get_rrule(p);
-                ri = icalrecur_iterator_new(rrule, per.stime);
-                for (next_date = icalrecur_iterator_next(ri);
-                    !icaltime_is_null_time(next_date)
-                        && local_compare_date_only(cur_time, next_date) > 0;
-                    next_date = icalrecur_iterator_next(ri)) {
-                    cnt_repeat++;
-                }
-                icalrecur_iterator_free(ri);
-                if (local_compare_date_only(next_date, cur_time) == 0) {
-                    alarm_add(ICAL_ACTION_DISPLAY
-                            , suid, file_type, ssummary, sdescription
-                            , NULL, 0, 0, next_date, per.stime);
-                    cnt_act_alarm++;
-                }
-            }
-        }
         trg_found = FALSE;
-        ssound = NULL;
-        repeat_cnt = 0;
-        repeat_delay = 0;
-        for (ca = icalcomponent_get_first_component(c, ICAL_VALARM_COMPONENT);
-             ca != 0;
-             ca = icalcomponent_get_next_component(c, ICAL_VALARM_COMPONENT)) {
-            for (p = icalcomponent_get_first_property(ca, ICAL_ANY_PROPERTY);
-                 p != 0;
-                 p = icalcomponent_get_next_property(ca, ICAL_ANY_PROPERTY)) {
-                switch (icalproperty_isa(p)) {
-                    case ICAL_ACTION_PROPERTY:
-                        stat = icalproperty_get_action(p);
-                        break;
-                    case ICAL_DESCRIPTION_PROPERTY:
-                        sdescription = (char *)icalproperty_get_description(p);
-                        break;
-                    case ICAL_ATTACH_PROPERTY:
-                        attach = icalproperty_get_attach(p);
-                        ssound = (char *)icalattach_get_url(attach);
-                        break;
-                    case ICAL_TRIGGER_PROPERTY:
-                        trg = icalproperty_get_trigger(p);
-                        trg_related_par = icalproperty_get_first_parameter(p
-                                , ICAL_RELATED_PARAMETER);
-                        if (trg_related_par)
-                            rel = icalparameter_get_related(trg_related_par);
-                        else
-                            rel = ICAL_RELATED_START;
-                        trg_found = TRUE;
-                        break;
-                    case ICAL_REPEAT_PROPERTY:
-                        repeat_cnt = icalproperty_get_repeat(p);
-                        break;
-                    case ICAL_DURATION_PROPERTY:
-                        duration = icalproperty_get_duration(p);
-                        repeat_delay = icaldurationtype_as_int(duration);
-                        break;
-                    default:
-                        g_warning(P_N "Unknown property (%s) in Alarm",
-                            (char *)icalproperty_get_property_name(p));
-                        break;
-                } 
-            } 
-        }  /* ALARMS */
-        if (trg_found) {
+        trg_active = FALSE;
+        for (ci = icalcomponent_begin_component(c, ICAL_VALARM_COMPONENT);
+                icalcompiter_deref(&ci) != 0;
+                icalcompiter_next(&ci)) {
+            ca = icalcompiter_deref(&ci);
             cnt_alarm++;
-            ssummary = (char*)icalcomponent_get_summary(c);
-            sdescription = (char*)icalcomponent_get_description(c);
-            if (icaltime_is_date(per.stime)) { 
-    /* HACK: convert to local time so that we can use time arithmetic
-     * when counting alarm time. */
-                per.stime.is_date       = 0;
-                per.stime.is_utc        = cur_time.is_utc;
-                per.stime.is_daylight   = cur_time.is_daylight;
-                per.stime.zone          = cur_time.zone;
-                per.stime.hour          = 0;
-                per.stime.minute        = 0;
-                per.stime.second        = 0;
+            if (!trg_found) {
+                trg_found = TRUE;
+                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);
+                    suid = (char *)icalcomponent_get_uid(c);
+                    new_alarm->uid = g_string_append(new_alarm->uid, suid);
+                    new_alarm->title = g_string_new(
+                            (char *)icalcomponent_get_summary(c));
+                    new_alarm->description = g_string_new(
+                            (char *)icalcomponent_get_description(c));
+                }
             }
-        /* all data available. let's pack it if alarm is still active */
-            if (rel == ICAL_RELATED_END)
-                alarm_time = icaltime_add(per.etime, trg.duration);
-            else /* default is ICAL_RELATED_START */
-                alarm_time = icaltime_add(per.stime, trg.duration);
-            if (icaltime_compare(cur_time, alarm_time) <= 0) { /* active */
-                alarm_add(stat, suid, file_type, ssummary, sdescription
-                        , ssound, repeat_cnt, repeat_delay
-                        , alarm_time, per.stime);
-                cnt_act_alarm++;
-            }
-            else if ((p = icalcomponent_get_first_property(c
-                , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring EVENTs */                    rrule = icalproperty_get_rrule(p);
-                next_date = icaltime_null_time();
-                alarm_time = icaltime_add(per.stime, trg.duration);
-                ri = icalrecur_iterator_new(rrule, alarm_time);
-                for (next_date = icalrecur_iterator_next(ri);
-                    (!icaltime_is_null_time(next_date))
-                    && (local_compare(cur_time, next_date) > 0) ;
-                    next_date = icalrecur_iterator_next(ri)) {
-                    cnt_repeat++;
-                }
-                icalrecur_iterator_free(ri);
-                if (icaltime_compare(cur_time, next_date) <= 0) {
-                    alarm_add(stat, suid, file_type, ssummary, sdescription
-                        , ssound, repeat_cnt, repeat_delay
-                        , next_date, per.stime);
+            if (trg_found) {
+                if (trg_active) {
                     cnt_act_alarm++;
+                    process_alarm_data(c, ca, new_alarm);
                 }
             }
-        } /* trg_found */
-    }  /* EVENTS */
+            else {
+                g_warning(P_N "Found alarm without trigger %s. Skipping it"
+                        , icalcomponent_get_uid(c));
+            }
+        }  /* ALARM */
+        if (trg_active) {
+            g_par.alarm_list = g_list_append(g_par.alarm_list, new_alarm);
+            cnt_alarm_add++;
+        }
+    }  /* COMPONENT */
     g_par.alarm_list = g_list_sort(g_par.alarm_list, alarm_order);
     if (first_list_today) {
-        orage_message("Build alarm list: Processed %d events."
-                , cnt_event);
+        orage_message("Build alarm list: Added %d alarms. Processed %d events."
+                , cnt_alarm_add, cnt_event);
         orage_message("\tFound %d alarms of which %d are active. (Searched %d recurring alarms.)"
                 , cnt_alarm, cnt_act_alarm, cnt_repeat);
-        }
+    }
 }
 
 static void xfical_alarm_build_list_internal(gboolean first_list_today)
@@ -1407,48 +1479,6 @@
     xfical_file_close(TRUE);
 }
 
-/*
-gboolean xfical_alarm_passed(char *alarm_stime)
-{
-#undef P_N
-#define P_N "xfical_alarm_passed: "
-    struct icaltimetype alarm_time, cur_time;
-
-#ifdef ORAGE_DEBUG
-    g_print(P_N "\n");
-#endif
-    cur_time = ical_get_current_local_time();
-    alarm_time = icaltime_from_string(alarm_stime);
-    if (local_compare(cur_time, alarm_time) > 0)
-        return(TRUE);
-    return(FALSE);
- }
- */
-
-/*
-gboolean xfical_duration(char *alarm_stime, int *days, int *hours, int *mins)
-{
-#undef P_N
-#define P_N "xfical_duration: "
-    struct icaltimetype alarm_time, cur_time;
-    struct icaldurationtype duration;
-
-#ifdef ORAGE_DEBUG
-    g_print(P_N "\n");
-#endif
-    duration = icaldurationtype_null_duration();
-    cur_time = ical_get_current_local_time();
-    alarm_time = icaltime_from_string(alarm_stime);
-    duration = icaltime_subtract(alarm_time, cur_time);
-    if (icaldurationtype_is_bad_duration(duration) || duration.is_neg)
-        return(FALSE);
-    *days = duration.weeks*7 + duration.days;
-    *hours = duration.hours;
-    *mins = duration.minutes;
-    return(TRUE);
- }
- */
-
 static char *generate_uid()
 {
 #undef P_N
@@ -1471,6 +1501,154 @@
     return(xf_uid);
 }
 
+static void appt_add_alarm_internal_display(xfical_appt *appt
+        , icalcomponent *ialarm)
+{
+#undef P_N
+#define P_N "appt_add_alarm_internal_display: "
+    char text[50];
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    icalcomponent_add_property(ialarm
+            , icalproperty_new_action(ICAL_ACTION_DISPLAY));
+    if ORAGE_STR_EXISTS(appt->note)
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_description(appt->note));
+    else if ORAGE_STR_EXISTS(appt->title)
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_description(appt->title));
+    else
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_description(_("Orage default alarm")));
+    if (appt->display_alarm_orage) {
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_from_string("X-ORAGE-DISPLAY-ALARM:ORAGE"));
+    }
+    if (appt->display_alarm_notify) {
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_from_string("X-ORAGE-DISPLAY-ALARM:NOTIFY"));
+        g_sprintf(text, "X-ORAGE-NOTIFY-ALARM-TIMEOUT:%d"
+                , appt->display_notify_timeout);
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_from_string(text));
+    }
+}
+
+static void appt_add_alarm_internal_audio(xfical_appt *appt
+        , icalcomponent *ialarm)
+{
+#undef P_N
+#define P_N "appt_add_alarm_internal_audio: "
+    icalattach *attach;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    icalcomponent_add_property(ialarm
+            , icalproperty_new_action(ICAL_ACTION_AUDIO));
+    attach = icalattach_new_from_url(appt->sound);
+    icalcomponent_add_property(ialarm
+            , icalproperty_new_attach(attach));
+    if (appt->soundrepeat) {
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_repeat(appt->soundrepeat_cnt));
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_duration(
+                        icaldurationtype_from_int(appt->soundrepeat_len)));
+    }
+}
+
+/* emailprop  = 5*(
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+                action / description / trigger / summary
+                ; the following is REQUIRED,
+                ; and MAY occur more than once
+                attendee /
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+                duration / repeat /
+                ; the following are optional,
+                ; and MAY occur more than once
+                attach / x-prop
+                )
+*/
+static void appt_add_alarm_internal_email(xfical_appt *appt
+        , icalcomponent *ialarm)
+{
+#undef P_N
+#define P_N "appt_add_alarm_internal_email: "
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    /*
+    icalcomponent_add_property(ialarm
+            , icalproperty_new_action(ICAL_ACTION_EMAIL));
+    */
+    g_warning("EMAIL ACTION not implemented yet");
+}
+
+/* procprop   = 3*(
+                ; the following are all REQUIRED,
+                ; but MUST NOT occur more than once
+                action / attach / trigger /
+                ; 'duration' and 'repeat' are both optional,
+                ; and MUST NOT occur more than once each,
+                ; but if one occurs, so MUST the other
+                duration / repeat /
+                ; 'description' is optional,
+                ; and MUST NOT occur more than once
+                description /
+                ; the following is optional,
+                ; and MAY occur more than once
+                x-prop
+                )
+*/
+static void appt_add_alarm_internal_procedure(xfical_appt *appt
+        , icalcomponent *ialarm)
+{
+#undef P_N
+#define P_N "appt_add_alarm_internal_procedure: "
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    /*
+    icalcomponent_add_property(ialarm
+            , icalproperty_new_action(ICAL_ACTION_PROCEDURE));
+    */
+    g_warning("PROCEDURE ACTION not implemented yet");
+}
+
+static icalcomponent *appt_add_alarm_internal_base(xfical_appt *appt
+        , struct icaltriggertype trg)
+{
+#undef P_N
+#define P_N "appt_add_alarm_internal_base: "
+    icalcomponent *ialarm;
+
+#ifdef ORAGE_DEBUG
+    g_print(P_N "\n");
+#endif
+    ialarm = icalcomponent_new(ICAL_VALARM_COMPONENT);
+    if (appt->alarm_related_start)
+        icalcomponent_add_property(ialarm
+                , icalproperty_new_trigger(trg));
+    else
+        icalcomponent_add_property(ialarm
+                , icalproperty_vanew_trigger(trg
+                        , icalparameter_new_related(ICAL_RELATED_END)
+                        , 0));
+    return(ialarm);
+}
+
+/* Add VALARM. We know we need one when we come here. 
+ * We also assume all alarms start and stop same time = have same trigger
+ */
 static void appt_add_alarm_internal(xfical_appt *appt, icalcomponent *ievent)
 {
 #undef P_N
@@ -1478,7 +1656,6 @@
     icalcomponent *ialarm;
     gint duration=0;
     struct icaltriggertype trg;
-    icalattach *attach;
 
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
@@ -1487,55 +1664,40 @@
     trg.time = icaltime_null_time();
     if (appt->alarm_before)
         trg.duration = icaldurationtype_from_int(-duration);
-    else
+    else /* alarm happens after */
         trg.duration = icaldurationtype_from_int(duration);
+
     /********** DISPLAY **********/
-    ialarm = icalcomponent_vanew(ICAL_VALARM_COMPONENT
-        , icalproperty_new_action(ICAL_ACTION_DISPLAY)
-        , NULL);
-    if (appt->alarm_related_start)
-        icalcomponent_add_property(ialarm
-                , icalproperty_new_trigger(trg));
-    else
-        icalcomponent_add_property(ialarm
-                , icalproperty_vanew_trigger(trg
-                        , icalparameter_new_related(ICAL_RELATED_END)
-                        , 0));
-    if ORAGE_STR_EXISTS(appt->note)
-        icalcomponent_add_property(ialarm
-            , icalproperty_new_description(appt->note));
-    else if ORAGE_STR_EXISTS(appt->title)
-        icalcomponent_add_property(ialarm
-            , icalproperty_new_description(appt->title));
-    else
-        icalcomponent_add_property(ialarm
-            , icalproperty_new_description(_("Orage default alarm")));
-    icalcomponent_add_component(ievent, ialarm);
+    if (appt->display_alarm_orage || appt->display_alarm_notify) {
+        ialarm = appt_add_alarm_internal_base(appt, trg);
+        appt_add_alarm_internal_display(appt, ialarm);
+        icalcomponent_add_component(ievent, ialarm);
+    }
+
     /********** AUDIO **********/
+    if (appt->sound_alarm && ORAGE_STR_EXISTS(appt->sound)) {
+        ialarm = appt_add_alarm_internal_base(appt, trg);
+        appt_add_alarm_internal_audio(appt, ialarm);
+        icalcomponent_add_component(ievent, ialarm);
+    }
+
+    /********** EMAIL **********/
+    /*
     if ORAGE_STR_EXISTS(appt->sound) {
-        ialarm = icalcomponent_vanew(ICAL_VALARM_COMPONENT
-            , icalproperty_new_action(ICAL_ACTION_AUDIO)
-            , NULL);
-        if (appt->alarm_related_start)
-            icalcomponent_add_property(ialarm
-                    , icalproperty_new_trigger(trg));
-        else
-            icalcomponent_add_property(ialarm
-                    , icalproperty_vanew_trigger(trg
-                            , icalparameter_new_related(ICAL_RELATED_END)
-                            , 0));
-        attach = icalattach_new_from_url(appt->sound);
-        icalcomponent_add_property(ialarm
-            , icalproperty_new_attach(attach));
-        if (appt->soundrepeat) {
-            icalcomponent_add_property(ialarm
-                , icalproperty_new_repeat(appt->soundrepeat_cnt));
-            icalcomponent_add_property(ialarm
-                , icalproperty_new_duration(
-                        icaldurationtype_from_int(appt->soundrepeat_len)));
-        }
+        ialarm = appt_add_alarm_internal_base(appt, trg);
+        appt_add_alarm_internal_email(appt, ialarm);
         icalcomponent_add_component(ievent, ialarm);
     }
+    */
+
+    /********** PROCEDURE **********/
+    /*
+    if ORAGE_STR_EXISTS(appt->sound) {
+        ialarm = appt_add_alarm_internal_base(appt, trg);
+        appt_add_alarm_internal_procedure(appt, ialarm);
+        icalcomponent_add_component(ievent, ialarm);
+    }
+    */
 }
 
 static void appt_add_recur_internal(xfical_appt *appt, icalcomponent *ievent)
@@ -1864,10 +2026,14 @@
     icalcomponent *ca = NULL;
     icalproperty *p = NULL;
     struct icaltriggertype trg;
+    enum icalproperty_action act;
     icalattach *attach;
     struct icaldurationtype duration;
     icalparameter *trg_related_par;
     icalparameter_related rel;
+    gboolean display_alarm = FALSE;
+    char *text;
+    int i;
 
 #ifdef ORAGE_DEBUG
     g_print(P_N "\n");
@@ -1919,8 +2085,48 @@
                 case ICAL_DURATION_PROPERTY:
                     duration = icalproperty_get_duration(p);
                     appt->soundrepeat_len = icaldurationtype_as_int(duration);
+                    break;
+                case ICAL_X_PROPERTY:
+                    text = (char *)icalproperty_get_x_name(p);
+                    /*
+                    g_print(P_N "x-property %s\n", text);
+                    */
+                    if (!strcmp(text, "X-ORAGE-DISPLAY-ALARM")) {
+                        text = (char *)icalproperty_get_value_as_string(p);
+                    /*
+                    g_print(P_N "x-value %s\n", text);
+                    */
+                        if (!strcmp(text, "ORAGE")) {
+                            appt->display_alarm_orage = TRUE;
+                    /*
+                    g_print(P_N "x-orage %s\n", text);
+                    */
+                        }
+                        else if (!strcmp(text, "NOTIFY")) {
+                            appt->display_alarm_notify = TRUE;
+                    /*
+                    g_print(P_N "x-notify %s\n", text);
+                    */
+                        }
+                    }
+                    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);
+                    }
+                    break;
                 case ICAL_ACTION_PROPERTY:
-                /* no actions defined */
+                    act = icalproperty_get_action(p);
+                    if (act == ICAL_ACTION_AUDIO)
+                        appt->sound_alarm = TRUE;
+                    else if (act == ICAL_ACTION_DISPLAY)
+                    /* we do not know yet which type of display alarm this is */
+                        display_alarm = TRUE;
+                    else /* unsupported property */
+                        g_warning(P_N "unknown action property %d", act);
                     break;
                 default:
                     g_warning(P_N "unknown property %s", (char *)icalproperty_get_property_name(p));
@@ -1928,6 +2134,10 @@
             }
         }
     }
+    /* default display alarm is Orage style */
+    if (display_alarm
+            && (!appt->display_alarm_orage && !appt->display_alarm_notify))	
+        appt->display_alarm_orage = TRUE;
 }
 
 static void process_start_date(xfical_appt *appt, icalproperty *p
@@ -2089,31 +2299,42 @@
             eltime = icaltime_null_time();
             duration = icaldurationtype_null_duration();
             key_found = TRUE;
+            appt.uid = NULL;
             appt.title = NULL;
             appt.location = NULL;
-            appt.alarmtime = 0;
-            appt.availability = -1;
-            appt.priority = 0;
             appt.allDay = FALSE;
-            appt.soundrepeat = FALSE;
-            appt.soundrepeat_cnt = 500;
-            appt.soundrepeat_len = 2;
-            appt.note = NULL;
-            appt.sound = NULL;
-            appt.uid = NULL;
             appt.starttime[0] = '\0';
             appt.start_tz_loc = NULL;
             appt.endtime[0] = '\0';
             appt.end_tz_loc = NULL;
+            appt.use_duration = FALSE;
+            appt.duration = 0;
             appt.completed = FALSE;
             appt.completedtime[0] = '\0';
             appt.completed_tz_loc = NULL;
-            appt.use_duration = FALSE;
-            appt.duration = 0;
+            appt.availability = -1;
+            appt.priority = 0;
+            appt.note = NULL;
+            appt.alarmtime = 0;
+            appt.alarm_before = TRUE;
+            appt.alarm_related_start = TRUE;
+            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;
+/*
+            appt.email_alarm = FALSE;
+            appt.email_attendees = NULL;
+            appt.procedure_alarm = FALSE;
+            appt.procedure_cmd = NULL;
+*/
             appt.starttimecur[0] = '\0';
             appt.endtimecur[0] = '\0';
             appt.freq = XFICAL_FREQ_NONE;
-            appt.interval = 1;
             appt.recur_limit = 0;
             appt.recur_count = 0;
             appt.recur_until[0] = '\0';
@@ -2121,6 +2342,7 @@
                 appt.recur_byday[i] = TRUE;
                 appt.recur_byday_cnt[i] = 0;
             }
+            appt.interval = 1;
         /*********** Properties ***********/
             for (p = icalcomponent_get_first_property(c, ICAL_ANY_PROPERTY);
                  p != 0;
@@ -2446,6 +2668,10 @@
     g_free(appt->end_tz_loc);
     g_free(appt->note);
     g_free(appt->sound);
+    /*
+    g_free(appt->email_attendees);
+    g_free(appt->procedure_cmd);
+    */
     g_free(appt);
 }
 
@@ -3405,7 +3631,9 @@
             for (c2=icalcomponent_get_first_component(c1, ICAL_ANY_COMPONENT);
                  c2 != 0;
                  c2=icalcomponent_get_next_component(c1, ICAL_ANY_COMPONENT)){
-                if (icalcomponent_isa(c2) == ICAL_VEVENT_COMPONENT) {
+                if ((icalcomponent_isa(c2) == ICAL_VEVENT_COMPONENT)
+                ||  (icalcomponent_isa(c2) == ICAL_VTODO_COMPONENT)
+                ||  (icalcomponent_isa(c2) == ICAL_VJOURNAL_COMPONENT)) {
                     cnt2++;
                     add_event(c2);
                 }

Modified: xfcalendar/trunk/src/ical-code.h
===================================================================
--- xfcalendar/trunk/src/ical-code.h	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/ical-code.h	2007-05-19 20:54:25 UTC (rev 25721)
@@ -42,7 +42,7 @@
    ,XFICAL_TYPE_JOURNAL
 } xfical_type;
 
-typedef struct
+typedef struct _xfical_appt
 {
     gchar *uid; 
     /* note that version 4.5.9 changed uid format.
@@ -79,15 +79,30 @@
     gchar *note;
 
         /* alarm */
-    gint alarmtime;
+    gint alarmtime; /* 0 means no alarms */
     gboolean alarm_before; /* TRUE = before FALSE = after */
         /* TRUE = related to start FALSE= related to end */
     gboolean alarm_related_start; 
+
+    gboolean sound_alarm;
     gchar *sound;
     gboolean soundrepeat;
     gint soundrepeat_cnt;
     gint soundrepeat_len;
 
+    gboolean display_alarm_orage;
+    gboolean display_alarm_notify;
+        /* used only with libnotify. -1 = no timeout 0 = use default timeout */
+    gint display_notify_timeout;  
+
+    /*
+    gboolean email_alarm;
+    gchar *email_attendees;
+
+    gboolean procedure_alarm;
+    gchar *procedure_cmd;
+    */
+
         /* for repeating events cur times show current repeating event.
          * normal times are always the real (=first) start and end times
          */

Modified: xfcalendar/trunk/src/main.c
===================================================================
--- xfcalendar/trunk/src/main.c	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/main.c	2007-05-19 20:54:25 UTC (rev 25721)
@@ -264,9 +264,9 @@
     g_print(_("using GTK+-%d.%d.%d.\n")
             , gtk_major_version, gtk_minor_version, gtk_micro_version);
 #ifdef HAVE_DBUS
-    g_print(_("\tusing DBUS for import.\n"));
+    g_print(_("\tUsing DBUS for import.\n"));
 #else
-    g_print(_("\tnot using DBUS. import works only partially.\n"));
+    g_print(_("\tNot using DBUS. Import works only partially.\n"));
 #endif
     g_print("\n");
 }

Modified: xfcalendar/trunk/src/reminder.c
===================================================================
--- xfcalendar/trunk/src/reminder.c	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/reminder.c	2007-05-19 20:54:25 UTC (rev 25721)
@@ -42,6 +42,9 @@
 #include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
 #include <libxfcegui4/dialogs.h>
+#ifdef HAVE_NOTIFY
+#include <libnotify/notify.h>
+#endif
 
 #include "functions.h"
 #include "mainbox.h"
@@ -53,14 +56,8 @@
 #include "tray_icon.h"
 #include "parameters.h"
 
+void create_notify_reminder(alarm_struct *alarm);
 
-void set_play_command(gchar *cmd)
-{
-    if (g_par.sound_application)
-        g_free(g_par.sound_application);
-    g_par.sound_application = g_strdup(cmd);
-}
-
 static void child_setup_async(gpointer user_data)
 {
 #if defined(HAVE_SETSID) && !defined(G_OS_WIN32)
@@ -100,110 +97,187 @@
     return success;
 }
 
-gboolean orage_sound_alarm(gpointer data)
+static void alarm_free_memory(alarm_struct *alarm)
 {
+    if (!alarm->display_orage && !alarm->display_notify)
+        /* if both visuals are gone we can't stop audio anymore, so stop it 
+         * now before it is too late */
+        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);
+        if (alarm->title != NULL)
+            g_string_free(alarm->title, TRUE);
+        if (alarm->description != NULL)
+            g_string_free(alarm->description, TRUE);
+        if (alarm->sound != NULL)
+            g_string_free(alarm->sound, TRUE);
+        g_free(alarm->active_alarm);
+        g_free(alarm);
+    }
+}
+
+static gboolean sound_alarm(gpointer data)
+{
+    alarm_struct *alarm = (alarm_struct *)data;
     GError *error = NULL;
     gboolean status;
-    orage_audio_alarm_type *audio_alarm = (orage_audio_alarm_type *) data;
-    GtkWidget *wReminder;
     GtkWidget *stop;
 
     /* note: -1 loops forever */
-    if (audio_alarm->cnt != 0) {
-        /*
-        status = xfce_exec(audio_alarm->play_cmd, FALSE, FALSE, &error);
-        */
-        if (audio_alarm->sound_active) {
+    if (alarm->repeat_cnt != 0) {
+        if (alarm->active_alarm->sound_active) {
             return(TRUE);
         }
-        status = orage_exec(audio_alarm->play_cmd, &audio_alarm->sound_active
-                , &error);
+        status = orage_exec(alarm->sound->str
+                , &alarm->active_alarm->sound_active, &error);
         if (!status) {
-            g_warning("reminder: play failed (%si)", audio_alarm->play_cmd);
-            audio_alarm->cnt = 0; /* one warning is enough */
+            g_warning("reminder: play failed (%si)", alarm->sound->str);
+            alarm->repeat_cnt = 0; /* one warning is enough */
         }
-        else if (audio_alarm->cnt > 0)
-            audio_alarm->cnt--;
+        else if (alarm->repeat_cnt > 0)
+            alarm->repeat_cnt--;
     }
-    else { /* cnt == 0 */
-        if ((wReminder = audio_alarm->wReminder) != NULL) {
-            g_object_steal_data(G_OBJECT(wReminder), "AUDIO ACTIVE");
-            stop = g_object_get_data(G_OBJECT(wReminder), "AUDIO STOP");
+    else { /* repeat_cnt == 0 */
+        if (alarm->display_orage 
+        && ((stop = alarm->active_alarm->stop_noise_reminder) != NULL)) {
             gtk_widget_set_sensitive(GTK_WIDGET(stop), FALSE);
         }
-        g_free(audio_alarm->play_cmd);
-        g_free(data);
-        status = FALSE; /* no more alarms */
+#ifdef HAVE_NOTIFY
+        if (alarm->display_notify) {
+            /* We need to remove the silence button from notify window.
+             * This is not nice method, but it is not possible to access
+             * the timeout so we just need to start it from all over */
+            notify_notification_close(alarm->active_alarm->active_notify, NULL);
+            create_notify_reminder(alarm);
+        }
+#endif
+        alarm_free_memory(alarm);
+        status = FALSE; /* no more alarms, end timeouts */
     }
         
     return(status);
 }
 
-orage_audio_alarm_type *create_soundReminder(alarm_struct *alarm
-        , GtkWidget *wReminder)
+static void create_sound_reminder(alarm_struct *alarm)
 {
-    orage_audio_alarm_type *audio_alarm;
-
-    audio_alarm =  g_new(orage_audio_alarm_type, 1);
-    audio_alarm->play_cmd = g_strconcat(g_par.sound_application, " \""
-            , alarm->sound->str, "\"", NULL);
-    audio_alarm->delay = alarm->repeat_delay;
-    audio_alarm->sound_active = FALSE;
-    if ((audio_alarm->cnt = alarm->repeat_cnt) == 0) {
-        audio_alarm->cnt++;
-        audio_alarm->wReminder = NULL;
+    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 */
     }
-    else { /* repeat alarm */
-        audio_alarm->wReminder = wReminder;
-        g_object_set_data(G_OBJECT(wReminder), "AUDIO ACTIVE", audio_alarm);
-    }
 
     g_timeout_add(alarm->repeat_delay*1000
-            , (GtkFunction) orage_sound_alarm
-            , (gpointer) audio_alarm);
+            , (GtkFunction) sound_alarm
+            , (gpointer) alarm);
+}
 
-    return(audio_alarm);
+#ifdef HAVE_NOTIFY
+static void notify_closed(NotifyNotification *n, gpointer par)
+{
+    alarm_struct *alarm = (alarm_struct *)par;
+
+    alarm->display_notify = FALSE; /* I am gone */
+    alarm_free_memory(alarm);
 }
 
-void on_btOkReminder_clicked(GtkButton *button, gpointer user_data)
+static void notify_action_open(NotifyNotification *n, const char *action
+        , gpointer par)
 {
-    GtkWidget *wReminder = (GtkWidget *)user_data;
+    alarm_struct *alarm = (alarm_struct *)par;
 
-    gtk_widget_destroy(wReminder); /* destroy the specific appointment window */
+    create_notify_reminder(alarm);
+    create_appt_win("UPDATE", alarm->uid->str, NULL);
 }
 
-void on_btStopNoiseReminder_clicked(GtkButton *button, gpointer user_data)
+static void notify_action_silence(NotifyNotification *n, const char *action
+        , gpointer par)
 {
-    orage_audio_alarm_type *audio_alarm = (orage_audio_alarm_type *)user_data;
+    alarm_struct *alarm = (alarm_struct *)par;
 
-    audio_alarm->cnt = 0;
+    alarm->repeat_cnt = 0;
+    create_notify_reminder(alarm);
+}
+#endif
+
+void create_notify_reminder(alarm_struct *alarm) 
+{
+#ifdef HAVE_NOTIFY
+    char heading[250];
+    NotifyNotification *n;
+
+    if (!notify_init("Orage")) {
+        g_warning("Notify init failed\n");
+        return;
+    }
+
+    strncpy(heading,  _("Reminder "), 199);
+    strncat(heading, alarm->title->str, 50);
+    n = notify_notification_new(heading, alarm->description->str, 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);
+
+    if (alarm->notify_timeout == -1)
+        notify_notification_set_timeout(n, NOTIFY_EXPIRES_NEVER);
+    else if (alarm->notify_timeout == 0)
+        notify_notification_set_timeout(n, NOTIFY_EXPIRES_DEFAULT);
+    else
+        notify_notification_set_timeout(n, alarm->notify_timeout*1000);
+
+    notify_notification_add_action(n, "open", _("Open")
+            , (NotifyActionCallback)notify_action_open
+            , alarm, NULL);
+    if ((alarm->audio) && (alarm->repeat_cnt > 1)) {
+        notify_notification_add_action(n, "stop", "Silence"
+                , (NotifyActionCallback)notify_action_silence
+                , alarm, NULL);
+    }
+    (void)g_signal_connect(G_OBJECT(n), "closed"
+           , G_CALLBACK(notify_closed), alarm);
+
+    if (!notify_notification_show(n, NULL)) {
+        g_warning("failed to send notification");
+    }
+#else
+    g_warning("libnotify not linked in. Can't use notifications.");
+#endif
+}
+
+static void destroy_orage_reminder(GtkWidget *wReminder, gpointer user_data)
+{
+    alarm_struct *alarm = (alarm_struct *)user_data;
+
+    alarm->display_orage = FALSE; /* I am gone */
+    alarm_free_memory(alarm);
+}
+
+static void on_btStopNoiseReminder_clicked(GtkButton *button
+        , gpointer user_data)
+{
+    alarm_struct *alarm = (alarm_struct *)user_data;
+
+    alarm->repeat_cnt = 0;
     gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
 }
 
-void on_btOpenReminder_clicked(GtkButton *button, gpointer user_data)
+static void on_btOkReminder_clicked(GtkButton *button, gpointer user_data)
 {
     GtkWidget *wReminder = (GtkWidget *)user_data;
-    gchar *uid;
-    appt_win *app;
-                                                                                
-    if ((uid = (gchar *)g_object_get_data(G_OBJECT(wReminder), "ALARM_UID"))
-        != NULL) {
-        app = create_appt_win("UPDATE", uid, NULL);
-    }
+
+    gtk_widget_destroy(wReminder); /* destroy the specific appointment window */
 }
 
-static void on_destroy(GtkWidget *wReminder, gpointer user_data)
+static void on_btOpenReminder_clicked(GtkButton *button, gpointer user_data)
 {
-    orage_audio_alarm_type *audio_alarm = (orage_audio_alarm_type *)user_data;
+    alarm_struct *alarm = (alarm_struct *)user_data;
 
-    if (g_object_get_data(G_OBJECT(wReminder), "AUDIO ACTIVE") != NULL) {
-        audio_alarm->cnt = 0;
-        audio_alarm->wReminder = NULL; /* window is being distroyed */
-    }
-    g_free(g_object_get_data(G_OBJECT(wReminder), "ALARM_UID")); /* free uid */
+    create_appt_win("UPDATE", alarm->uid->str, NULL);
 }
 
-void create_wReminder(alarm_struct *alarm)
+static void create_orage_reminder(alarm_struct *alarm)
 {
     GtkWidget *wReminder;
     GtkWidget *vbReminder;
@@ -216,8 +290,6 @@
     GtkWidget *hdReminder;
     char heading[250];
     gchar *head2;
-    orage_audio_alarm_type *audio_alarm;
-    gchar *alarm_uid;
 
     wReminder = gtk_dialog_new();
     gtk_widget_set_size_request(wReminder, 300, 250);
@@ -229,72 +301,106 @@
     gtk_window_set_keep_above(GTK_WINDOW(wReminder), TRUE);
 
     vbReminder = GTK_DIALOG(wReminder)->vbox;
-    gtk_widget_show(vbReminder);
 
     strncat(heading, alarm->title->str, 50);
     head2 = g_markup_escape_text(heading, -1);
     hdReminder = xfce_create_header(NULL, head2);
     g_free(head2);
-    gtk_widget_show(hdReminder);
     gtk_box_pack_start(GTK_BOX(vbReminder), hdReminder, FALSE, TRUE, 0);
 
     swReminder = gtk_scrolled_window_new(NULL, NULL);
     gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swReminder)
             , GTK_SHADOW_NONE);
-    gtk_widget_show(swReminder);
     gtk_box_pack_start(GTK_BOX(vbReminder), swReminder, TRUE, TRUE, 5);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swReminder)
             , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
     lbReminder = gtk_label_new(alarm->description->str);
     gtk_label_set_line_wrap(GTK_LABEL(lbReminder), TRUE);
-    gtk_widget_show(lbReminder);
     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swReminder)
             , lbReminder);
 
     daaReminder = GTK_DIALOG(wReminder)->action_area;
     gtk_dialog_set_has_separator(GTK_DIALOG(wReminder), FALSE);
-    gtk_widget_show(daaReminder);
     gtk_button_box_set_layout(GTK_BUTTON_BOX(daaReminder), GTK_BUTTONBOX_END);
 
     btOpenReminder = gtk_button_new_from_stock("gtk-open");
-    gtk_widget_show(btOpenReminder);
     gtk_dialog_add_action_widget(GTK_DIALOG(wReminder), btOpenReminder
             , GTK_RESPONSE_OK);
 
     btOkReminder = gtk_button_new_from_stock("gtk-close");
-    gtk_widget_show(btOkReminder);
     gtk_dialog_add_action_widget(GTK_DIALOG(wReminder), btOkReminder
             , GTK_RESPONSE_OK);
     GTK_WIDGET_SET_FLAGS(btOkReminder, GTK_CAN_DEFAULT);
 
-    alarm_uid = g_strdup(alarm->uid->str);
-    g_object_set_data(G_OBJECT(wReminder), "ALARM_UID", alarm_uid);
     g_signal_connect((gpointer) btOpenReminder, "clicked"
-            , G_CALLBACK(on_btOpenReminder_clicked), wReminder);
+            , G_CALLBACK(on_btOpenReminder_clicked), alarm);
 
     g_signal_connect((gpointer) btOkReminder, "clicked"
             , G_CALLBACK(on_btOkReminder_clicked), wReminder);
 
-    if (alarm->audio) {
-        audio_alarm = create_soundReminder(alarm, wReminder);
-        if (alarm->repeat_cnt != 0) {
-            btStopNoiseReminder = gtk_button_new_from_stock("gtk-stop");
-            gtk_widget_show(btStopNoiseReminder);
-            gtk_dialog_add_action_widget(GTK_DIALOG(wReminder)
-                    , btStopNoiseReminder, GTK_RESPONSE_OK);
-            g_object_set_data(G_OBJECT(wReminder), "AUDIO STOP"
-                    , btStopNoiseReminder);
-
-            g_signal_connect((gpointer) btStopNoiseReminder, "clicked",
-                G_CALLBACK(on_btStopNoiseReminder_clicked), audio_alarm);
-            g_signal_connect(G_OBJECT(wReminder), "destroy",
-                G_CALLBACK(on_destroy), audio_alarm);
-        }
+    if ((alarm->audio) && (alarm->repeat_cnt > 1)) {
+        btStopNoiseReminder = gtk_button_new_from_stock("gtk-stop");
+        alarm->active_alarm->stop_noise_reminder = btStopNoiseReminder;
+        gtk_dialog_add_action_widget(GTK_DIALOG(wReminder)
+                , btStopNoiseReminder, GTK_RESPONSE_OK);
+        g_signal_connect((gpointer)btStopNoiseReminder, "clicked",
+            G_CALLBACK(on_btStopNoiseReminder_clicked), alarm);
+        g_signal_connect(G_OBJECT(wReminder), "destroy",
+            G_CALLBACK(destroy_orage_reminder), alarm);
     }
-    gtk_widget_show(wReminder);
+    gtk_widget_show_all(wReminder);
 }
 
+void create_reminders(alarm_struct *alarm)
+{
+    alarm_struct *n_alarm;
+
+    /* FIXME: instead of copying this new private version of the alarm,
+     * g_list_remove(GList *g_par.alarm_list, gconstpointer alarm);
+     * remove it and use the original. saves time */
+    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->notify_timeout = alarm->notify_timeout;
+    n_alarm->display = alarm->display;
+    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)
+        n_alarm->sound = g_string_new(alarm->sound->str);
+    n_alarm->repeat_cnt = alarm->repeat_cnt;
+    n_alarm->repeat_delay = alarm->repeat_delay;
+    if (n_alarm->display
+    && (!n_alarm->display_orage && !n_alarm->display_notify))
+        n_alarm->display_orage = TRUE;
+    n_alarm->active_alarm = g_new0(active_alarm_struct, 1);
+
+    if (n_alarm->audio)
+        create_sound_reminder(n_alarm);
+    if (n_alarm->display_orage)
+        create_orage_reminder(n_alarm);
+    if (n_alarm->display_notify)
+        create_notify_reminder(n_alarm);
+    /*
+    if (alarm->display
+    && (!alarm->display_orage && !alarm->display_notify))
+        alarm->display_orage = TRUE;
+    alarm->active_alarm = g_new0(active_alarm_struct, 1);
+
+    if (alarm->audio)
+        create_sound_reminder(alarm);
+    if (alarm->display_orage)
+        create_orage_reminder(alarm);
+    if (alarm->display_notify)
+        create_notify_reminder(alarm);
+        */
+}
+
 gboolean orage_alarm_clock(gpointer user_data)
 {
     CalWin *xfcal = (CalWin *)user_data;
@@ -358,17 +464,14 @@
         cur_alarm = (alarm_struct *)alarm_l->data;
         g_sprintf(time_now, XFICAL_APPT_TIME_FORMAT, t->tm_year + 1900
                 , t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
-        if (strcmp(time_now, cur_alarm->alarm_time->str) > 0) {
-            /*
-        if (xfical_alarm_passed(cur_alarm->alarm_time->str)) {
-        */
-            create_wReminder(cur_alarm);
+        if (strcmp(time_now, cur_alarm->alarm_time) > 0) {
+            create_reminders(cur_alarm);
             alarm_raised = TRUE;
         }
-        else /*if (strcmp(time_now, cur_alarm->alarm_time->str) <= 0) */ {
+        else /*if (strcmp(time_now, cur_alarm->alarm_time) <= 0) */ {
             /* check if this should be visible in systray icon tooltip */
             if (tooltip && (alarm_cnt < tooltip_alarm_limit)) {
-                sscanf(cur_alarm->alarm_time->str, XFICAL_APPT_TIME_FORMAT
+                sscanf(cur_alarm->alarm_time, XFICAL_APPT_TIME_FORMAT
                         , &year, &month, &day, &hour, &minute, &second);
                 g_now = g_date_new_dmy(t->tm_mday, t->tm_mon + 1
                         , t->tm_year + 1900);
@@ -396,8 +499,9 @@
                 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); 
+    }
 
     if (tooltip) {
         if (alarm_cnt == 0)

Modified: xfcalendar/trunk/src/reminder.h
===================================================================
--- xfcalendar/trunk/src/reminder.h	2007-05-17 20:00:53 UTC (rev 25720)
+++ xfcalendar/trunk/src/reminder.h	2007-05-19 20:54:25 UTC (rev 25721)
@@ -24,33 +24,39 @@
 #ifndef __REMINDER_H__
 #define __REMINDER_H__
 
-typedef struct 
+typedef struct _active_alarm_struct
 {
+    gboolean sound_active; /* sound is currently being played */
+    GtkWidget *stop_noise_reminder;
+    gpointer active_notify; /* this is NotifyNotification, but it may not be
+                               linked in, so need to be done like this */
+} active_alarm_struct;
+
+typedef struct _alarm_struct
+{
+    gchar   *alarm_time;
     GString *uid;
-    GString *alarm_time;
-    GString *event_time;
     GString *title;
+    GString *description;
+
     gboolean display;
-    GString *description;
+    gboolean display_orage;
+    gboolean display_notify;
+    gint     notify_timeout;
+
     gboolean audio;
     GString *sound;
     gint     repeat_cnt;
     gint     repeat_delay;
+
+    /*
+    gboolean email;
+    gboolean procedure;
+    */
+    /* this is used to control active alarms */
+    active_alarm_struct *active_alarm;
 } alarm_struct;
 
-typedef struct {
-    gchar *play_cmd;
-    gint cnt;
-    gint delay;
-    GtkWidget *wReminder; /* needed for callbacks when stopping timer */
-    gboolean sound_active;
-} orage_audio_alarm_type;
-
-
-void create_wReminder(alarm_struct *alarm);
-
 gboolean orage_alarm_clock(gpointer user_data);
 
-void set_play_command(gchar *cmd);
-
 #endif /* !__REMINDER_H__ */



More information about the Xfce4-commits mailing list