[Xfce4-commits] r29900 - in xfcalendar/trunk: . panel-plugin plugin src

Juha Kautto juha at xfce.org
Fri Apr 24 09:18:45 CEST 2009


Author: juha
Date: 2009-04-24 07:18:45 +0000 (Fri, 24 Apr 2009)
New Revision: 29900

Removed:
   xfcalendar/trunk/plugin/xfcalendar_plugin.c
   xfcalendar/trunk/src/xfce_trayicon.c
   xfcalendar/trunk/src/xfce_trayicon.h
Modified:
   xfcalendar/trunk/NEWS
   xfcalendar/trunk/README
   xfcalendar/trunk/TODO
   xfcalendar/trunk/configure.in.in
   xfcalendar/trunk/panel-plugin/orageclock.c
   xfcalendar/trunk/plugin/Makefile.am
   xfcalendar/trunk/src/Makefile.am
   xfcalendar/trunk/src/appointment.c
   xfcalendar/trunk/src/appointment.h
   xfcalendar/trunk/src/day-view.c
   xfcalendar/trunk/src/day-view.h
   xfcalendar/trunk/src/event-list.c
   xfcalendar/trunk/src/functions.c
   xfcalendar/trunk/src/functions.h
   xfcalendar/trunk/src/ical-code.c
   xfcalendar/trunk/src/ical-code.h
   xfcalendar/trunk/src/interface.c
   xfcalendar/trunk/src/main.c
   xfcalendar/trunk/src/mainbox.c
   xfcalendar/trunk/src/parameters.c
   xfcalendar/trunk/src/parameters.h
   xfcalendar/trunk/src/reminder.c
   xfcalendar/trunk/src/tray_icon.c
   xfcalendar/trunk/src/tray_icon.h
Log:
Version 4.7.1
First version after stable release 4.6.
Several changes:
Dependent on GTK 2.10, Removed 4.4 Xfce dependency MCS.
Does not work with Xfce 4.4 anymore.
Xfce trayicon removed and replaced with gtk trayicon.
Using g_timeout_add_seconds.
Possibility to have TODOs repeating based on completed time.
Import no longer creates dublicate entries.
Added visual presentation of recurring appointments.
Added priority and possibility to skip low pri events in lists.



Modified: xfcalendar/trunk/NEWS
===================================================================
--- xfcalendar/trunk/NEWS	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/NEWS	2009-04-24 07:18:45 UTC (rev 29900)
@@ -1,3 +1,20 @@
+20091504: differences between 4.7.1 and 4.6 Version or Orage
+---------
+        * Removed Xfce trayicon code and replaced it with gtk trayicon
+        * Now dependent on GTK 2.10
+        * Removed 4.4 Xfce dependency MCS
+        * clarified default alarm setting in appointment alarm page
+        * Using g_timeout_add_seconds in orage if available (Bug 4723) 
+        * Possibility to have TODOs repeating based on completed time (Bug 4713)
+        * Added visual presentation of recurring appointments
+        * Added priority and possibility to omit low priority appointments from
+          day list view and calendar
+        * Fixed core dump in event-list when event crossed days on "today"
+        * Import no longer creates dublicate entries (Debian BUG 517548)
+
+20090227: 4.6.0 Version of Orage published
+---------
+
 20080718: differences between 4.6 and 4.4 Version or Orage
 ---------
         * Man page created for orage and globaltime

Modified: xfcalendar/trunk/README
===================================================================
--- xfcalendar/trunk/README	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/README	2009-04-24 07:18:45 UTC (rev 29900)
@@ -1,16 +1,16 @@
 Time-managing application for the Xfce desktop environment.
 
-Orage 4.3 uses new ical interface instead of old dbh to store and
-utilize calender appointments. 
+Orage uses ical interface instead of old dbh to store and
+utilize calender appointments.ince version 4.3
 
 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
-clean table.
+the new version (from 4.4 to 4.6 for example) so after each major version
+you need to manually add appointments.
 
-First thing you want to do is add your local timezone in the preferces,
+First thing you want to do is add your local timezone in the preferences,
 If you do not set local timezone, do not use timezones in any appointments
 either. It will cause just problems.

Modified: xfcalendar/trunk/TODO
===================================================================
--- xfcalendar/trunk/TODO	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/TODO	2009-04-24 07:18:45 UTC (rev 29900)
@@ -49,6 +49,7 @@
 
 13) Repeating rule visual presentation
     Show when events actually happen
+*** DONE 4.7 ***
 
 14) Alarm before the end of the event. 
     Needed for TODOs

Modified: xfcalendar/trunk/configure.in.in
===================================================================
--- xfcalendar/trunk/configure.in.in	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/configure.in.in	2009-04-24 07:18:45 UTC (rev 29900)
@@ -9,10 +9,10 @@
 dnl
 
 dnl Version information
-m4_define([orage_version], [4.7.0.0-svn])
+m4_define([orage_version], [4.7.1.1-svn])
 
-m4_define([gtk_minimum_version], [2.6.0])
-m4_define([xfce_minimum_version], [4.4.0])
+m4_define([gtk_minimum_version], [2.10.0])
+m4_define([xfce_minimum_version], [4.6.0])
 m4_define([dbus_minimum_version], [0.34])
 m4_define([notify_minimum_version], [0.3.2])
 m4_define([intltool_minimum_version], [0.31])
@@ -204,18 +204,6 @@
                            [notify_minimum_version], [libnotify], 
                            [LIBNOTIFY support])
 
-dnl ********************************
-dnl *** Optional support for MCS ***
-dnl ********************************
-XDT_CHECK_OPTIONAL_PACKAGE([XFCEMCS], [libxfce4mcs-client-1.0],
-                           [xfce_minimum_version], [libxfce4mcs], 
-                           [XFCE_MCS_MANAGER support])
-
-if test x"$XFCEMCS_FOUND" = x"yes"; then
-dnl configure the mcs plugin
-XDT_XFCE_MCS_PLUGIN([XFCE_MCS_MANAGER], [xfce_minimum_version])
-fi
-
 dnl ************************************************
 dnl *** Optional support for automatic archiving ***
 dnl ************************************************
@@ -276,10 +264,5 @@
 else
 echo "* LIBNOTIFY support:         no"
 fi
-if test x"$XFCEMCS_FOUND" = x"yes"; then
-echo "* XFCE MCS support:          yes"
-else
-echo "* XFCE MCS support:          no"
-fi
 echo "* Automatic archiving:       $have_archive"
 echo

Modified: xfcalendar/trunk/panel-plugin/orageclock.c
===================================================================
--- xfcalendar/trunk/panel-plugin/orageclock.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/panel-plugin/orageclock.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -580,6 +580,9 @@
 
     for (i = 0; i < OC_MAX_LINES; i++) {
         clock->line[i].label = gtk_label_new("");
+        /* clicking does not work after this
+        gtk_label_set_selectable(GTK_LABEL(clock->line[i].label), TRUE);
+        */
         g_object_ref(clock->line[i].label); /* it is not always in the vbox */
         gtk_widget_show(clock->line[i].label);
         clock->line[i].show = show_init[i];

Modified: xfcalendar/trunk/plugin/Makefile.am
===================================================================
--- xfcalendar/trunk/plugin/Makefile.am	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/plugin/Makefile.am	2009-04-24 07:18:45 UTC (rev 29900)
@@ -1,24 +1,3 @@
-if HAVE_XFCEMCS
-orage_plugindir = 							\
-	$(libdir)/xfce4/mcs-plugins
-
-orage_plugin_LTLIBRARIES = orage_plugin.la
-
-orage_plugin_la_LDFLAGS =					\
-	-avoid-version							\
-	-module
-
-orage_plugin_la_SOURCES =					\
-	xfcalendar_plugin.c
-
-orage_plugin_la_CFLAGS = 					\
-	$(XFCE_MCS_MANAGER_CFLAGS) 				\
-	-DBINDIR=\"$(bindir)\"	\
-	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"	\
-	-DSYSCONFDIR=\"$(sysconfdir)\"			\
-	-DDATADIR=\"$(pkgdatadir)\" 
-endif
-
 desktopdir = $(datadir)/applications
 desktop_in_files = xfce-xfcalendar-settings.desktop.in
 desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)

Modified: xfcalendar/trunk/src/Makefile.am
===================================================================
--- xfcalendar/trunk/src/Makefile.am	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/Makefile.am	2009-04-24 07:18:45 UTC (rev 29900)
@@ -25,9 +25,7 @@
 	reminder.c							\
 	reminder.h							\
 	tray_icon.c                                                     \
-	tray_icon.h                                                     \
-	xfce_trayicon.c							\
-	xfce_trayicon.h
+	tray_icon.h
 
 orage_CFLAGS =							\
 	$(LIBXFCEGUI4_CFLAGS)						\

Modified: xfcalendar/trunk/src/appointment.c
===================================================================
--- xfcalendar/trunk/src/appointment.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/appointment.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -46,8 +46,7 @@
 #include <glib/gprintf.h>
 #include <glib/gstdio.h>
 
-#include <libxfcegui4/libxfcegui4.h>
-
+#include "orage-i18n.h"
 #include "functions.h"
 #include "mainbox.h"
 #include "ical-code.h"
@@ -82,11 +81,11 @@
 static void refresh_categories(category_win_struct *catw);
 static void read_default_alarm(xfical_appt *appt);
 
+/*  
+ *  these are the main functions in this file:
+ */ 
 static void fill_appt_window(appt_win *apptw, char *action, char *par);
-/*  
- *  the previous and the following are the main functions in this file
-static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw)
-*/ 
+static gboolean fill_appt_from_apptw(xfical_appt *appt, appt_win *apptw);
 
 
 static GtkWidget *datetime_hbox_new(GtkWidget *date_button
@@ -115,7 +114,6 @@
 
     space_label = gtk_label_new("  ");
     gtk_box_pack_start(GTK_BOX(hbox), space_label, FALSE, FALSE, 0);
-
     gtk_box_pack_start(GTK_BOX(hbox), timezone_button, TRUE, TRUE, 0);
 
     return(hbox);
@@ -215,10 +213,6 @@
         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->CompletedDate_button, comp_act);
         if (dur_act) {
             gtk_widget_set_sensitive(apptw->EndDate_button, FALSE);
             gtk_widget_set_sensitive(apptw->Dur_spin_dd, due_act);
@@ -258,11 +252,11 @@
             gtk_widget_set_sensitive(apptw->Dur_spin_mm, FALSE);
             gtk_widget_set_sensitive(apptw->Dur_spin_mm_label, FALSE);
         }
-        gtk_widget_set_sensitive(apptw->CompletedDate_button, comp_act);
-        gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, comp_act);
-        gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, comp_act);
-        gtk_widget_set_sensitive(apptw->CompletedTimezone_button, comp_act);
     }
+    gtk_widget_set_sensitive(apptw->CompletedDate_button, comp_act);
+    gtk_widget_set_sensitive(apptw->CompletedTime_spin_hh, comp_act);
+    gtk_widget_set_sensitive(apptw->CompletedTime_spin_mm, comp_act);
+    gtk_widget_set_sensitive(apptw->CompletedTimezone_button, comp_act);
 }
 
 static void set_repeat_sensitivity(appt_win *apptw)
@@ -284,6 +278,7 @@
         gtk_widget_set_sensitive(apptw->Recur_int_spin, FALSE);
         gtk_widget_set_sensitive(apptw->Recur_int_spin_label1, FALSE);
         gtk_widget_set_sensitive(apptw->Recur_int_spin_label2, FALSE);
+        gtk_widget_set_sensitive(apptw->Recur_todo_base_hbox, FALSE);
     }
     else {
         gtk_widget_set_sensitive(apptw->Recur_limit_rb, TRUE);
@@ -321,6 +316,7 @@
         gtk_widget_set_sensitive(apptw->Recur_int_spin, TRUE);
         gtk_widget_set_sensitive(apptw->Recur_int_spin_label1, TRUE);
         gtk_widget_set_sensitive(apptw->Recur_int_spin_label2, TRUE);
+        gtk_widget_set_sensitive(apptw->Recur_todo_base_hbox, TRUE);
     }
 }
 
@@ -360,6 +356,8 @@
         gtk_widget_set_sensitive(apptw->End_label, TRUE);
         gtk_widget_set_sensitive(apptw->EndTime_hbox, TRUE);
         gtk_widget_set_sensitive(apptw->Dur_hbox, TRUE);
+        gtk_widget_hide(apptw->Recur_todo_base_label);
+        gtk_widget_hide(apptw->Recur_todo_base_hbox);
     }
     else if (gtk_toggle_button_get_active(
             GTK_TOGGLE_BUTTON(apptw->Type_todo_rb))) {
@@ -378,6 +376,8 @@
         gtk_widget_set_sensitive(apptw->End_label, TRUE);
         gtk_widget_set_sensitive(apptw->EndTime_hbox, TRUE);
         gtk_widget_set_sensitive(apptw->Dur_hbox, TRUE);
+        gtk_widget_show(apptw->Recur_todo_base_label);
+        gtk_widget_show(apptw->Recur_todo_base_hbox);
     }
     else /* if (gtk_toggle_button_get_active(
             GTK_TOGGLE_BUTTON(apptw->Type_journal_rb))) */ {
@@ -396,6 +396,8 @@
         gtk_widget_set_sensitive(apptw->End_label, FALSE);
         gtk_widget_set_sensitive(apptw->EndTime_hbox, FALSE);
         gtk_widget_set_sensitive(apptw->Dur_hbox, FALSE);
+        gtk_widget_hide(apptw->Recur_todo_base_label);
+        gtk_widget_hide(apptw->Recur_todo_base_hbox);
     }
     set_time_sensitivity(apptw); /* todo has different settings */
 }
@@ -518,11 +520,32 @@
     mark_appointment_changed((appt_win *)user_data);
 }
 
+static void refresh_recur_calendars(appt_win *apptw)
+{
+    xfical_appt *appt;
+
+    appt = (xfical_appt *)apptw->xf_appt;
+    if (apptw->appointment_changed) {
+        fill_appt_from_apptw(appt, apptw);
+    }
+    xfical_mark_calendar_recur(GTK_CALENDAR(apptw->Recur_calendar1), appt);
+    xfical_mark_calendar_recur(GTK_CALENDAR(apptw->Recur_calendar2), appt);
+    xfical_mark_calendar_recur(GTK_CALENDAR(apptw->Recur_calendar3), appt);
+}
+
+static void on_notebook_page_switch(GtkNotebook *notebook
+        , GtkNotebookPage *page, guint page_num, gpointer user_data)
+{
+    if (page_num == 2)
+        refresh_recur_calendars((appt_win *)user_data);
+}
+
 static void app_recur_checkbutton_clicked_cb(GtkCheckButton *checkbutton
         , gpointer user_data)
 {
     set_repeat_sensitivity((appt_win *)user_data);
     mark_appointment_changed((appt_win *)user_data);
+    refresh_recur_calendars((appt_win *)user_data);
 }
 
 static void app_recur_feature_checkbutton_clicked_cb(GtkCheckButton *cb
@@ -618,6 +641,7 @@
 {
     set_repeat_sensitivity((appt_win *)user_data);
     mark_appointment_changed((appt_win *)user_data);
+    refresh_recur_calendars((appt_win *)user_data);
 }
 
 static void on_app_combobox_changed_cb(GtkComboBox *cb, gpointer user_data)
@@ -630,6 +654,13 @@
     mark_appointment_changed((appt_win *)user_data);
 }
 
+static void on_recur_spin_button_changed_cb(GtkSpinButton *sb
+        , gpointer user_data)
+{
+    mark_appointment_changed((appt_win *)user_data);
+    refresh_recur_calendars((appt_win *)user_data);
+}
+
 static void on_appSound_button_clicked_cb(GtkButton *button, gpointer user_data)
 {
     appt_win *apptw = (appt_win *)user_data;
@@ -713,14 +744,9 @@
     gint result;
 
     if (apptw->appointment_changed == TRUE) {
-        result = xfce_message_dialog(GTK_WINDOW(apptw->Window)
-                , _("Warning")
-                , GTK_STOCK_DIALOG_WARNING
+        result = orage_warning_dialog(GTK_WINDOW(apptw->Window)
                 , _("The appointment information has been modified.")
-                , _("Do you want to continue?")
-                , GTK_STOCK_NO, GTK_RESPONSE_CANCEL
-                , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT
-                , NULL);
+                , _("Do you want to continue?"));
 
         if (result == GTK_RESPONSE_ACCEPT) {
             app_free_memory(apptw);
@@ -742,18 +768,14 @@
 {
     gint result;
 
-    /* Journal does not have end time so no need to check.
-     * Or if TODO has no end time no need to check. */
+    /* Journal does not have end time so no need to check */
     if (appt->type == XFICAL_TYPE_JOURNAL
     ||  (appt->type == XFICAL_TYPE_TODO && !appt->use_due_time))
         return(TRUE);
+
     if (xfical_compare_times(appt) > 0) {
-        result = xfce_message_dialog(GTK_WINDOW(apptw->Window)
-                , _("Error")
-                , GTK_STOCK_DIALOG_ERROR
+        result = orage_error_dialog(GTK_WINDOW(apptw->Window)
                 , _("The end of this appointment is earlier than the beginning.")
-                , NULL
-                , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT
                 , NULL);
         return(FALSE);
     }
@@ -1018,6 +1040,10 @@
     else
         appt->categories = tmp2;
 
+    /* priority */
+    appt->priority = gtk_spin_button_get_value_as_int(
+            GTK_SPIN_BUTTON(apptw->Priority_spin));
+
     /* notes */
     gtk_text_buffer_get_bounds(apptw->Note_buffer, &start, &end);
     appt->note = gtk_text_iter_get_text(&start, &end);
@@ -1070,6 +1096,10 @@
                 GTK_SPIN_BUTTON(apptw->Recur_byday_spin[i]));
     }
 
+    /* recurrence todo base */
+    appt->recur_todo_base_start = gtk_toggle_button_get_active(
+            GTK_TOGGLE_BUTTON(apptw->Recur_todo_base_start_rb));
+
     return(TRUE);
 }
 
@@ -1143,14 +1173,9 @@
 {
     gint result;
 
-    result = xfce_message_dialog(GTK_WINDOW(apptw->Window)
-            , _("Warning")
-            , GTK_STOCK_DIALOG_WARNING
+    result = orage_warning_dialog(GTK_WINDOW(apptw->Window)
             , _("This appointment will be permanently removed.")
-            , _("Do you want to continue?")
-            , GTK_STOCK_NO, GTK_RESPONSE_REJECT
-            , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT
-            , NULL);
+            , _("Do you want to continue?"));
                                  
     if (result == GTK_RESPONSE_ACCEPT) {
         if (!apptw->appointment_add) {
@@ -1237,6 +1262,16 @@
         mark_appointment_changed(apptw);
 }
 
+static void on_recur_Date_button_clicked_cb(GtkWidget *button
+        , gpointer *user_data)
+{
+    appt_win *apptw = (appt_win *)user_data;
+
+    if (orage_date_button_clicked(button, apptw->Window))
+        mark_appointment_changed(apptw);
+    refresh_recur_calendars((appt_win *)user_data);
+}
+
 static void on_appStartTimezone_clicked_cb(GtkButton *button
         , gpointer *user_data)
 {
@@ -1273,6 +1308,18 @@
         mark_appointment_changed(apptw);
 }
 
+static void recur_month_changed_cb(GtkCalendar *calendar, gpointer user_data)
+{
+    appt_win *apptw = (appt_win *)user_data;
+    xfical_appt *appt;
+
+    appt = (xfical_appt *)apptw->xf_appt;
+    /* actually we do not have to do fill_appt_from_apptw always, 
+     * but as we are not keeping track of changes, we just do it always */
+    fill_appt_from_apptw(appt, apptw);
+    xfical_mark_calendar_recur(calendar, appt);
+}
+
 static void fill_appt_window_times(appt_win *apptw, xfical_appt *appt)
 {
     char *startdate_to_display, *enddate_to_display, *completeddate_to_display;
@@ -1406,6 +1453,8 @@
             appt->start_tz_loc = g_strdup("floating");
         appt->end_tz_loc = g_strdup(appt->start_tz_loc);
         appt->duration = 30*60;
+        /* use completed by default for new TODO */
+        appt->completed = TRUE;
         /* use duration by default for new appointments */
         appt->use_duration = TRUE;
         g_sprintf(appt->completedtime,"%sT%02d%02d00"
@@ -1419,13 +1468,9 @@
         if (!xfical_file_open(TRUE))
             return(NULL);
         if ((appt = xfical_appt_get(par)) == NULL) {
-            xfce_message_dialog(GTK_WINDOW(apptw->Window)
-                , _("Info")
-                , GTK_STOCK_DIALOG_INFO
+            orage_info_dialog(GTK_WINDOW(apptw->Window)
                 , _("This appointment does not exist.")
-                , _("It was probably removed, please refresh your screen.")
-                , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT
-                , NULL);
+                , _("It was probably removed, please refresh your screen."));
         }
         xfical_file_close(TRUE);
     }
@@ -1727,7 +1772,7 @@
             , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swin)
             , catw->cur_frame_vbox);
-    catw->cur_frame = xfce_create_framebox_with_content(
+    catw->cur_frame = orage_create_framebox_with_content(
             _("Current categories"), swin);
     gtk_box_pack_start(GTK_BOX(catw->vbox), catw->cur_frame, TRUE, TRUE, 5);
 
@@ -1742,7 +1787,7 @@
 
     /***** New category *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    catw->new_frame = xfce_create_framebox_with_content(
+    catw->new_frame = orage_create_framebox_with_content(
             _("Add new category with color"), vbox);
     gtk_box_pack_start(GTK_BOX(catw->vbox), catw->new_frame, FALSE, FALSE, 5);
 
@@ -1763,7 +1808,7 @@
     /* refresh_categories always destroys frame first, so let's create
      * a dummy for it for the first time */
     vbox = gtk_vbox_new(FALSE, 0);
-    catw->cur_frame = xfce_create_framebox_with_content(("dummy"), vbox);
+    catw->cur_frame = orage_create_framebox_with_content(("dummy"), vbox);
     refresh_categories(catw);
 }
 
@@ -1799,8 +1844,62 @@
 /* categories end.                                        */
 /**********************************************************/
 
-static void fill_appt_window_alarm(xfical_appt *appt, appt_win *apptw)
+static void fill_appt_window_general(appt_win *apptw, xfical_appt *appt
+        , char *action)
 {
+    int i;
+
+    /* type */
+    if (appt->type == XFICAL_TYPE_EVENT)
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(apptw->Type_event_rb), TRUE);
+    else if (appt->type == XFICAL_TYPE_TODO)
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(apptw->Type_todo_rb), TRUE);
+    else if (appt->type == XFICAL_TYPE_JOURNAL)
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(apptw->Type_journal_rb), TRUE);
+    else
+        g_warning("fill_appt_window_general: Illegal value for type\n");
+
+    /* appointment name */
+    gtk_entry_set_text(GTK_ENTRY(apptw->Title_entry)
+            , (appt->title ? appt->title : ""));
+
+    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);
+    }
+
+    /* location */
+    gtk_entry_set_text(GTK_ENTRY(apptw->Location_entry)
+            , (appt->location ? appt->location : ""));
+
+    /* times */
+    fill_appt_window_times(apptw, appt);
+
+    /* availability */
+    if (appt->availability != -1) {
+        gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Availability_cb)
+               , appt->availability);
+    }
+
+    /* categories */
+    fill_category_data(apptw, appt);
+
+    /* priority */
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(apptw->Priority_spin)
+            , (gdouble)appt->priority);
+
+    /* note */
+    gtk_text_buffer_set_text(apptw->Note_buffer
+            , (appt->note ? (const gchar *) appt->note : ""), -1);
+}
+
+static void fill_appt_window_alarm(appt_win *apptw, xfical_appt *appt)
+{
     int day, hours, minutes;
     char *tmp;
 
@@ -1887,112 +1986,13 @@
     g_free(tmp);
 }
 
-/* Fill appointment window with data */
-static void fill_appt_window(appt_win *apptw, char *action, char *par)
+static void fill_appt_window_recurrence(appt_win *apptw, xfical_appt *appt)
 {
-    xfical_appt *appt;
-    struct tm *t, tm_date;
-    char *untildate_to_display;
+    char *untildate_to_display, *text;
+    struct tm tm_date;
     int i;
 
-    orage_message(10, "%s appointment: %s", action, par);
-    if ((appt = fill_appt_window_get_appt(apptw, action, par)) == NULL) {
-        apptw->xf_appt = NULL;
-        return;
-    }
-    apptw->xf_appt = appt;
-
-    /* first flags */
-    apptw->xf_uid = g_strdup(appt->uid);
-    apptw->par = g_strdup((const gchar *)par);
-    apptw->appointment_changed = FALSE;
-    if (strcmp(action, "NEW") == 0) {
-        apptw->appointment_add = TRUE;
-        apptw->appointment_new = TRUE;
-    }
-    else if (strcmp(action, "UPDATE") == 0) {
-        apptw->appointment_add = FALSE;
-        apptw->appointment_new = FALSE;
-    }
-    else if (strcmp(action, "COPY") == 0) {
-            /* COPY uses old uid as base and adds new, so
-             * add == TRUE && new == FALSE */
-        apptw->appointment_add = TRUE;
-        apptw->appointment_new = FALSE;
-    }
-    else {
-        g_error("fill_appt_window: unknown parameter\n");
-        return;
-    }
-    if (!appt->completed) { /* some nice default */
-        t = orage_localtime(); /* probably completed today? */
-        g_sprintf(appt->completedtime, XFICAL_APPT_TIME_FORMAT
-                , t->tm_year+1900, t->tm_mon+1 , t->tm_mday
-                , t->tm_hour, t->tm_min, 0);
-        appt->completed_tz_loc = g_strdup(appt->start_tz_loc);
-    }
-    /* we only want to enable duplication if we are working with an old
-     * existing app (=not adding new) */
-    gtk_widget_set_sensitive(apptw->Duplicate, !apptw->appointment_add);
-    gtk_widget_set_sensitive(apptw->File_menu_duplicate
-            , !apptw->appointment_add);
-
-    /* window title */
-    gtk_window_set_title(GTK_WINDOW(apptw->Window)
-            , _("New appointment - Orage"));
-
-    /********************* GENERAL tab *********************/
-    /* type */
-    if (appt->type == XFICAL_TYPE_EVENT)
-        gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(apptw->Type_event_rb), TRUE);
-    else if (appt->type == XFICAL_TYPE_TODO)
-        gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(apptw->Type_todo_rb), TRUE);
-    else if (appt->type == XFICAL_TYPE_JOURNAL)
-        gtk_toggle_button_set_active(
-            GTK_TOGGLE_BUTTON(apptw->Type_journal_rb), TRUE);
-    else
-        g_warning("fill_appt_window: Illegal value for type\n");
-
-    /* appointment name */
-    gtk_entry_set_text(GTK_ENTRY(apptw->Title_entry)
-            , (appt->title ? appt->title : ""));
-
-    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);
-    }
-
-    /* location */
-    gtk_entry_set_text(GTK_ENTRY(apptw->Location_entry)
-            , (appt->location ? appt->location : ""));
-
-    /* times */
-    fill_appt_window_times(apptw, appt);
-
-    /* availability */
-    if (appt->availability != -1) {
-        gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Availability_cb)
-                   , appt->availability);
-    }
-
-    /* categories */
-    fill_category_data(apptw, appt);
-
-    /* note */
-    gtk_text_buffer_set_text(apptw->Note_buffer
-            , (appt->note ? (const gchar *) appt->note : ""), -1);
-
-    /********************* ALARM tab *********************/
-    fill_appt_window_alarm(appt, apptw);
-
-    /********************* RECURRENCE tab *********************/
-    /* recurrence */
-    gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Recur_freq_cb)
-            , appt->freq);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(apptw->Recur_freq_cb), appt->freq);
     switch(appt->recur_limit) {
         case 0: /* no limit */
             gtk_toggle_button_set_active(
@@ -2032,17 +2032,17 @@
     for (i=0; i <= 6; i++) {
         gtk_toggle_button_set_active(
                 GTK_TOGGLE_BUTTON(apptw->Recur_byday_cb[i])
-                , appt->recur_byday[i]);
+                        , appt->recur_byday[i]);
         /* which weekday of month / year */
         gtk_spin_button_set_value(
                 GTK_SPIN_BUTTON(apptw->Recur_byday_spin[i])
-                , (gdouble)appt->recur_byday_cnt[i]);
+                        , (gdouble)appt->recur_byday_cnt[i]);
     }
 
     /* interval */
     gtk_spin_button_set_value(
             GTK_SPIN_BUTTON(apptw->Recur_int_spin)
-            , (gdouble)appt->interval);
+                    , (gdouble)appt->interval);
 
     if (appt->interval > 1
     || !appt->recur_byday[0] || !appt->recur_byday[1] || !appt->recur_byday[2] 
@@ -2056,6 +2056,78 @@
                 GTK_TOGGLE_BUTTON(apptw->Recur_feature_normal_rb), TRUE);
     }
 
+    /* todo base */
+    if (appt->recur_todo_base_start)
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(apptw->Recur_todo_base_start_rb), TRUE);
+    else
+        gtk_toggle_button_set_active(
+                GTK_TOGGLE_BUTTON(apptw->Recur_todo_base_done_rb), TRUE);
+}
+
+/* Fill appointment window with data */
+static void fill_appt_window(appt_win *apptw, char *action, char *par)
+{
+    xfical_appt *appt;
+    struct tm *t;
+
+    /********************* INIT *********************/
+    orage_message(10, "%s appointment: %s", action, par);
+    if ((appt = fill_appt_window_get_appt(apptw, action, par)) == NULL) {
+        apptw->xf_appt = NULL;
+        return;
+    }
+    apptw->xf_appt = appt;
+
+    /* first flags */
+    apptw->xf_uid = g_strdup(appt->uid);
+    apptw->par = g_strdup((const gchar *)par);
+    apptw->appointment_changed = FALSE;
+    if (strcmp(action, "NEW") == 0) {
+        apptw->appointment_add = TRUE;
+        apptw->appointment_new = TRUE;
+    }
+    else if (strcmp(action, "UPDATE") == 0) {
+        apptw->appointment_add = FALSE;
+        apptw->appointment_new = FALSE;
+    }
+    else if (strcmp(action, "COPY") == 0) {
+            /* COPY uses old uid as base and adds new, so
+             * add == TRUE && new == FALSE */
+        apptw->appointment_add = TRUE;
+        apptw->appointment_new = FALSE;
+    }
+    else {
+        g_error("fill_appt_window: unknown parameter\n");
+        return;
+    }
+    if (!appt->completed) { /* some nice default */
+        t = orage_localtime(); /* probably completed today? */
+        g_sprintf(appt->completedtime, XFICAL_APPT_TIME_FORMAT
+                , t->tm_year+1900, t->tm_mon+1 , t->tm_mday
+                , t->tm_hour, t->tm_min, 0);
+        appt->completed_tz_loc = g_strdup(appt->start_tz_loc);
+    }
+    /* we only want to enable duplication if we are working with an old
+     * existing app (=not adding new) */
+    gtk_widget_set_sensitive(apptw->Duplicate, !apptw->appointment_add);
+    gtk_widget_set_sensitive(apptw->File_menu_duplicate
+            , !apptw->appointment_add);
+
+    /* window title */
+    gtk_window_set_title(GTK_WINDOW(apptw->Window)
+            , _("New appointment - Orage"));
+
+    /********************* GENERAL tab *********************/
+    fill_appt_window_general(apptw, appt, action);
+
+    /********************* ALARM tab *********************/
+    fill_appt_window_alarm(apptw, appt);
+
+    /********************* RECURRENCE tab *********************/
+    fill_appt_window_recurrence(apptw, appt);
+
+    /********************* FINALIZE *********************/
     set_time_sensitivity(apptw);
     set_repeat_sensitivity(apptw);
     set_sound_sensitivity(apptw);
@@ -2212,7 +2284,7 @@
     xfical_appt *appt = (xfical_appt *)apptw->xf_appt;
 
     read_default_alarm(appt);
-    fill_appt_window_alarm(appt, apptw);
+    fill_appt_window_alarm(apptw, appt);
 }
 
 static void build_toolbar(appt_win *apptw)
@@ -2260,7 +2332,7 @@
     GtkWidget *label, *event, *hbox;
     char *availability_array[2] = {_("Free"), _("Busy")};
 
-    apptw->TableGeneral = orage_table_new(11, BORDER_SIZE);
+    apptw->TableGeneral = orage_table_new(12, BORDER_SIZE);
     apptw->General_notebook_page = apptw->TableGeneral;
     apptw->General_tab_label = gtk_label_new(_("General"));
 
@@ -2429,6 +2501,18 @@
             , apptw->Categories_label, apptw->Categories_hbox
             , ++row, (GTK_EXPAND | GTK_FILL), (0));
 
+    /* priority */
+    apptw->Priority_label = gtk_label_new(_("Priority"));
+    apptw->Priority_spin = gtk_spin_button_new_with_range(0, 9, 1);
+    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Priority_spin), TRUE);
+    hbox = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), apptw->Priority_spin, FALSE, FALSE, 0);
+    label = gtk_label_new(_("(0 = undefined, 1 = highest, 9 = lowest)"));
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
+    orage_table_add_row(apptw->TableGeneral
+            , apptw->Priority_label, hbox
+            , ++row, (GTK_FILL), (GTK_FILL));
+
     /* note */
     apptw->Note = gtk_label_new(_("Note"));
     apptw->Note_Scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
@@ -2451,6 +2535,13 @@
     gtk_tooltips_set_tip(apptw->Tooltips, event
             , _("<D> inserts current date in local date format.\n<T> inserts time and\n<DT> inserts date and time."), NULL);
 
+    /* Take care of the title entry to build the appointment window title */
+    g_signal_connect((gpointer)apptw->Title_entry, "changed"
+            , G_CALLBACK(on_appTitle_entry_changed_cb), apptw);
+}
+
+static void enable_general_page_signals(appt_win *apptw)
+{
     g_signal_connect((gpointer)apptw->Type_event_rb, "clicked"
             , G_CALLBACK(app_type_checkbutton_clicked_cb), apptw);
     g_signal_connect((gpointer)apptw->Type_todo_rb, "clicked"
@@ -2495,9 +2586,6 @@
             , G_CALLBACK(on_app_spin_button_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->CompletedTimezone_button, "clicked"
             , G_CALLBACK(on_appCompletedTimezone_clicked_cb), apptw);
-    /* Take care of the title entry to build the appointment window title */
-    g_signal_connect((gpointer)apptw->Title_entry, "changed"
-            , G_CALLBACK(on_appTitle_entry_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->Location_entry, "changed"
             , G_CALLBACK(on_app_entry_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->Categories_entry, "changed"
@@ -2515,13 +2603,15 @@
 static void build_alarm_page(appt_win *apptw)
 {
     gint row;
-    GtkWidget *label, *event;
+    GtkWidget *label, *event, *vbox;
     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;
+    vbox = gtk_vbox_new(FALSE, 0);
+    apptw->TableAlarm = orage_table_new(7, BORDER_SIZE);
+    gtk_box_pack_start(GTK_BOX(vbox), apptw->TableAlarm, FALSE, FALSE, 0);
+    apptw->Alarm_notebook_page = vbox;
     apptw->Alarm_tab_label = gtk_label_new(_("Alarm"));
 
     gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook)
@@ -2710,25 +2800,30 @@
             , ++row, (GTK_FILL), (GTK_FILL));
 
     /***** Default Alarm Settings *****/
-    apptw->Default_label = gtk_label_new(_("Default alarm"));
+    apptw->Default_hbox = gtk_hbox_new(FALSE, 6);
+    apptw->Default_label = gtk_label_new(NULL);
+    gtk_label_set_markup(GTK_LABEL(apptw->Default_label)
+            , _("<b>Default alarm</b>"));
+    gtk_box_pack_start(GTK_BOX(apptw->Default_hbox), apptw->Default_label
+            , FALSE, FALSE, 0);
 
-    apptw->Default_hbox = gtk_hbox_new(FALSE, 6);
-    apptw->Default_savebutton =gtk_button_new_from_stock("gtk-save");
+    apptw->Default_savebutton = gtk_button_new_from_stock("gtk-save");
     gtk_box_pack_start(GTK_BOX(apptw->Default_hbox), apptw->Default_savebutton
-            , FALSE, FALSE, 0);
+            , TRUE, TRUE, 0);
     gtk_tooltips_set_tip(apptw->Tooltips, apptw->Default_savebutton
             , _("Store current settings as default alarm"), NULL);
     apptw->Default_readbutton =gtk_button_new_from_stock("gtk-revert-to-saved");
     gtk_box_pack_start(GTK_BOX(apptw->Default_hbox), apptw->Default_readbutton
-            , FALSE, TRUE, 0);
+            , TRUE, TRUE, 0);
     gtk_tooltips_set_tip(apptw->Tooltips, apptw->Default_readbutton
             , _("Set current settings from default alarm"), NULL);
 
-    orage_table_add_row(apptw->TableAlarm
-            , apptw->Default_label, apptw->Default_hbox
-            , ++row, (GTK_FILL), (GTK_FILL));
-    gtk_table_set_row_spacing(GTK_TABLE(apptw->TableAlarm), row-1, 50);
+    gtk_box_pack_end(GTK_BOX(vbox), apptw->Default_hbox, FALSE, FALSE, 0);
+    gtk_box_pack_end(GTK_BOX(vbox), gtk_hseparator_new(), FALSE, FALSE, 3);
+}
 
+static void enable_alarm_page_signals(appt_win *apptw)
+{
     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"
@@ -2777,56 +2872,59 @@
 
 static void build_recurrence_page(appt_win *apptw)
 {
-    gint row, i;
+    gint row, i, y, m, d;
     char *recur_freq_array[5] = {
         _("None"), _("Daily"), _("Weekly"), _("Monthly"), _("Yearly")};
     char *weekday_array[7] = {
         _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun")};
+    GtkWidget *hbox;
 
-    apptw->TableRecur = orage_table_new(8, BORDER_SIZE);
+    apptw->TableRecur = orage_table_new(9, BORDER_SIZE);
     apptw->Recur_notebook_page = apptw->TableRecur;
     apptw->Recur_tab_label = gtk_label_new(_("Recurrence"));
 
     gtk_notebook_append_page(GTK_NOTEBOOK(apptw->Notebook)
             , apptw->Recur_notebook_page, apptw->Recur_tab_label);
 
+    /* complexity */
     apptw->Recur_feature_label = gtk_label_new(_("Complexity"));
     apptw->Recur_feature_hbox = gtk_hbox_new(FALSE, 0);
     apptw->Recur_feature_normal_rb = gtk_radio_button_new_with_label(NULL
             , _("Basic"));
     gtk_box_pack_start(GTK_BOX(apptw->Recur_feature_hbox)
-            , apptw->Recur_feature_normal_rb, FALSE, FALSE, 15);
+            , apptw->Recur_feature_normal_rb, FALSE, FALSE, 0);
     apptw->Recur_feature_advanced_rb = 
             gtk_radio_button_new_with_mnemonic_from_widget(
                     GTK_RADIO_BUTTON(apptw->Recur_feature_normal_rb)
                     , _("Advanced"));
     gtk_box_pack_start(GTK_BOX(apptw->Recur_feature_hbox)
-            , apptw->Recur_feature_advanced_rb, FALSE, FALSE, 15);
-    orage_table_add_row(apptw->TableRecur
-            , apptw->Recur_feature_label, apptw->Recur_feature_hbox
-            , row = 0, (GTK_EXPAND | GTK_FILL), (0));
+            , apptw->Recur_feature_advanced_rb, FALSE, FALSE, 20);
     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 Saturday and Sunday or \n First Tuesday every month")
             , NULL);
+    orage_table_add_row(apptw->TableRecur
+            , apptw->Recur_feature_label, apptw->Recur_feature_hbox
+            , row = 0, (GTK_EXPAND | GTK_FILL), (0));
 
+    /* frequency */
     apptw->Recur_freq_label = gtk_label_new(_("Frequency"));
     apptw->Recur_freq_hbox = gtk_hbox_new(FALSE, 0);
     apptw->Recur_freq_cb = orage_create_combo_box_with_content(
             recur_freq_array, 5);
     gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox)
-            , apptw->Recur_freq_cb, FALSE, FALSE, 15);
+            , apptw->Recur_freq_cb, FALSE, FALSE, 0);
     apptw->Recur_int_spin_label1 = gtk_label_new(_("Each"));
     gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox)
-            , apptw->Recur_int_spin_label1, FALSE, FALSE, 0);
+            , apptw->Recur_int_spin_label1, FALSE, FALSE, 5);
     apptw->Recur_int_spin = gtk_spin_button_new_with_range(1, 100, 1);
     gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Recur_int_spin), TRUE);
     gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox)
-            , apptw->Recur_int_spin, FALSE, FALSE, 5);
+            , apptw->Recur_int_spin, FALSE, FALSE, 0);
     apptw->Recur_int_spin_label2 = gtk_label_new(_("occurrence"));
     gtk_box_pack_start(GTK_BOX(apptw->Recur_freq_hbox)
-            , apptw->Recur_int_spin_label2, FALSE, FALSE, 0);
+            , apptw->Recur_int_spin_label2, FALSE, FALSE, 5);
     gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_int_spin
             , _("Limit frequency to certain interval.\n For example: Every third day:\n Frequency = Daily and Interval = 3")
             , NULL);
@@ -2834,6 +2932,7 @@
             , apptw->Recur_freq_label, apptw->Recur_freq_hbox
             , ++row, (GTK_EXPAND | GTK_FILL), (GTK_FILL));
 
+    /*
     apptw->Recur_limit_label = gtk_label_new(_("Limit"));
     apptw->Recur_limit_rb = gtk_radio_button_new_with_label(NULL
             , _("Repeat forever"));
@@ -2869,7 +2968,47 @@
     orage_table_add_row(apptw->TableRecur
             , NULL, apptw->Recur_until_hbox
             , ++row, (GTK_EXPAND | GTK_FILL), (0));
+            */
 
+    /* limitation */
+    hbox = gtk_hbox_new(FALSE, 0);
+    apptw->Recur_limit_label = gtk_label_new(_("Limit"));
+    apptw->Recur_limit_rb = gtk_radio_button_new_with_label(NULL
+            , _("Repeat forever"));
+    gtk_box_pack_start(GTK_BOX(hbox)
+            , apptw->Recur_limit_rb, FALSE, FALSE, 0);
+
+    apptw->Recur_count_hbox = gtk_hbox_new(FALSE, 0);
+    apptw->Recur_count_rb = gtk_radio_button_new_with_mnemonic_from_widget(
+            GTK_RADIO_BUTTON(apptw->Recur_limit_rb), _("Repeat "));
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox)
+            , apptw->Recur_count_rb, FALSE, FALSE, 0);
+    apptw->Recur_count_spin = gtk_spin_button_new_with_range(1, 100, 1);
+    gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(apptw->Recur_count_spin)
+            , TRUE);
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox)
+            , apptw->Recur_count_spin, FALSE, FALSE, 0);
+    apptw->Recur_count_label = gtk_label_new(_("times"));
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_count_hbox)
+            , apptw->Recur_count_label, FALSE, FALSE, 5);
+    gtk_box_pack_start(GTK_BOX(hbox)
+            , apptw->Recur_count_hbox, FALSE, FALSE, 20);
+
+    apptw->Recur_until_hbox = gtk_hbox_new(FALSE, 0);
+    apptw->Recur_until_rb = gtk_radio_button_new_with_mnemonic_from_widget(
+            GTK_RADIO_BUTTON(apptw->Recur_limit_rb), _("Repeat until "));
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_until_hbox)
+            , apptw->Recur_until_rb, FALSE, FALSE, 0);
+    apptw->Recur_until_button = gtk_button_new();
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_until_hbox)
+            , apptw->Recur_until_button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox)
+            , apptw->Recur_until_hbox, FALSE, FALSE, 0);
+    orage_table_add_row(apptw->TableRecur
+            , apptw->Recur_limit_label, hbox
+            , ++row, (GTK_EXPAND | GTK_FILL), (0));
+
+    /* weekdays (only for complex settings) */
     apptw->Recur_byday_label = gtk_label_new(_("Weekdays"));
     apptw->Recur_byday_hbox = gtk_hbox_new(TRUE, 0);
     for (i=0; i <= 6; i++) {
@@ -2897,6 +3036,69 @@
             , apptw->Recur_byday_spin_label, apptw->Recur_byday_spin_hbox
             , ++row ,(GTK_EXPAND | GTK_FILL), (0));
 
+    /* TODO base (only for TODOs) */
+    apptw->Recur_todo_base_label = gtk_label_new(_("TODO base"));
+    apptw->Recur_todo_base_hbox = gtk_hbox_new(FALSE, 0);
+    apptw->Recur_todo_base_start_rb = gtk_radio_button_new_with_label(NULL
+            , _("Start"));
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_todo_base_hbox)
+            , apptw->Recur_todo_base_start_rb, FALSE, FALSE, 15);
+    apptw->Recur_todo_base_done_rb = 
+            gtk_radio_button_new_with_mnemonic_from_widget(
+                    GTK_RADIO_BUTTON(apptw->Recur_todo_base_start_rb)
+                    , _("Done"));
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_todo_base_hbox)
+            , apptw->Recur_todo_base_done_rb, FALSE, FALSE, 15);
+    gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_todo_base_start_rb
+            , _("TODO reoccurs regularly starting on start time and repeating after each interval no matter when it was last completed"), NULL);
+    gtk_tooltips_set_tip(apptw->Tooltips, apptw->Recur_todo_base_done_rb
+            , _("TODO reoccurrency is based on complete time and repeats after the interval counted from the last completed time.\n(Note that you can not tell anything about the history of the TODO since reoccurrence base changes after each completion.)")
+            , NULL);
+    orage_table_add_row(apptw->TableRecur
+            , apptw->Recur_todo_base_label, apptw->Recur_todo_base_hbox
+            , ++row ,(GTK_EXPAND | GTK_FILL), (0));
+
+    apptw->Recur_calendar_label = gtk_label_new(_("Action dates"));
+    apptw->Recur_calendar_hbox = gtk_hbox_new(FALSE, 0);
+    apptw->Recur_calendar1 = gtk_calendar_new();
+    gtk_calendar_set_display_options(GTK_CALENDAR(apptw->Recur_calendar1)
+            , GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
+    gtk_calendar_get_date(GTK_CALENDAR(apptw->Recur_calendar1), &y, &m, &d);
+    gtk_calendar_select_day(GTK_CALENDAR(apptw->Recur_calendar1), 0);
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_calendar_hbox)
+            , apptw->Recur_calendar1, FALSE, FALSE, 0);
+    apptw->Recur_calendar2 = gtk_calendar_new();
+    gtk_calendar_set_display_options(GTK_CALENDAR(apptw->Recur_calendar2)
+            , GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
+    if (++m>11) {
+        m=0;
+        y++;
+    }
+    gtk_calendar_select_month(GTK_CALENDAR(apptw->Recur_calendar2), m, y);
+    gtk_calendar_select_day(GTK_CALENDAR(apptw->Recur_calendar2), 0);
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_calendar_hbox)
+            , apptw->Recur_calendar2, FALSE, FALSE, 0);
+    apptw->Recur_calendar3 = gtk_calendar_new();
+    gtk_calendar_set_display_options(GTK_CALENDAR(apptw->Recur_calendar3)
+            , GTK_CALENDAR_SHOW_HEADING | GTK_CALENDAR_SHOW_DAY_NAMES);
+    if (++m>11) {
+        m=0;
+        y++;
+    }
+    gtk_calendar_select_month(GTK_CALENDAR(apptw->Recur_calendar3), m, y);
+    gtk_calendar_select_day(GTK_CALENDAR(apptw->Recur_calendar3), 0);
+    gtk_box_pack_start(GTK_BOX(apptw->Recur_calendar_hbox)
+            , apptw->Recur_calendar3, FALSE, FALSE, 0);
+    orage_table_add_row(apptw->TableRecur
+            , apptw->Recur_calendar_label, apptw->Recur_calendar_hbox
+            , ++row ,(GTK_EXPAND | GTK_FILL), (0));
+
+}
+
+static void enable_recurrence_page_signals(appt_win *apptw)
+{
+    gint i;
+
     g_signal_connect((gpointer)apptw->Recur_feature_normal_rb, "clicked"
             , G_CALLBACK(app_recur_feature_checkbutton_clicked_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_feature_advanced_rb, "clicked"
@@ -2904,23 +3106,33 @@
     g_signal_connect((gpointer)apptw->Recur_freq_cb, "changed"
             , G_CALLBACK(on_freq_combobox_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_int_spin, "value-changed"
-            , G_CALLBACK(on_app_spin_button_changed_cb), apptw);
+            , G_CALLBACK(on_recur_spin_button_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_limit_rb, "clicked"
             , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_count_rb, "clicked"
             , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_count_spin, "value-changed"
-            , G_CALLBACK(on_app_spin_button_changed_cb), apptw);
+            , G_CALLBACK(on_recur_spin_button_changed_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_until_rb, "clicked"
             , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
     g_signal_connect((gpointer)apptw->Recur_until_button, "clicked"
-            , G_CALLBACK(on_Date_button_clicked_cb), apptw);
+            , G_CALLBACK(on_recur_Date_button_clicked_cb), apptw);
     for (i=0; i <= 6; i++) {
         g_signal_connect((gpointer)apptw->Recur_byday_cb[i], "clicked"
-                , G_CALLBACK(app_checkbutton_clicked_cb), apptw);
+                , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
         g_signal_connect((gpointer)apptw->Recur_byday_spin[i], "value-changed"
-                , G_CALLBACK(on_app_spin_button_changed_cb), apptw);
+                , G_CALLBACK(on_recur_spin_button_changed_cb), apptw);
     }
+    g_signal_connect((gpointer)apptw->Recur_todo_base_start_rb, "clicked"
+            , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
+    g_signal_connect((gpointer)apptw->Recur_todo_base_done_rb, "clicked"
+            , G_CALLBACK(app_recur_checkbutton_clicked_cb), apptw);
+    g_signal_connect((gpointer)apptw->Recur_calendar1, "month-changed"
+            , G_CALLBACK(recur_month_changed_cb), apptw);
+    g_signal_connect((gpointer)apptw->Recur_calendar2, "month-changed"
+            , G_CALLBACK(recur_month_changed_cb), apptw);
+    g_signal_connect((gpointer)apptw->Recur_calendar3, "month-changed"
+            , G_CALLBACK(recur_month_changed_cb), apptw);
 }
 
 appt_win *create_appt_win(char *action, char *par)
@@ -2965,14 +3177,18 @@
 
     fill_appt_window(apptw, action, par);
     if (apptw->xf_appt) { /* all fine */
+        enable_general_page_signals(apptw);
+        enable_alarm_page_signals(apptw);
+        enable_recurrence_page_signals(apptw);
         gtk_widget_show_all(apptw->Window);
         recur_hide_show(apptw);
         type_hide_show(apptw);
+        g_signal_connect((gpointer)apptw->Notebook, "switch-page"
+                , G_CALLBACK(on_notebook_page_switch), apptw);
         gtk_widget_grab_focus(apptw->Title_entry);
         window = GTK_WIDGET(apptw->Window)->window;
         gdk_x11_window_set_user_time(window, gdk_x11_get_server_time(window));
         gtk_window_present(GTK_WINDOW(apptw->Window));
-
     }
     else { /* failed to get data */
         app_free_memory(apptw);

Modified: xfcalendar/trunk/src/appointment.h
===================================================================
--- xfcalendar/trunk/src/appointment.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/appointment.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -100,6 +100,8 @@
     GtkWidget *Categories_cb;
     GtkWidget *Categories_cb_event;
     GtkWidget *Categories_button;
+    GtkWidget *Priority_label;
+    GtkWidget *Priority_spin;
     GtkWidget *Note;
     GtkWidget *Note_Scrolledwindow;
     GtkWidget *Note_textview;
@@ -178,6 +180,15 @@
     GtkWidget *Recur_byday_spin_label;
     GtkWidget *Recur_byday_spin_hbox;
     GtkWidget *Recur_byday_spin[7];  /* 0=Mo, 1=Tu ... 6=Su */
+    GtkWidget *Recur_todo_base_label;
+    GtkWidget *Recur_todo_base_hbox;
+    GtkWidget *Recur_todo_base_start_rb;
+    GtkWidget *Recur_todo_base_done_rb;
+    GtkWidget *Recur_calendar_label;
+    GtkWidget *Recur_calendar_hbox;
+    GtkWidget *Recur_calendar1;
+    GtkWidget *Recur_calendar2;
+    GtkWidget *Recur_calendar3;
 
     void *xf_appt; /* this is xfical_appt * */
     gchar *xf_uid;

Modified: xfcalendar/trunk/src/day-view.c
===================================================================
--- xfcalendar/trunk/src/day-view.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/day-view.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -422,7 +422,7 @@
     changeSelectedDate((day_win *)user_data, 1);
 }
 
-static void add_row(day_win *dw, xfical_appt *appt, char *a_day, gint days)
+static void add_row(day_win *dw, xfical_appt *appt)
 {
     gint row, start_row, end_row;
     gint col, start_col, end_col, first_col, last_col;
@@ -435,7 +435,7 @@
     /* First clarify timings */
     tm_start = orage_icaltime_to_tm_time(appt->starttimecur, FALSE);
     tm_end   = orage_icaltime_to_tm_time(appt->endtimecur, FALSE);
-    tm_first = orage_icaltime_to_tm_time(a_day, FALSE);
+    tm_first = orage_icaltime_to_tm_time(dw->a_day, FALSE);
     start_col = orage_days_between(&tm_first, &tm_start)+1;
     end_col   = orage_days_between(&tm_first, &tm_end)+1;
 
@@ -530,8 +530,8 @@
             first_col = 1;
         else
             first_col = start_col;
-        if (end_col > days)
-            last_col = days;
+        if (end_col > dw->days)
+            last_col = dw->days;
         else
             last_col = end_col;
         for (col = first_col; col <= last_col; col++) {
@@ -559,43 +559,43 @@
     }
 }
 
-static void app_rows(day_win *dw, char *a_day , xfical_type ical_type
-        , gchar *file_type)
+static void app_rows(day_win *dw, xfical_type ical_type, gchar *file_type)
 {
     xfical_appt *appt;
-    int days = 1;
     GList *date_list, *tmp; /* recurring event times */
     struct time_data {
         char starttimecur[17];
         char endtimecur[17];
     } *time_datap;
 
-    days = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dw->day_spin));
     /* xfical_appt_get_next_on_day uses extra days so to show 7 days we need
      * to pass days=6, which means 6 days in addition to the one */
-    for (appt = xfical_appt_get_next_on_day(a_day, TRUE, days-1
+    for (appt = xfical_appt_get_next_on_day(dw->a_day, TRUE, dw->days-1
                 , ical_type , file_type);
          appt;
-         appt = xfical_appt_get_next_on_day(a_day, FALSE, days-1
+         appt = xfical_appt_get_next_on_day(dw->a_day, FALSE, dw->days-1
                 , ical_type , file_type)) {
-        if (appt->freq) { /* complex, need to process all events */
-            date_list = NULL;
-            xfical_process_each_app(appt, a_day, days, &date_list);
-            for (tmp = g_list_first(date_list);
-                 tmp != NULL;
-                 tmp = g_list_next(tmp)) {
-                time_datap = (struct time_data *)tmp->data;
-                /* Only use date since time is the same always */
-                strncpy(appt->starttimecur, time_datap->starttimecur, 8);
-                strncpy(appt->endtimecur, time_datap->endtimecur, 8);
-                add_row(dw, appt, a_day, days);
-                g_free(time_datap);
+        if (appt->priority < g_par.priority_list_limit) {
+            /* we only show high enough priority and 0 (=undefned) */
+            if (appt->freq) { /* complex, need to process all events */
+                date_list = NULL;
+                xfical_process_each_app(appt, dw->a_day, dw->days, &date_list);
+                for (tmp = g_list_first(date_list);
+                     tmp != NULL;
+                     tmp = g_list_next(tmp)) {
+                    time_datap = (struct time_data *)tmp->data;
+                    /* Only use date since time is the same always */
+                    strncpy(appt->starttimecur, time_datap->starttimecur, 8);
+                    strncpy(appt->endtimecur, time_datap->endtimecur, 8);
+                    add_row(dw, appt);
+                    g_free(time_datap);
+                }
+                g_list_free(date_list);
             }
-            g_list_free(date_list);
+            else { /* simple case, only one event */
+                add_row(dw, appt);
+            }
         }
-        else { /* simple case, only one event */
-            add_row(dw, appt, a_day, days);
-        }
         xfical_appt_free(appt);
     }
 }
@@ -605,21 +605,21 @@
     xfical_type ical_type;
     gchar file_type[8];
     gint i;
-    gchar a_day[9]; /* yyyymmdd */
 
     ical_type = XFICAL_TYPE_EVENT;
-    strcpy(a_day, orage_i18_date_to_icaltime(gtk_button_get_label(
+    strcpy(dw->a_day, orage_i18_date_to_icaltime(gtk_button_get_label(
             GTK_BUTTON(dw->StartDate_button))));
+    dw->days = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dw->day_spin));
 
     /* first search base orage file */
     if (!xfical_file_open(TRUE))
         return;
     strcpy(file_type, "O00.");
-    app_rows(dw, a_day, ical_type, file_type);
+    app_rows(dw, ical_type, file_type);
     /* then process all foreign files */
     for (i = 0; i < g_par.foreign_count; i++) {
         g_sprintf(file_type, "F%02d.", i);
-        app_rows(dw, a_day, ical_type, file_type);
+        app_rows(dw, ical_type, file_type);
     }
     xfical_file_close(TRUE);
 }

Modified: xfcalendar/trunk/src/day-view.h
===================================================================
--- xfcalendar/trunk/src/day-view.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/day-view.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -73,6 +73,8 @@
 
     GdkColor bg1, bg2, line_color, bg_today, fg_sunday;
     GList    *apptw_list; /* keep track of appointments being updated */
+    gchar a_day[9]; /* start date yyyymmdd */
+    gint days;      /* how many days to show */
 } day_win;
 
 day_win *create_day_win(char *start_date);

Modified: xfcalendar/trunk/src/event-list.c
===================================================================
--- xfcalendar/trunk/src/event-list.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/event-list.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -46,12 +46,12 @@
 #include <unistd.h>
 #include <time.h>
 
-#include <libxfcegui4/libxfcegui4.h>
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #include <glib/gprintf.h>
 
+#include "orage-i18n.h"
 #include "functions.h"
 #include "mainbox.h"
 #include "reminder.h"
@@ -265,6 +265,9 @@
         }
 
         gtk_tree_model_get(model, iter, COL_TIME, &stime, -1);
+        /* we need to remember the real address in case we increment it, 
+         * so that we can free the correct pointer */
+        stime2 = stime; 
         if (stime[0] == '+')
             stime++;
         etime = stime + 8; /* hh:mm - hh:mm */
@@ -303,7 +306,7 @@
                      , "weight-set",        TRUE
                      , NULL);
         }
-        g_free(stime);
+        g_free(stime2);
     }
     else if (el->page == TODO_PAGE) {
         gtk_tree_model_get(model, iter, COL_SORT, &stime, -1);
@@ -721,14 +724,10 @@
         start_appt_win("COPY", el, model, &iter, path);
     }
     else {
-        g_warning("Copy: No row selected\n");
-        xfce_message_dialog(GTK_WINDOW(el->Window)
-                , _("Info")
-                , GTK_STOCK_DIALOG_INFO
+        orage_info_dialog(GTK_WINDOW(el->Window)
                 , _("No rows have been selected.")
                 , _("Click a row to select it and after that you can copy it.")
-                , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT
-                , NULL);
+                );
     }
     g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
     g_list_free(list);
@@ -893,15 +892,9 @@
     gint  list_len, i;
     gchar *uid = NULL;
 
-    result = xfce_message_dialog(GTK_WINDOW(el->Window)
-            , _("Warning")
-            , GTK_STOCK_DIALOG_WARNING
+    result = orage_warning_dialog(GTK_WINDOW(el->Window)
             , _("You will permanently remove all\nselected appointments.")
-            , _("Do you want to continue?")
-            , GTK_STOCK_NO, GTK_RESPONSE_CANCEL
-            , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT
-            , NULL);
-
+            , _("Do you want to continue?"));
     if (result == GTK_RESPONSE_ACCEPT) {
         if (!xfical_file_open(TRUE))
             return;

Modified: xfcalendar/trunk/src/functions.c
===================================================================
--- xfcalendar/trunk/src/functions.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/functions.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -37,6 +37,7 @@
 #include <gdk/gdk.h>
 
 #include <libxfce4util/libxfce4util.h>
+#include <libxfcegui4/libxfcegui4.h>
 
 #include "orage-i18n.h"
 #include "functions.h"
@@ -51,9 +52,8 @@
  * strace -ttt -f -o /tmp/logfile.strace ./orage
  * And then you can check results:
  * grep MARK /tmp/logfile.strace
- * grep MARK /tmp/logfile.strace|sed s/", F_OK) = -1 ENOENT (No such file or directory)"//
+ * grep MARK /tmp/logfile.strace|sed s/", F_OK) = -1 ENOENT (No such file or directory)"/\)/
  * */
-/*
 void program_log (const char *format, ...)
 {
         va_list args;
@@ -69,7 +69,6 @@
         access (str, F_OK);
         g_free (str);
 }
-*/
 
 /* Print message at various level:
  * < 0     = Debug (Use only in special debug code which should not be in 
@@ -404,7 +403,8 @@
         t.tm_sec = -1;
     }
     else if (ret[0] != 0) { /* icaltime was not processed completely */
-        if (ret[0] != 'Z' || ret[1] != 0) /* UTC times end to Z, which is ok */
+        /* UTC times end to Z, which is ok */
+        if (ret[0] != 'Z' || ret[1] != 0) /* real error */
             g_error("orage: orage_icaltime_to_tm_time error %s %s", icaltime
                     , ret);
     }
@@ -648,3 +648,50 @@
 {
     xfce_rc_delete_entry((XfceRc *)orc->rc, key, FALSE);
 }
+
+/*******************************************************
+ * xfce functions
+ *******************************************************/
+
+gint orage_info_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text)
+{
+    return(xfce_message_dialog(parent
+        , _("Info")
+        , GTK_STOCK_DIALOG_INFO
+        , primary_text
+        , secondary_text
+        , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT
+        , NULL));
+}
+
+gint orage_warning_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text)
+{
+    return(xfce_message_dialog(parent
+        , _("Warning")
+        , GTK_STOCK_DIALOG_WARNING
+        , primary_text
+        , secondary_text
+        , GTK_STOCK_NO, GTK_RESPONSE_CANCEL
+        , GTK_STOCK_YES, GTK_RESPONSE_ACCEPT
+        , NULL));
+}
+
+gint orage_error_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text)
+{
+    return(xfce_message_dialog(parent
+        , _("Error")
+        , GTK_STOCK_DIALOG_ERROR
+        , primary_text
+        , secondary_text
+        , GTK_STOCK_OK, GTK_RESPONSE_ACCEPT
+        , NULL));
+}
+
+GtkWidget *orage_create_framebox_with_content(const gchar *title
+        , GtkWidget *content)
+{
+    return(xfce_create_framebox_with_content (title, content));
+}

Modified: xfcalendar/trunk/src/functions.h
===================================================================
--- xfcalendar/trunk/src/functions.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/functions.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -40,6 +40,11 @@
 
 #define ORAGE_STR_EXISTS(str) ((str != NULL) && (str[0] != 0))
 
+#if !GLIB_CHECK_VERSION(2,14,0)
+#define g_timeout_add_seconds(interval,func,data) \
+        g_timeout_add((interval)*1000, func, data)
+#endif
+
 typedef struct _OrageRc
 {
     void *rc;
@@ -102,4 +107,13 @@
 gboolean orage_rc_exists_item(OrageRc *orc, char *key);
 void orage_rc_del_item(OrageRc *orc, char *key);
 
+gint orage_info_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text);
+gint orage_warning_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text);
+gint orage_error_dialog(GtkWindow *parent
+        , char *primary_text, char *secondary_text);
+GtkWidget *orage_create_framebox_with_content(const gchar *title
+        , GtkWidget *content);
+
 #endif /* !__ORAGE_FUNCTIONS_H__ */

Modified: xfcalendar/trunk/src/ical-code.c
===================================================================
--- xfcalendar/trunk/src/ical-code.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/ical-code.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -808,7 +808,7 @@
 #ifdef ORAGE_DEBUG
             orage_message(-10, P_N "closing file after 10 minutes");
 #endif
-            file_close_timer = g_timeout_add(10*60*1000
+            file_close_timer = g_timeout_add_seconds(10*60
                     , (GtkFunction)delayed_file_close, NULL);
         }
     }
@@ -1262,6 +1262,7 @@
     appt->interval = 1;
     for (i=0; i <= 6; i++)
         appt->recur_byday[i] = TRUE;
+    appt->recur_todo_base_start = TRUE;
     return(appt);
 }
 
@@ -1631,6 +1632,16 @@
     }
     rrule = icalrecurrencetype_from_string(recur_str);
     icalcomponent_add_property(icmp, icalproperty_new_rrule(rrule));
+    if (appt->type == XFICAL_TYPE_TODO) {
+        if (appt->recur_todo_base_start)
+            icalcomponent_add_property(icmp
+                    , icalproperty_new_from_string(
+                            "X-ORAGE-TODO-BASE:START"));
+        else
+            icalcomponent_add_property(icmp
+                    , icalproperty_new_from_string(
+                            "X-ORAGE-TODO-BASE:COMPLETED"));
+    }
 }
 
 static void appt_add_starttime_internal(xfical_appt *appt, icalcomponent *icmp)
@@ -2371,6 +2382,7 @@
                 appt.recur_byday_cnt[i] = 0;
             }
             appt.interval = 1;
+            appt.recur_todo_base_start = TRUE;
         /*********** Properties ***********/
             for (p = icalcomponent_get_first_property(c, ICAL_ANY_PROPERTY);
                  p != 0;
@@ -2439,7 +2451,17 @@
                             etime_found = TRUE;
                             break;
                         }
+                        if (g_str_has_prefix(text, "X-ORAGE-TODO-BASE")) {
+                            text = icalproperty_get_value_as_string(p);
+                            if (strcmp(text, "START") == 0)
+                                appt.recur_todo_base_start = TRUE;
+                            else
+                                appt.recur_todo_base_start = FALSE;
+
+                            break;
+                        }
                         orage_message(160, P_N "unknown X property %s", (char *)text);
+                        break; /* ICAL_X_PROPERTY: */
                     case ICAL_PRIORITY_PROPERTY:
                         appt.priority = icalproperty_get_priority(p);
                         break;
@@ -2574,7 +2596,7 @@
 {
 #undef P_N
 #define P_N "xfical_appt_get: "
-    xfical_appt *appt;
+    xfical_appt *appt = NULL;
     char *ical_uid;
     char file_type[8];
     gint i;
@@ -2586,25 +2608,23 @@
     file_type[4] = '\0';
     ical_uid = uid+4; /* skip file id */
     if (uid[0] == 'O') {
-        return(appt_get_any(ical_uid, ical, file_type));
+        appt = appt_get_any(ical_uid, ical, file_type);
     }
 #ifdef HAVE_ARCHIVE
     else if (uid[0] == 'A') {
-        return(appt_get_any(ical_uid, aical, file_type));
+        appt = appt_get_any(ical_uid, aical, file_type);
     }
 #endif
     else if (uid[0] == 'F') {
         sscanf(uid, "F%02d", &i);
         if (i < g_par.foreign_count && f_ical[i].ical != NULL)
-            return(appt_get_any(ical_uid, f_ical[i].ical, file_type));
+            appt = appt_get_any(ical_uid, f_ical[i].ical, file_type);
         else {
             orage_message(250, P_N "unknown foreign file number %s", uid);
-            return(NULL);
         }
     }
     else {
         orage_message(250, P_N "unknown file type %s", uid);
-        return(NULL);
     }
     return(appt);
 }
@@ -2777,6 +2797,67 @@
                 , ((alarm_struct *)b)->alarm_time));
 }
 
+static void set_todo_times(icalcomponent *c, xfical_period *per)
+{
+    char *text;
+    icalproperty *p = NULL;
+
+    if (per->ikind == ICAL_VTODO_COMPONENT 
+    && !icaltime_is_null_time(per->ctime)) {
+        /* we need to check if repeat is based on 
+         * start date or complete date */
+        for (p = icalcomponent_get_first_property(c, ICAL_X_PROPERTY);
+             p != 0;
+             p = icalcomponent_get_next_property(c, ICAL_X_PROPERTY)) {
+            text = (char *)icalproperty_get_x_name(p);
+            if (!strcmp(text, "X-ORAGE-TODO-BASE")) {
+                text = (char *)icalproperty_get_value_as_string(p);
+                if (!strcmp(text, "COMPLETED")) {/* use completed time */
+                     per->stime = per->ctime;
+                     per->etime = icaltime_add(per->stime, per->duration);
+                }
+                break; /* for loop done */
+            }
+        }
+    }
+}
+
+struct icaltimetype count_alarm_time(xfical_period per
+        , struct icaltimetype cur_time
+        , struct icaldurationtype dur
+        , icalparameter_related rel) 
+{
+    struct icaltimetype alarm_time;
+
+    if (icaltime_is_date(per.stime)) { 
+/* HACK: convert to local time so that we can use time arithmetic
+ * when counting alarm time. */
+        if (rel == ICAL_RELATED_START) {
+            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;
+        }
+        else {
+            per.etime.is_date       = 0;
+            per.etime.is_utc        = cur_time.is_utc;
+            per.etime.is_daylight   = cur_time.is_daylight;
+            per.etime.zone          = cur_time.zone;
+            per.etime.hour          = 0;
+            per.etime.minute        = 0;
+            per.etime.second        = 0;
+        }
+    }
+    if (rel == ICAL_RELATED_END)
+        alarm_time = icaltime_add(per.etime, dur);
+    else /* default is ICAL_RELATED_START */
+        alarm_time = icaltime_add(per.stime, dur);
+    return(alarm_time);
+}
+
 /* 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 
@@ -2794,9 +2875,10 @@
     struct icalrecurrencetype rrule;
     icalrecur_iterator* ri;
     xfical_period per;
-    struct icaltimetype alarm_time, next_time;
+    struct icaltimetype next_alarm_time, next_start_time;
     gboolean trg_active = FALSE;
     alarm_struct *new_alarm;
+    struct icaldurationtype alarm_start_diff;
 
 #ifdef ORAGE_DEBUG
     orage_message(-200, P_N);
@@ -2814,58 +2896,61 @@
     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. */
-        if (rel == ICAL_RELATED_START) {
-            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;
+    next_alarm_time = count_alarm_time(per, cur_time, trg.duration, rel);
+    /* we only have ctime for TODOs and only if todo has been completed.
+     * So if we have ctime, we need to compare against it instead of 
+     * current date */
+    if (per.ikind == ICAL_VTODO_COMPONENT) {
+        if (icaltime_is_null_time(per.ctime)
+        || local_compare(per.ctime, per.stime) < 0) {
+        /* VTODO is never completed  */
+        /* or it has completed before start, so
+         * this one is not done and needs to be counted */
+            if (icaltime_compare(cur_time, next_alarm_time) <= 0) { /* active */
+                trg_active = TRUE;
+            }
         }
-        else {
-            per.etime.is_date       = 0;
-            per.etime.is_utc        = cur_time.is_utc;
-            per.etime.is_daylight   = cur_time.is_daylight;
-            per.etime.zone          = cur_time.zone;
-            per.etime.hour          = 0;
-            per.etime.minute        = 0;
-            per.etime.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 */
+    else if (icaltime_compare(cur_time, next_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)) {
+    if (!trg_active 
+    && (p = icalcomponent_get_first_property(c , ICAL_RRULE_PROPERTY)) != 0) { 
+        /* check recurring EVENTs */
+        rrule = icalproperty_get_rrule(p);
+        set_todo_times(c, &per); /* may change per.stime to be per.ctime */
+        next_alarm_time = count_alarm_time(per, cur_time, trg.duration, rel);
+        alarm_start_diff = icaltime_subtract(per.stime, next_alarm_time);
+        ri = icalrecur_iterator_new(rrule, next_alarm_time);
+        for (next_alarm_time = icalrecur_iterator_next(ri),
+             next_start_time = icaltime_add(next_alarm_time, alarm_start_diff);
+            (!icaltime_is_null_time(next_alarm_time)
+             && ((per.ikind == ICAL_VTODO_COMPONENT
+                  && local_compare(next_start_time, per.ctime) <= 0)
+                 || (per.ikind != ICAL_VTODO_COMPONENT 
+                     && local_compare(next_alarm_time, cur_time) <= 0)));
+            next_alarm_time = icalrecur_iterator_next(ri),
+            next_start_time = icaltime_add(next_alarm_time, alarm_start_diff)) {
+            /* we loop = search next active alarm time as long as 
+             * next_alarm_time is not null = real alarm time still found
+             * and if TODO and next_alarm_time before complete time
+             *     or if not TODO (= EVENT) and next_alarm_time before current time
+             *    */
             (*cnt_repeat)++;
         }
         icalrecur_iterator_free(ri);
-        if (icaltime_compare(cur_time, next_time) <= 0) {
+        if (icaltime_compare(cur_time, next_alarm_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));
+        new_alarm->alarm_time = g_strdup(icaltime_as_ical_string(next_alarm_time));
         return(new_alarm);
     }
-    else
+    else {
         return(NULL);
+    }
 }
 
 static void process_alarm_data(icalcomponent *ca, alarm_struct *new_alarm)
@@ -3187,6 +3272,7 @@
                 , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring */
             nsdate = icaltime_null_time();
             rrule = icalproperty_get_rrule(p);
+            set_todo_times(c, &per); /* may change per.stime to be per.ctime */
             ri = icalrecur_iterator_new(rrule, per.stime);
             for (nsdate = icalrecur_iterator_next(ri),
                     nedate = icaltime_add(nsdate, per.duration);
@@ -3357,13 +3443,12 @@
   * month: Month to be searched
   */
 static void xfical_mark_calendar_internal(GtkCalendar *gtkcal
-        , icalcomponent *base, int year, int month)
+        , icalcomponent *c, int year, int month)
 {
 #undef P_N
 #define P_N "xfical_mark_calendar_internal: "
     xfical_period per;
     struct icaltimetype nsdate, nedate;
-    icalcomponent *c;
     struct icalrecurrencetype rrule;
     icalrecur_iterator* ri;
     icalproperty *p = NULL;
@@ -3374,66 +3459,87 @@
 #endif
     /* Note that all VEVENTS are marked, but only the first VTODO
      * end date is marked */
+    per = get_period(c);
+    if (per.ikind == ICAL_VEVENT_COMPONENT) {
+        xfical_mark_calendar_days(gtkcal, year, month
+                , per.stime.year, per.stime.month, per.stime.day
+                , per.etime.year, per.etime.month, per.etime.day);
+        if ((p = icalcomponent_get_first_property(c
+                , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring EVENTs */
+            nsdate = icaltime_null_time();
+            rrule = icalproperty_get_rrule(p);
+            ri = icalrecur_iterator_new(rrule, per.stime);
+            for (nsdate = icalrecur_iterator_next(ri),
+                    nedate = icaltime_add(nsdate, per.duration);
+                 !icaltime_is_null_time(nsdate)
+                    && (nsdate.year*12+nsdate.month) <= (year*12+month);
+                 nsdate = icalrecur_iterator_next(ri),
+                    nedate = icaltime_add(nsdate, per.duration)) {
+                xfical_mark_calendar_days(gtkcal, year, month
+                        , nsdate.year, nsdate.month, nsdate.day
+                        , nedate.year, nedate.month, nedate.day);
+            }
+            icalrecur_iterator_free(ri);
+        } 
+    } /* ICAL_VEVENT_COMPONENT */
+    else if (per.ikind == ICAL_VTODO_COMPONENT) {
+        marked = FALSE;
+        if (icaltime_is_null_time(per.ctime)
+        || (local_compare(per.ctime, per.stime) < 0)) {
+            /* VTODO needs to be checked either if it never completed 
+             * or it has completed before start */
+            marked = xfical_mark_calendar_days(gtkcal, year, month
+                    , per.etime.year, per.etime.month, per.etime.day
+                    , per.etime.year, per.etime.month, per.etime.day);
+        }
+        if (!marked && (p = icalcomponent_get_first_property(c
+                , ICAL_RRULE_PROPERTY)) != 0) { 
+            /* check recurring TODOs */
+            nsdate = icaltime_null_time();
+            rrule = icalproperty_get_rrule(p);
+            set_todo_times(c, &per);/* may change per.stime to per.ctime */
+            ri = icalrecur_iterator_new(rrule, per.stime);
+            for (nsdate = icalrecur_iterator_next(ri);
+                 !icaltime_is_null_time(nsdate)
+                    && (nsdate.year*12+nsdate.month) <= (year*12+month)
+                    && (local_compare(nsdate, per.ctime) <= 0);
+                 nsdate = icalrecur_iterator_next(ri)) {
+                /* find the active one like in 
+                 * xfical_appt_get_next_on_day_internal */
+            }
+            icalrecur_iterator_free(ri);
+            if (!icaltime_is_null_time(nsdate)) {
+                nedate = icaltime_add(nsdate, per.duration);
+                marked = xfical_mark_calendar_days(gtkcal, year, month
+                        , nedate.year, nedate.month, nedate.day
+                        , nedate.year, nedate.month, nedate.day);
+            }
+        } 
+    } /* ICAL_VTODO_COMPONENT */
+}
+
+ /* Get all appointments from the file and mark calendar for EVENTs and TODOs
+  */
+static void xfical_mark_calendar_file(GtkCalendar *gtkcal
+        , icalcomponent *base, int year, int month)
+{
+#undef P_N
+#define P_N "xfical_mark_calendar_file: "
+    icalcomponent *c;
+    icalcomponent_kind kind;
+    icalproperty *p = NULL;
+
     for (c = icalcomponent_get_first_component(base, ICAL_ANY_COMPONENT);
          c != 0;
          c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) {
-        per = get_period(c);
-        if (per.ikind == ICAL_VEVENT_COMPONENT) {
-            xfical_mark_calendar_days(gtkcal, year, month
-                    , per.stime.year, per.stime.month, per.stime.day
-                    , per.etime.year, per.etime.month, per.etime.day);
-            if ((p = icalcomponent_get_first_property(c
-                    , ICAL_RRULE_PROPERTY)) != 0) { /* check recurring EVENTs */
-                nsdate = icaltime_null_time();
-                rrule = icalproperty_get_rrule(p);
-                ri = icalrecur_iterator_new(rrule, per.stime);
-                for (nsdate = icalrecur_iterator_next(ri),
-                        nedate = icaltime_add(nsdate, per.duration);
-                     !icaltime_is_null_time(nsdate)
-                        && (nsdate.year*12+nsdate.month) <= (year*12+month);
-                     nsdate = icalrecur_iterator_next(ri),
-                        nedate = icaltime_add(nsdate, per.duration)) {
-                    xfical_mark_calendar_days(gtkcal, year, month
-                            , nsdate.year, nsdate.month, nsdate.day
-                            , nedate.year, nedate.month, nedate.day);
-                }
-                icalrecur_iterator_free(ri);
-            } 
-        } /* ICAL_VEVENT_COMPONENT */
-        else if (per.ikind == ICAL_VTODO_COMPONENT) {
-            marked = FALSE;
-            if (icaltime_is_null_time(per.ctime)
-            || (local_compare(per.ctime, per.stime) <= 0)) {
-                /* VTODO needs to be checked either if it never completed 
-                 * or it has completed before start */
-                marked = xfical_mark_calendar_days(gtkcal, year, month
-                        , per.etime.year, per.etime.month, per.etime.day
-                        , per.etime.year, per.etime.month, per.etime.day);
-            }
-            if (!marked && (p = icalcomponent_get_first_property(c
-                    , ICAL_RRULE_PROPERTY)) != 0) { 
-                /* check recurring TODOs */
-                nsdate = icaltime_null_time();
-                rrule = icalproperty_get_rrule(p);
-                ri = icalrecur_iterator_new(rrule, per.stime);
-                for (nsdate = icalrecur_iterator_next(ri),
-                        nedate = icaltime_add(nsdate, per.duration);
-                     !icaltime_is_null_time(nsdate)
-                        && (nsdate.year*12+nsdate.month) <= (year*12+month)
-                        && (local_compare(nsdate, per.ctime) < 0);
-                     nsdate = icalrecur_iterator_next(ri),
-                        nedate = icaltime_add(nsdate, per.duration)) {
-                    /* find the active one like in 
-                     * xfical_appt_get_next_on_day_internal */
-                }
-                icalrecur_iterator_free(ri);
-                if (!icaltime_is_null_time(nsdate)) {
-                    marked = xfical_mark_calendar_days(gtkcal, year, month
-                            , nedate.year, nedate.month, nedate.day
-                            , nedate.year, nedate.month, nedate.day);
-                }
-            } 
-        } /* ICAL_VTODO_COMPONENT */
+        kind = icalcomponent_isa(c);
+        if (kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT) {
+            /* need to check that priority either does not exist or is high
+             * enough (=smaller than threshhold) */
+            p = icalcomponent_get_first_property(c, ICAL_PRIORITY_PROPERTY);
+            if (!p || icalproperty_get_priority(p) < g_par.priority_list_limit)
+                xfical_mark_calendar_internal(gtkcal, c, year, month);
+        }
     } 
 }
 
@@ -3449,11 +3555,12 @@
 #endif
     gtk_calendar_get_date(gtkcal, &year, &month, &day);
     gtk_calendar_clear_marks(gtkcal);
-    xfical_mark_calendar_internal(gtkcal, ical, year, month+1);
+    xfical_mark_calendar_file(gtkcal, ical, year, month+1);
     for (i = 0; i < g_par.foreign_count; i++) {
-        xfical_mark_calendar_internal(gtkcal, f_ical[i].ical, year, month+1);
+        xfical_mark_calendar_file(gtkcal, f_ical[i].ical, year, month+1);
     }
 }
+
 /* FIXME: seems like this does not understand timezones, but returns
  * always raw time */
 void process_one_app(icalcomponent *comp, struct icaltime_span *span
@@ -3473,18 +3580,20 @@
     orage_message(-100, P_N);
 #endif
     list = (GList **)data;
+    /*
     start = span->start;
     end = span->end;
-    gmtime_r(&start, &start_tm);
-    gmtime_r(&end, &end_tm);
+    */
+    gmtime_r(&span->start, &start_tm);
+    gmtime_r(&span->end, &end_tm);
     time_datap = g_new0(struct time_data, 1);
     strcpy(time_datap->starttimecur, orage_tm_time_to_icaltime(&start_tm));
     strcpy(time_datap->endtimecur, orage_tm_time_to_icaltime(&end_tm));
     *list = g_list_prepend(*list, time_datap);
-/*
- *  g_print("callme: Start:%s End:%s \n"
- *         , time_datap->starttimecur, time_datap->endtimecur);
- */
+    /*
+    g_print("callme: Start:%s End:%s \n"
+            , time_datap->starttimecur, time_datap->endtimecur);
+            */
 }
 
 void xfical_process_each_app(xfical_appt *appt, char *a_day, int days
@@ -3516,7 +3625,42 @@
     icalcomponent_free(icmp);
 }
 
+void xfical_mark_calendar_recur(GtkCalendar *gtkcal, xfical_appt *appt)
+{
+#undef P_N
+#define P_N "xfical_mark_calendar_recur: "
+    guint year, month, day;
+    icalcomponent_kind ikind = ICAL_VEVENT_COMPONENT;
+    icalcomponent *icmp;
+
+#ifdef ORAGE_DEBUG
+    orage_message(-100, P_N);
+#endif
+    gtk_calendar_get_date(gtkcal, &year, &month, &day);
+    gtk_calendar_clear_marks(gtkcal);
+    if (appt->type == XFICAL_TYPE_EVENT)
+        ikind = ICAL_VEVENT_COMPONENT;
+    else if (appt->type == XFICAL_TYPE_TODO)
+        ikind = ICAL_VTODO_COMPONENT;
+    else if (appt->type == XFICAL_TYPE_JOURNAL)
+        ikind = ICAL_VJOURNAL_COMPONENT;
+    else
+        orage_message(260, P_N "Unsupported Type");
+
+    icmp = icalcomponent_vanew(ikind
+               , icalproperty_new_uid("RECUR_TEST")
+               , NULL);
+    appt_add_starttime_internal(appt, icmp);
+    appt_add_endtime_internal(appt, icmp);
+    appt_add_completedtime_internal(appt, icmp);
+    appt_add_recur_internal(appt, icmp);
+    xfical_mark_calendar_internal(gtkcal, icmp, year, month+1);
+    icalcomponent_free(icmp);
+}
+
 #ifdef HAVE_ARCHIVE
+/* FIXME: check that it is not already achived. 
+ * Should not happen, but worth being a bit more robust here */
 static void xfical_icalcomponent_archive_normal(icalcomponent *e) 
 {
 #undef P_N
@@ -3879,40 +4023,96 @@
             file_modified = TRUE;
         }
     }
-    icalset_mark(afical);
-    icalset_commit(afical);
+    if (key_found) {
+        icalset_mark(afical);
+        icalset_commit(afical);
+        icalset_mark(fical);
+        icalset_commit(fical);
+    }
     xfical_archive_close();
-    icalset_mark(fical);
-    icalset_commit(fical);
     xfical_file_close(FALSE);
 
     return(TRUE);
 }
 #endif
 
+static icalcomponent *get_ical_component_uid(char *new_uid, icalcomponent *base)
+{
+    icalcomponent *c;
+    char *old_uid;
+
+    for (c = icalcomponent_get_first_component(base, ICAL_ANY_COMPONENT);
+         c != 0;
+         c = icalcomponent_get_next_component(base, ICAL_ANY_COMPONENT)) {
+        old_uid = (char *)icalcomponent_get_uid(c);
+        if (ORAGE_STR_EXISTS(old_uid) && (strcmp(old_uid, new_uid) == 0)) {
+            return(c);
+        }
+    }
+    return(NULL);
+}
+
 static gboolean add_event(icalcomponent *c)
 {
 #undef P_N
 #define P_N "add_event: "
-    icalcomponent *ca = NULL;
-    char *uid;
+    icalcomponent *new_c = NULL, *old_c = NULL;
+    char *uid, *ext_uid;
+    struct icaltimetype old_mod_time = icaltime_null_time(),
+                        new_mod_time = icaltime_null_time();
+    icalproperty *p;
 
 #ifdef ORAGE_DEBUG
     orage_message(-300, P_N);
 #endif
-    ca = icalcomponent_new_clone(c);
-    if ((uid = (char *)icalcomponent_get_uid(ca)) == NULL) {
+    new_c = icalcomponent_new_clone(c);
+    if ((uid = (char *)icalcomponent_get_uid(new_c)) == NULL) {
         uid = generate_uid();
-        icalcomponent_add_property(ca,  icalproperty_new_uid(uid));
-        orage_message(15, "Generated UID %s", uid);
+        icalcomponent_add_property(new_c,  icalproperty_new_uid(uid));
+        orage_message(15, _("Generated UID %s"), uid);
         g_free(uid);
-
+        if ((uid = (char *)icalcomponent_get_uid(new_c)) == NULL) {
+            orage_message(150, "Add event failed %s", uid);
+            return(FALSE);
+        }
     }
+    orage_message(50, _("import: adding component %s"), uid);
+    /* we need to make sure it is not archived, so let's try to 
+     * unarchive it just to play it safe */
+    ext_uid = g_strconcat("A00.", uid, NULL);
+    if (xfical_unarchive_uid(ext_uid))
+        orage_message(50, _("\timport: Unarchived component"));
+    g_free(ext_uid);
     if (!xfical_file_open(FALSE)) {
         orage_message(250, P_N "ical file open failed");
         return(FALSE);
     }
-    icalcomponent_add_component(ical, ca);
+    if (old_c = get_ical_component_uid(uid, ical)) {
+        orage_message(50, _("\timport: component exists already"));
+        /* component exists already */
+        if ((p = icalcomponent_get_first_property(old_c
+                , ICAL_LASTMODIFIED_PROPERTY)))
+            old_mod_time = icalproperty_get_lastmodified(p);
+        if ((p = icalcomponent_get_first_property(new_c
+                , ICAL_LASTMODIFIED_PROPERTY)))
+            new_mod_time = icalproperty_get_lastmodified(p);
+        orage_message(50, _("\timport: new last modified time %s old last modified time %s")
+                , icaltime_as_ical_string(new_mod_time)
+                , icaltime_as_ical_string(old_mod_time));
+        if (icaltime_compare(new_mod_time, old_mod_time) > 0) {
+            /* new time is more fresh, so we need to remove the old
+             * and add the new one. Adding happens later as it is teh standard
+             * method */
+            icalcomponent_remove_component(ical, old_c);
+        }
+        else { /* old is more fresh, so we do nothing */
+            orage_message(50, _("import: Not added as the new appointment is not newer than the old"));
+            xfical_file_close(FALSE);
+            return(FALSE);
+        }
+    }
+    icalcomponent_add_component(ical, new_c);
+    orage_message(50, _("import: added"));
     file_modified = TRUE;
     icalset_mark(fical);
     icalset_commit(fical);
@@ -3941,7 +4141,7 @@
         g_error_free(error);
         return(FALSE);
     }
-    /***** Check utf8 coformtability *****/
+    /***** Check utf8 conformtability *****/
     if (!g_utf8_validate(text, -1, NULL)) {
         orage_message(250, P_N "is not in utf8 format. Conversion needed.\n (Use iconv and convert it into UTF-8 and import it again.)\n");
         return(FALSE);
@@ -4025,26 +4225,26 @@
 {
 #undef P_N
 #define P_N "xfical_import_file: "
-    icalset *file_ical = NULL;
-    char *ical_file_name = NULL;
+    icalset *imp_file_ical = NULL;
+    char *imp_ical_file_name = NULL;
     icalcomponent *c1, *c2;
     int cnt1 = 0, cnt2 = 0;
 
 #ifdef ORAGE_DEBUG
     orage_message(-100, P_N);
 #endif
-    ical_file_name = g_strdup_printf("%s.orage", file_name);
-    if (!pre_format(file_name, ical_file_name)) {
+    imp_ical_file_name = g_strdup_printf("%s.orage", file_name);
+    if (!pre_format(file_name, imp_ical_file_name)) {
         return(FALSE);
     }
-    if ((file_ical = icalset_new_file(ical_file_name)) == NULL) {
+    if ((imp_file_ical = icalset_new_file(imp_ical_file_name)) == NULL) {
         orage_message(250, P_N "Could not open ical file (%s) %s"
-                , ical_file_name, icalerror_strerror(icalerrno));
+                , imp_ical_file_name, icalerror_strerror(icalerrno));
         return(FALSE);
     }
-    for (c1 = icalset_get_first_component(file_ical);
+    for (c1 = icalset_get_first_component(imp_file_ical);
          c1 != 0;
-         c1 = icalset_get_next_component(file_ical)) {
+         c1 = icalset_get_next_component(imp_file_ical)) {
         if (icalcomponent_isa(c1) == ICAL_VCALENDAR_COMPONENT) {
             cnt1++;
             for (c2=icalcomponent_get_first_component(c1, ICAL_ANY_COMPONENT);
@@ -4053,8 +4253,8 @@
                 if ((icalcomponent_isa(c2) == ICAL_VEVENT_COMPONENT)
                 ||  (icalcomponent_isa(c2) == ICAL_VTODO_COMPONENT)
                 ||  (icalcomponent_isa(c2) == ICAL_VJOURNAL_COMPONENT)) {
-                    cnt2++;
-                    add_event(c2);
+                    if (add_event(c2))
+                        cnt2++;
                 }
                 /* we ignore TIMEZONE component; Orage only uses internal
                  * timezones from libical */
@@ -4062,25 +4262,26 @@
                     orage_message(140, P_N "unknown component %s %s"
                             , icalcomponent_kind_to_string(
                                     icalcomponent_isa(c2))
-                            , ical_file_name);
+                            , imp_ical_file_name);
             }
 
         }
         else
             orage_message(140, P_N "unknown icalset component %s in %s"
                     , icalcomponent_kind_to_string(icalcomponent_isa(c1))
-                    , ical_file_name);
+                    , imp_ical_file_name);
     }
     if (cnt1 == 0) {
         orage_message(150, P_N "No valid icalset components found");
         return(FALSE);
     }
     if (cnt2 == 0) {
-        orage_message(150, P_N "No valid ical components found");
-        return(FALSE);
+        orage_message(150, P_N "No valid ical components imported");
     }
+    orage_message(40, _("Imported %d calendars including %d appointments")
+            , cnt1, cnt2);
 
-    g_free(ical_file_name);
+    g_free(imp_ical_file_name);
     return(TRUE);
 }
 

Modified: xfcalendar/trunk/src/ical-code.h
===================================================================
--- xfcalendar/trunk/src/ical-code.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/ical-code.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -119,6 +119,7 @@
     gboolean recur_byday[7]; /* 0=Mo, 1=Tu, 2=We, 3=Th, 4=Fr, 5=Sa, 6=Su */
     gint   recur_byday_cnt[7]; /* monthly/early: 1=first -1=last 2=second... */
     gint   interval;    /* 1=every day/week..., 2=every second day/week,... */
+    gboolean recur_todo_base_start; /* TRUE=start time, FALSE=completed time */
 } xfical_appt;
 
 gboolean xfical_set_local_timezone(gboolean testing);
@@ -141,6 +142,7 @@
         , GList **data);
 
 void xfical_mark_calendar(GtkCalendar *gtkcal);
+void xfical_mark_calendar_recur(GtkCalendar *gtkcal, xfical_appt *appt);
 
 void xfical_alarm_build_list(gboolean first_list_today);
 

Modified: xfcalendar/trunk/src/interface.c
===================================================================
--- xfcalendar/trunk/src/interface.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/interface.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -38,8 +38,7 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkkeysyms.h>
 
-#include <libxfcegui4/libxfcegui4.h>
-
+#include "orage-i18n.h"
 #include "functions.h"
 #include "mainbox.h"
 #include "interface.h"
@@ -622,7 +621,7 @@
     if (!first)
         gtk_widget_destroy(intf_w->for_cur_frame);
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->for_cur_frame = xfce_create_framebox_with_content(
+    intf_w->for_cur_frame = orage_create_framebox_with_content(
             _("Current foreign files"), vbox);
     gtk_box_pack_start(GTK_BOX(intf_w->for_tab_main_vbox)
             , intf_w->for_cur_frame, FALSE, FALSE, 5);
@@ -693,7 +692,7 @@
     orage_mark_appointments();
     xfical_alarm_build_list(FALSE);
     if (g_par.foreign_count == 1) /* we just added our first foreign file */
-        g_timeout_add(30*1000, (GtkFunction) orage_foreign_files_check, NULL);
+        g_timeout_add_seconds(30, (GtkFunction)orage_foreign_files_check, NULL);
     return(TRUE);
 }
 
@@ -964,14 +963,14 @@
     gchar *str;
 
     m_vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->iea_notebook_page = xfce_create_framebox_with_content(NULL, m_vbox);
+    intf_w->iea_notebook_page = orage_create_framebox_with_content(NULL, m_vbox);
     intf_w->iea_tab_label = gtk_label_new(_("Import/export"));
     gtk_notebook_append_page(GTK_NOTEBOOK(intf_w->notebook)
             , intf_w->iea_notebook_page, intf_w->iea_tab_label);
 
     /***** import *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->iea_imp_frame = xfce_create_framebox_with_content(
+    intf_w->iea_imp_frame = orage_create_framebox_with_content(
             _("Import"), vbox);
     gtk_box_pack_start(GTK_BOX(m_vbox)
             , intf_w->iea_imp_frame, FALSE, FALSE, 5);
@@ -998,7 +997,7 @@
 
     /***** export *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->iea_exp_frame = xfce_create_framebox_with_content(
+    intf_w->iea_exp_frame = orage_create_framebox_with_content(
             _("Export"), vbox);
     gtk_box_pack_start(GTK_BOX(m_vbox)
             , intf_w->iea_exp_frame, FALSE, FALSE, 5);
@@ -1066,7 +1065,7 @@
 #ifdef HAVE_ARCHIVE
     /***** archive *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->iea_arc_frame = xfce_create_framebox_with_content(
+    intf_w->iea_arc_frame = orage_create_framebox_with_content(
             _("Archive"), vbox);
     gtk_box_pack_start(GTK_BOX(m_vbox)
             , intf_w->iea_arc_frame, FALSE, FALSE, 5);
@@ -1107,14 +1106,14 @@
     GtkWidget *label, *hbox, *vbox, *m_vbox;
 
     m_vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->fil_notebook_page = xfce_create_framebox_with_content(NULL, m_vbox);
+    intf_w->fil_notebook_page = orage_create_framebox_with_content(NULL, m_vbox);
     intf_w->fil_tab_label = gtk_label_new(_("Orage files"));
     gtk_notebook_append_page(GTK_NOTEBOOK(intf_w->notebook)
             , intf_w->fil_notebook_page, intf_w->fil_tab_label);
 
     /***** main file *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->orage_file_frame = xfce_create_framebox_with_content(
+    intf_w->orage_file_frame = orage_create_framebox_with_content(
             _("Orage main calendar file"), vbox);
     gtk_box_pack_start(GTK_BOX(m_vbox)
             , intf_w->orage_file_frame, FALSE, FALSE, 5);
@@ -1179,7 +1178,7 @@
 #ifdef HAVE_ARCHIVE
     /***** archive file *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->archive_file_frame = xfce_create_framebox_with_content(
+    intf_w->archive_file_frame = orage_create_framebox_with_content(
             _("Archive file"), vbox);
     gtk_box_pack_start(GTK_BOX(m_vbox)
             , intf_w->archive_file_frame, FALSE, FALSE, 5);
@@ -1241,7 +1240,7 @@
     GtkWidget *label, *hbox, *vbox;
 
     intf_w->for_tab_main_vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->for_notebook_page = xfce_create_framebox_with_content(NULL
+    intf_w->for_notebook_page = orage_create_framebox_with_content(NULL
             , intf_w->for_tab_main_vbox);
     intf_w->for_tab_label = gtk_label_new(_("Foreign files"));
     gtk_notebook_append_page(GTK_NOTEBOOK(intf_w->notebook)
@@ -1249,7 +1248,7 @@
 
     /***** Add new file *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    intf_w->for_new_frame = xfce_create_framebox_with_content(
+    intf_w->for_new_frame = orage_create_framebox_with_content(
             _("Add new foreign file"), vbox);
     gtk_box_pack_start(GTK_BOX(intf_w->for_tab_main_vbox)
             , intf_w->for_new_frame, FALSE, FALSE, 5);

Modified: xfcalendar/trunk/src/main.c
===================================================================
--- xfcalendar/trunk/src/main.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/main.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -482,7 +482,7 @@
 
     /* start monitoring foreign file updates if we have foreign files */
     if (g_par.foreign_count)
-        g_timeout_add(30*1000, (GtkFunction)orage_foreign_files_check, NULL);
+        g_timeout_add_seconds(30, (GtkFunction)orage_foreign_files_check, NULL);
                                                         
     /* let's check if I got filename as a parameter */
     initialized = TRUE;

Modified: xfcalendar/trunk/src/mainbox.c
===================================================================
--- xfcalendar/trunk/src/mainbox.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/mainbox.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -241,7 +241,7 @@
         g_source_remove(timer);
     if (calendar->num_marked_dates) /* undocumented, internal field; ugly */
         gtk_calendar_clear_marks(calendar);
-    timer = g_timeout_add(500, (GtkFunction)upd_calendar, calendar);
+    timer = g_timeout_add(400, (GtkFunction)upd_calendar, calendar);
 }
 
 static void build_menu(void)

Modified: xfcalendar/trunk/src/parameters.c
===================================================================
--- xfcalendar/trunk/src/parameters.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/parameters.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -323,7 +323,6 @@
 
 static void set_systray()
 {
-#if GTK_CHECK_VERSION(2,10,0)
     if (!(g_par.trayIcon 
     && gtk_status_icon_is_embedded((GtkStatusIcon *)g_par.trayIcon))) {
         g_par.trayIcon = create_TrayIcon();
@@ -333,17 +332,6 @@
         gtk_status_icon_set_visible((GtkStatusIcon *)g_par.trayIcon, TRUE);
     else
         gtk_status_icon_set_visible((GtkStatusIcon *)g_par.trayIcon, FALSE);
-#else
-    if (!(g_par.trayIcon 
-    && NETK_IS_TRAY_ICON(((XfceTrayIcon *)g_par.trayIcon)->tray))) {
-        g_par.trayIcon = create_TrayIcon();
-    }
-
-    if (g_par.show_systray)
-        xfce_tray_icon_connect((XfceTrayIcon *)g_par.trayIcon);
-    else
-        xfce_tray_icon_disconnect((XfceTrayIcon *)g_par.trayIcon);
-#endif
 }
 
 static void systray_changed(GtkWidget *dialog, gpointer user_data)
@@ -469,14 +457,14 @@
 
     dialog->setup_vbox = gtk_vbox_new(FALSE, 0);
     dialog->setup_tab = 
-            xfce_create_framebox_with_content(NULL, dialog->setup_vbox);
+            orage_create_framebox_with_content(NULL, dialog->setup_vbox);
     dialog->setup_tab_label = gtk_label_new(_("Main setups"));
     gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook)
           , dialog->setup_tab, dialog->setup_tab_label);
 
     /* Choose a timezone to be used in appointments */
     vbox = gtk_vbox_new(TRUE, 0);
-    dialog->timezone_frame = xfce_create_framebox_with_content(_("Timezone")
+    dialog->timezone_frame = orage_create_framebox_with_content(_("Timezone")
             , vbox);
     gtk_box_pack_start(GTK_BOX(dialog->setup_vbox)
             , dialog->timezone_frame, FALSE, FALSE, 5);
@@ -504,7 +492,7 @@
     /* Choose archiving threshold */
     hbox = gtk_hbox_new(FALSE, 0);
     dialog->archive_threshold_frame = 
-            xfce_create_framebox_with_content(_("Archive threshold (months)")
+            orage_create_framebox_with_content(_("Archive threshold (months)")
                     , hbox);
     gtk_box_pack_start(GTK_BOX(dialog->setup_vbox)
             , dialog->archive_threshold_frame, FALSE, FALSE, 5);
@@ -526,7 +514,7 @@
     /* Choose a sound application for reminders */
     hbox = gtk_hbox_new(FALSE, 0);
     dialog->sound_application_frame = 
-            xfce_create_framebox_with_content(_("Sound command"), hbox);
+            orage_create_framebox_with_content(_("Sound command"), hbox);
     gtk_box_pack_start(GTK_BOX(dialog->setup_vbox)
             , dialog->sound_application_frame, FALSE, FALSE, 5);
 
@@ -555,7 +543,7 @@
 
     dialog->display_vbox = gtk_vbox_new(FALSE, 0);
     dialog->display_tab = 
-        xfce_create_framebox_with_content(NULL, dialog->display_vbox);
+        orage_create_framebox_with_content(NULL, dialog->display_vbox);
     dialog->display_tab_label = gtk_label_new(_("Display"));
     gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook)
           , dialog->display_tab, dialog->display_tab_label);
@@ -563,7 +551,7 @@
     /* Display calendar borders and menu or not and set stick or ontop */
     vbox = gtk_vbox_new(TRUE, 0);
     dialog->mode_frame = 
-            xfce_create_framebox_with_content(_("Calendar main window"), vbox);
+            orage_create_framebox_with_content(_("Calendar main window"), vbox);
     gtk_box_pack_start(GTK_BOX(dialog->display_vbox), dialog->mode_frame
             , FALSE, FALSE, 5);
 
@@ -654,7 +642,7 @@
     /* how to show when started (show/hide/minimize) */
     dialog->visibility_radiobutton_group = NULL;
     hbox = gtk_hbox_new(TRUE, 0);
-    dialog->visibility_frame = xfce_create_framebox_with_content(
+    dialog->visibility_frame = orage_create_framebox_with_content(
             _("Calendar start") , hbox);
     gtk_box_pack_start(GTK_BOX(dialog->display_vbox), dialog->visibility_frame
             , FALSE, FALSE, 5);
@@ -713,14 +701,14 @@
 
     dialog->extra_vbox = gtk_vbox_new(FALSE, 0);
     dialog->extra_tab = 
-            xfce_create_framebox_with_content(NULL, dialog->extra_vbox);
+            orage_create_framebox_with_content(NULL, dialog->extra_vbox);
     dialog->extra_tab_label = gtk_label_new(_("Extra setups"));
     gtk_notebook_append_page(GTK_NOTEBOOK(dialog->notebook)
           , dialog->extra_tab, dialog->extra_tab_label);
 
     /****** select_always_today ******/
     hbox = gtk_hbox_new(FALSE, 0);
-    dialog->always_today_frame = xfce_create_framebox_with_content(
+    dialog->always_today_frame = orage_create_framebox_with_content(
             _("Select always today"), hbox);
     gtk_box_pack_start(GTK_BOX(dialog->extra_vbox)
             , dialog->always_today_frame, FALSE, FALSE, 5);
@@ -740,7 +728,7 @@
     /* code removed. relying in get_first_weekday_from_locale now
     / ***** ical week start day (0 = Monday, 1 = Tuesday,... 6 = Sunday) ***** /
     hbox = gtk_hbox_new(FALSE, 0);
-    dialog->ical_weekstartday_frame = xfce_create_framebox_with_content(
+    dialog->ical_weekstartday_frame = orage_create_framebox_with_content(
             _("Ical week start day"), hbox);
     gtk_box_pack_start(GTK_BOX(dialog->extra_vbox)
             , dialog->ical_weekstartday_frame, FALSE, FALSE, 5);
@@ -762,7 +750,7 @@
 
     /***** tray icon size  (0 = use static icon) *****/
     vbox = gtk_vbox_new(FALSE, 0);
-    dialog->icon_size_frame = xfce_create_framebox_with_content(
+    dialog->icon_size_frame = orage_create_framebox_with_content(
             _("Dynamic icon size"), vbox);
     gtk_box_pack_start(GTK_BOX(dialog->extra_vbox)
             , dialog->icon_size_frame, FALSE, FALSE, 5);
@@ -801,7 +789,7 @@
     /***** Start event or day window from main calendar *****/
     dialog->click_to_show_radiobutton_group = NULL;
     hbox = gtk_vbox_new(FALSE, 0);
-    dialog->click_to_show_frame = xfce_create_framebox_with_content(
+    dialog->click_to_show_frame = orage_create_framebox_with_content(
             _("Main Calendar double click shows"), hbox);
     gtk_box_pack_start(GTK_BOX(dialog->extra_vbox)
             , dialog->click_to_show_frame, FALSE, FALSE, 5);
@@ -956,6 +944,7 @@
         orage_rc_del_item(orc, f_par);
     }
     orage_rc_put_int(orc, "Logging level", g_par.log_level);
+    orage_rc_put_int(orc, "Priority list limit", g_par.priority_list_limit);
 
     orage_rc_file_close(orc);
 }
@@ -1096,6 +1085,7 @@
         g_par.foreign_data[i].read_only = orage_rc_get_bool(orc, f_par, TRUE);
     }
     g_par.log_level = orage_rc_get_int(orc, "Logging level", 0);
+    g_par.priority_list_limit = orage_rc_get_int(orc, "Priority list limit", 8);
 
     orage_rc_file_close(orc);
 }

Modified: xfcalendar/trunk/src/parameters.h
===================================================================
--- xfcalendar/trunk/src/parameters.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/parameters.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -79,7 +79,7 @@
     gint pos_x, pos_y;
 
     /* tray icon */
-    void *trayIcon; /* this is XfceTrayIcon * */
+    void *trayIcon; /* this is GtkStatusIcon * */
     gint icon_size_x, icon_size_y;
 
     /* event-list window */
@@ -90,6 +90,9 @@
 
     /* Controls which messages are printed */
     gint log_level;
+
+    /* Controls which appointment priorities are shown in lists */
+    gint priority_list_limit;
 } global_parameters; /* global parameters */
 
 #ifdef ORAGE_MAIN

Modified: xfcalendar/trunk/src/reminder.c
===================================================================
--- xfcalendar/trunk/src/reminder.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/reminder.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -53,7 +53,6 @@
 #include "event-list.h"
 #include "appointment.h"
 #include "reminder.h"
-#include "xfce_trayicon.h"
 #include "tray_icon.h"
 #include "parameters.h"
 
@@ -360,8 +359,7 @@
         alarm->repeat_cnt++; /* need to do it once */
     }
 
-    g_timeout_add(alarm->repeat_delay*1000
-            , (GtkFunction) sound_alarm
+    g_timeout_add_seconds(alarm->repeat_delay, (GtkFunction) sound_alarm
             , (gpointer) alarm);
 }
 
@@ -427,17 +425,10 @@
         g_strlcat(heading, alarm->title, 50);
     n = notify_notification_new(heading, alarm->description, NULL, NULL);
     alarm->active_alarm->active_notify = n;
-#if GTK_CHECK_VERSION(2,10,0)
     if (g_par.trayIcon 
     && gtk_status_icon_is_embedded((GtkStatusIcon *)g_par.trayIcon))
         notify_notification_attach_to_status_icon(n
                 , (GtkStatusIcon *)g_par.trayIcon);
-#else
-    if (g_par.trayIcon 
-    && NETK_IS_TRAY_ICON(((XfceTrayIcon *)g_par.trayIcon)->tray)) 
-        notify_notification_attach_to_widget(n
-                , ((XfceTrayIcon *)g_par.trayIcon)->image);
-#endif
 
     if (alarm->notify_timeout == -1)
         notify_notification_set_timeout(n, NOTIFY_EXPIRES_NEVER);
@@ -731,7 +722,7 @@
     else { /* the change did not happen. Need to try again asap. */
         secs_left = 1;
     }
-    g_par.day_timer = g_timeout_add(secs_left * 1000
+    g_par.day_timer = g_timeout_add_seconds(secs_left
             , (GtkFunction) orage_day_change, NULL);
 }
 
@@ -806,7 +797,7 @@
         secs_to_alarm += 1; /* alarm needs to come a bit later */
         if (secs_to_alarm < 1) /* were rare, but possible */
             secs_to_alarm = 1;
-        g_par.alarm_timer = g_timeout_add(secs_to_alarm * 1000
+        g_par.alarm_timer = g_timeout_add_seconds(secs_to_alarm
                 , (GtkFunction) orage_alarm_clock, NULL);
     }
 }
@@ -830,13 +821,8 @@
 #ifdef ORAGE_DEBUG
     orage_message(-100, P_N);
 #endif
-#if GTK_CHECK_VERSION(2,10,0)
     if (!(g_par.trayIcon 
     && gtk_status_icon_is_embedded((GtkStatusIcon *)g_par.trayIcon))) {
-#else
-    if (!(g_par.trayIcon 
-    && NETK_IS_TRAY_ICON(((XfceTrayIcon *)g_par.trayIcon)->tray))) { 
-#endif
            /* no trayicon => no need to update the tooltip */
         return(FALSE);
     }
@@ -878,12 +864,7 @@
     }
     if (alarm_cnt == 0)
         g_string_append_printf(tooltip, _("\nNo active alarms found"));
-#if GTK_CHECK_VERSION(2,10,0)
     gtk_status_icon_set_tooltip((GtkStatusIcon *)g_par.trayIcon, tooltip->str);
-#else
-    xfce_tray_icon_set_tooltip((XfceTrayIcon *)g_par.trayIcon, tooltip->str
-            , NULL);
-#endif
     g_string_free(tooltip, TRUE);
     return(TRUE);
 }
@@ -902,7 +883,7 @@
     }
 
     orage_tooltip_update(NULL);
-    g_par.tooltip_timer = g_timeout_add(60*1000
+    g_par.tooltip_timer = g_timeout_add_seconds(60
             , (GtkFunction) orage_tooltip_update, NULL);
     return(FALSE);
 }
@@ -927,7 +908,7 @@
      * only when appoinments are updated in less than 1 minute apart. 
      * Perhaps not worth fixing. 
      * Should add another timer or static time to keep track of this */
-    g_timeout_add(secs_left*1000
+    g_timeout_add_seconds(secs_left
             , (GtkFunction) start_orage_tooltip_update, NULL);
     return(FALSE);
 }
@@ -944,5 +925,5 @@
     store_persistent_alarms(); /* keep track of alarms when orage is down */
     /* We need to use timer since for some reason it does not work if we
      * do it here directly. Ugly, I know, but it works. */
-    g_timeout_add(1*1000, (GtkFunction) reset_orage_tooltip_update, NULL);
+    g_timeout_add_seconds(1, (GtkFunction) reset_orage_tooltip_update, NULL);
 }

Modified: xfcalendar/trunk/src/tray_icon.c
===================================================================
--- xfcalendar/trunk/src/tray_icon.c	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/tray_icon.c	2009-04-24 07:18:45 UTC (rev 29900)
@@ -33,19 +33,17 @@
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 #include <glib/gprintf.h>
-#include <libxfcegui4/libxfcegui4.h>
-#include <libxfcegui4/netk-trayicon.h>
 
+#include "orage-i18n.h"
 #include "functions.h"
 #include "mainbox.h"
 #include "about-xfcalendar.h"
 #include "ical-code.h"
 #include "event-list.h"
 #include "appointment.h"
-#include "xfce_trayicon.h"
 #include "parameters.h"
 
-#define ORAGE_TRAYICON ((XfceTrayIcon *)g_par.trayIcon)
+#define ORAGE_TRAYICON ((GtkStatusIcon *)g_par.trayIcon)
 
 void orage_toggle_visible();
 
@@ -83,23 +81,21 @@
     create_wAbout((GtkWidget *)menuitem, user_data);
 }
 
-#if GTK_CHECK_VERSION(2,10,0)
 void toggle_visible_cb(GtkStatusIcon *status_icon, gpointer user_data)
-#else
-void toggle_visible_cb ()
-#endif
 {
     orage_toggle_visible ();
 }
 
-#if GTK_CHECK_VERSION(2,10,0)
 void show_menu(GtkStatusIcon *status_icon, guint button, guint activate_time
         , gpointer user_data)
 {
     gtk_menu_popup((GtkMenu *)user_data, NULL, NULL, NULL, NULL, button, activate_time);
 }
-#endif
 
+GdkPixbuf *orage_create_icon2(gboolean static_icon, gint x, gint y)
+{
+}
+
 GdkPixbuf *orage_create_icon(gboolean static_icon, gint x, gint y)
 {
     CalWin *xfcal = (CalWin *)g_par.xfcal;
@@ -296,29 +292,15 @@
     return(pixbuf);
 }
 
-void destroy_TrayIcon(XfceTrayIcon *trayIcon)
+void destroy_TrayIcon(GtkStatusIcon *trayIcon)
 {
-#if GTK_CHECK_VERSION(2,10,0)
     g_object_unref(trayIcon);
-#else
-    if (trayIcon == NULL) 
-        return;
-    if (trayIcon->tip_text != NULL)
-        g_free(trayIcon->tip_text);
-    if (trayIcon->tip_private != NULL)
-        g_free(trayIcon->tip_private);
-    g_object_unref(G_OBJECT(trayIcon->tooltips));
-    g_object_unref(G_OBJECT(trayIcon->image));
-    /*
-    g_object_unref(GTK_OBJECT(trayIcon));
-    */
-#endif
 }
 
-XfceTrayIcon* create_TrayIcon()
+GtkStatusIcon* create_TrayIcon()
 {
     CalWin *xfcal = (CalWin *)g_par.xfcal;
-    XfceTrayIcon *trayIcon = NULL;
+    GtkStatusIcon *trayIcon = NULL;
     GtkWidget *menuItem;
     GtkWidget *trayMenu;
     GdkPixbuf *pixbuf;
@@ -379,49 +361,27 @@
      */
 
     pixbuf = orage_create_icon(FALSE, g_par.icon_size_x, g_par.icon_size_y);
-#if GTK_CHECK_VERSION(2,10,0)
     trayIcon = gtk_status_icon_new_from_pixbuf(pixbuf);
-#else
-    trayIcon = xfce_tray_icon_new_with_menu_from_pixbuf(trayMenu, pixbuf);
-#endif
 
     g_object_ref(trayIcon);
-#if GTK_CHECK_VERSION(2,10,0)
     g_object_ref_sink(trayIcon);
-#else
-    gtk_object_sink(GTK_OBJECT(trayIcon));
-#endif
     g_object_unref(pixbuf);
 
-#if GTK_CHECK_VERSION(2,10,0)
     g_signal_connect(G_OBJECT(trayIcon), "activate",
     			   G_CALLBACK(toggle_visible_cb), xfcal);
     g_signal_connect(G_OBJECT(trayIcon), "popup_menu",
     			   G_CALLBACK(show_menu), trayMenu);
-#else
-    g_signal_connect_swapped(G_OBJECT(trayIcon), "clicked",
-    			   G_CALLBACK(toggle_visible_cb), xfcal);
-#endif
     return(trayIcon);
 }
 
 void refresh_TrayIcon()
 {
     if (g_par.show_systray) { /* refresh tray icon */
-#if GTK_CHECK_VERSION(2,10,0)
         if (ORAGE_TRAYICON && gtk_status_icon_is_embedded(ORAGE_TRAYICON)) {
             gtk_status_icon_set_visible(ORAGE_TRAYICON, FALSE);
             destroy_TrayIcon(ORAGE_TRAYICON);
         }
         g_par.trayIcon = create_TrayIcon();
         gtk_status_icon_set_visible(ORAGE_TRAYICON, TRUE);
-#else
-        if (ORAGE_TRAYICON && NETK_IS_TRAY_ICON(ORAGE_TRAYICON->tray)) {
-            xfce_tray_icon_disconnect(ORAGE_TRAYICON);
-            destroy_TrayIcon(ORAGE_TRAYICON);
-        }
-        g_par.trayIcon = create_TrayIcon();
-        xfce_tray_icon_connect(ORAGE_TRAYICON);
-#endif
     }
 }

Modified: xfcalendar/trunk/src/tray_icon.h
===================================================================
--- xfcalendar/trunk/src/tray_icon.h	2009-04-23 23:04:58 UTC (rev 29899)
+++ xfcalendar/trunk/src/tray_icon.h	2009-04-24 07:18:45 UTC (rev 29900)
@@ -24,11 +24,9 @@
 #ifndef __TRAY_ICON_H__
 #define __TRAY_ICON_H__
 
-#include "xfce_trayicon.h"
-
 GdkPixbuf *orage_create_icon(gboolean static_icon, gint x, gint y);
 
-XfceTrayIcon *create_TrayIcon(void);
+GtkStatusIcon *create_TrayIcon(void);
 
 void refresh_TrayIcon(void);
 




More information about the Xfce4-commits mailing list