removed notifyCategoriesChanged method on CalListener.
[platform/upstream/evolution-data-server.git] / calendar / backends / file / e-cal-backend-file.c
index 2b5a2c7..3c09ecc 100644 (file)
@@ -59,7 +59,9 @@ struct _ECalBackendFilePrivate {
        char *file_name;        
        gboolean read_only;
        gboolean is_dirty;
-       gint dirty_idle_id;
+       guint dirty_idle_id;
+
+       GMutex *idle_save_mutex;
 
        /* Toplevel VCALENDAR component */
        icalcomponent *icalcomp;
@@ -122,6 +124,13 @@ save_file_when_idle (gpointer user_data)
        g_assert (priv->uri != NULL);
        g_assert (priv->icalcomp != NULL);
 
+       g_mutex_lock (priv->idle_save_mutex);
+       if (!priv->is_dirty) {
+               priv->dirty_idle_id = 0;
+               g_mutex_unlock (priv->idle_save_mutex);
+               return FALSE;
+       }
+
        uri = gnome_vfs_uri_new (priv->uri);
        if (!uri)
                goto error_malformed_uri;
@@ -171,15 +180,20 @@ save_file_when_idle (gpointer user_data)
                goto error;
 
        priv->is_dirty = FALSE;
+       priv->dirty_idle_id = 0;
 
-       return TRUE;
+       g_mutex_unlock (priv->idle_save_mutex);
+
+       return FALSE;
 
  error_malformed_uri:
+       g_mutex_unlock (priv->idle_save_mutex);
        e_cal_backend_notify_error (E_CAL_BACKEND (cbfile),
                                  _("Can't save calendar data: Malformed URI."));
        return TRUE;
 
  error:
+       g_mutex_unlock (priv->idle_save_mutex);
        e_cal_backend_notify_error (E_CAL_BACKEND (cbfile), gnome_vfs_result_to_string (result));
        return TRUE;
 }
@@ -191,11 +205,13 @@ save (ECalBackendFile *cbfile)
 
        priv = cbfile->priv;
 
-       if (!priv->dirty_idle_id) {
+       g_mutex_lock (priv->idle_save_mutex);
+       priv->is_dirty = TRUE;
+
+       if (!priv->dirty_idle_id)
                priv->dirty_idle_id = g_idle_add ((GSourceFunc) save_file_when_idle, cbfile);
-       }
 
-       priv->is_dirty = TRUE;
+       g_mutex_unlock (priv->idle_save_mutex);
 }
 
 static void
@@ -266,6 +282,11 @@ e_cal_backend_file_finalize (GObject *object)
                priv->dirty_idle_id = 0;
        }
 
+       if (priv->idle_save_mutex) {
+               g_mutex_free (priv->idle_save_mutex);
+               priv->idle_save_mutex = NULL;
+       }
+
        if (priv->uri) {
                g_free (priv->uri);
                priv->uri = NULL;
@@ -416,7 +437,6 @@ add_component (ECalBackendFile *cbfile, ECalComponent *comp, gboolean add_to_top
        ECalBackendFilePrivate *priv;
        ECalBackendFileObject *obj_data;
        const char *uid;
-       GSList *categories;
 
        priv = cbfile->priv;
 
@@ -473,12 +493,9 @@ add_component (ECalBackendFile *cbfile, ECalComponent *comp, gboolean add_to_top
                g_assert (icalcomp != NULL);
 
                icalcomponent_add_component (priv->icalcomp, icalcomp);
-       }
 
-       /* Update the set of categories */
-       e_cal_component_get_categories_list (comp, &categories);
-       e_cal_backend_ref_categories (E_CAL_BACKEND (cbfile), categories);
-       e_cal_component_free_categories_list (categories);
+               save (cbfile);
+       }
 }
 
 /* g_hash_table_foreach_remove() callback to remove recurrences from the calendar */
@@ -486,7 +503,6 @@ static gboolean
 remove_recurrence_cb (gpointer key, gpointer value, gpointer data)
 {
        GList *l;
-       GSList *categories;
        icalcomponent *icalcomp;
        ECalBackendFilePrivate *priv;
        ECalComponent *comp = value;
@@ -504,11 +520,6 @@ remove_recurrence_cb (gpointer key, gpointer value, gpointer data)
        l = g_list_find (priv->comp, comp);
        priv->comp = g_list_delete_link (priv->comp, l);
 
-       /* Update the set of categories */
-       e_cal_component_get_categories_list (comp, &categories);
-       e_cal_backend_unref_categories (E_CAL_BACKEND (cbfile), categories);
-       e_cal_component_free_categories_list (categories);
-
        return TRUE;
 }
 
@@ -522,7 +533,6 @@ remove_component (ECalBackendFile *cbfile, const char *uid, ECalBackendFileObjec
        ECalBackendFilePrivate *priv;
        icalcomponent *icalcomp;
        GList *l;
-       GSList *categories;
 
        priv = cbfile->priv;
 
@@ -537,11 +547,6 @@ remove_component (ECalBackendFile *cbfile, const char *uid, ECalBackendFileObjec
                l = g_list_find (priv->comp, obj_data->full_object);
                g_assert (l != NULL);
                priv->comp = g_list_delete_link (priv->comp, l);
-
-               /* Update the set of categories */
-               e_cal_component_get_categories_list (obj_data->full_object, &categories);
-               e_cal_backend_unref_categories (E_CAL_BACKEND (cbfile), categories);
-               e_cal_component_free_categories_list (categories);
        }
 
        /* remove the recurrences also */
@@ -549,6 +554,8 @@ remove_component (ECalBackendFile *cbfile, const char *uid, ECalBackendFileObjec
 
        g_hash_table_remove (priv->comp_uid_hash, uid);
        free_object ((gpointer) uid, (gpointer) obj_data, NULL);
+
+       save (cbfile);
 }
 
 /* Scans the toplevel VCALENDAR component and stores the objects it finds */
@@ -1655,7 +1662,6 @@ sanitize_component (ECalBackendFile *cbfile, ECalComponent *comp)
 
 }      
 
-
 static ECalBackendSyncStatus
 e_cal_backend_file_create_object (ECalBackendSync *backend, EDataCal *cal, char **calobj, char **uid)
 {
@@ -1743,7 +1749,6 @@ static gboolean
 remove_object_instance_cb (gpointer key, gpointer value, gpointer user_data)
 {
        time_t fromtt, instancett;
-       GSList *categories;
        ECalComponent *instance = value;
        RemoveRecurrenceData *rrdata = user_data;
 
@@ -1760,11 +1765,6 @@ remove_object_instance_cb (gpointer key, gpointer value, gpointer user_data)
 
                        rrdata->obj_data->recurrences_list = g_list_remove (rrdata->obj_data->recurrences_list, instance);
 
-                       /* update the set of categories */
-                       e_cal_component_get_categories_list (instance, &categories);
-                       e_cal_backend_unref_categories (E_CAL_BACKEND (rrdata->cbfile), categories);
-                       e_cal_component_free_categories_list (categories);
-
                        return TRUE;
                }
        }
@@ -1974,7 +1974,6 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
 {
        char *hash_rid;
        ECalComponent *comp;
-       GSList *categories;
 
        if (!rid || !*rid)
                return;
@@ -1986,15 +1985,6 @@ remove_instance (ECalBackendFile *cbfile, ECalBackendFileObject *obj_data, const
                cbfile->priv->comp = g_list_remove (cbfile->priv->comp, comp);
                obj_data->recurrences_list = g_list_remove (obj_data->recurrences_list, comp);
                g_hash_table_remove (obj_data->recurrences, rid);
-               
-               /* update the set of categories */
-               e_cal_component_get_categories_list (comp, &categories);
-               e_cal_backend_unref_categories (E_CAL_BACKEND (cbfile), categories);
-               e_cal_component_free_categories_list (categories);
-
-               /* free memory */
-               g_free (hash_rid);
-               g_object_unref (comp);
 
                return;
        }
@@ -2108,6 +2098,8 @@ cancel_received_object (ECalBackendFile *cbfile, icalcomponent *icalcomp)
 {
        ECalBackendFileObject *obj_data;
        ECalBackendFilePrivate *priv;
+       const char *rid;
+       ECalComponent *comp;
 
        priv = cbfile->priv;
 
@@ -2117,7 +2109,17 @@ cancel_received_object (ECalBackendFile *cbfile, icalcomponent *icalcomp)
                return FALSE;
 
        /* And remove it */
-       remove_component (cbfile, icalcomponent_get_uid (icalcomp), obj_data);
+       comp = e_cal_component_new ();
+       if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp))) {
+               g_object_unref (comp);
+               return FALSE;
+       }
+
+       rid = e_cal_component_get_recurid_as_string (comp);
+       if (rid && *rid)
+               remove_instance (cbfile, obj_data, rid);
+       else
+               remove_component (cbfile, icalcomponent_get_uid (icalcomp), obj_data);
 
        return TRUE;
 }
@@ -2221,7 +2223,7 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, con
        ECalBackendFilePrivate *priv;
        icalcomponent *toplevel_comp, *icalcomp = NULL;
        icalcomponent_kind kind;
-       icalproperty_method method;
+       icalproperty_method toplevel_method, method;
        icalcomponent *subcomp;
        GList *comps, *del_comps, *l;
        ECalComponent *comp;
@@ -2245,10 +2247,17 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, con
                /* If its not a VCALENDAR, make it one to simplify below */
                icalcomp = toplevel_comp;
                toplevel_comp = e_cal_util_new_top_level ();
-               icalcomponent_add_component (toplevel_comp, icalcomp);  
+               if (icalcomponent_get_method (icalcomp) == ICAL_METHOD_CANCEL)
+                       icalcomponent_set_method (toplevel_comp, ICAL_METHOD_CANCEL);
+               else
+                       icalcomponent_set_method (toplevel_comp, ICAL_METHOD_PUBLISH);
+               icalcomponent_add_component (toplevel_comp, icalcomp);
+       } else {
+               if (!icalcomponent_get_first_property (toplevel_comp, ICAL_METHOD_PROPERTY))
+                       icalcomponent_set_method (toplevel_comp, ICAL_METHOD_PUBLISH);
        }
 
-       method = icalcomponent_get_method (toplevel_comp);
+       toplevel_method = icalcomponent_get_method (toplevel_comp);
 
        /* Build a list of timezones so we can make sure all the objects have valid info */
        tzdata.zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -2318,6 +2327,11 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, con
                e_cal_component_get_uid (comp, &uid);
                rid = e_cal_component_get_recurid_as_string (comp);
 
+               if (icalcomponent_get_first_property (subcomp, ICAL_METHOD_PROPERTY))
+                       method = icalcomponent_get_method (subcomp);
+               else
+                       method = toplevel_method;
+
                switch (method) {
                case ICAL_METHOD_PUBLISH:
                case ICAL_METHOD_REQUEST:
@@ -2328,7 +2342,10 @@ e_cal_backend_file_receive_objects (ECalBackendSync *backend, EDataCal *cal, con
                        obj_data = g_hash_table_lookup (priv->comp_uid_hash, uid);
                        if (obj_data) {
                                old_object = e_cal_component_get_as_string (obj_data->full_object);
-                               remove_component (cbfile, uid, obj_data);
+                               if (rid)
+                                       remove_instance (cbfile, obj_data, rid);
+                               else
+                                       remove_component (cbfile, uid, obj_data);
                                add_component (cbfile, comp, FALSE);
 
                                object = e_cal_component_get_as_string (comp);
@@ -2428,6 +2445,7 @@ e_cal_backend_file_init (ECalBackendFile *cbfile, ECalBackendFileClass *class)
        priv->read_only = FALSE;
        priv->is_dirty = FALSE;
        priv->dirty_idle_id = 0;
+       priv->idle_save_mutex = g_mutex_new ();
        priv->icalcomp = NULL;
        priv->comp_uid_hash = NULL;
        priv->comp = NULL;