summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sync/ChangeLog29
-rw-r--r--sync/src/Makefile.am3
-rw-r--r--sync/src/sync_collection.c406
-rw-r--r--sync/src/sync_collection.h67
-rw-r--r--sync/src/sync_evo2_item.c5
-rw-r--r--sync/src/sync_file_item.c5
-rw-r--r--sync/src/sync_group.c83
-rw-r--r--sync/src/sync_item.c67
-rw-r--r--sync/src/sync_item.h14
-rw-r--r--sync/src/sync_main.c223
-rw-r--r--sync/src/sync_main.h16
-rw-r--r--sync/src/sync_syncml_item.c4
12 files changed, 646 insertions, 276 deletions
diff --git a/sync/ChangeLog b/sync/ChangeLog
index f4c7e7b..1ad9538 100644
--- a/sync/ChangeLog
+++ b/sync/ChangeLog
@@ -1,3 +1,32 @@
+2006-08-03 Chris Lord,,, <chris@openedhand.com>
+
+ * src/Makefile.am:
+ * src/sync_collection.c:
+ * src/sync_collection.h:
+ Write a class that allows simultaneous synchronisation of multiple
+ SyncGroup's
+
+ * src/sync_evo2_item.c:
+ * src/sync_file_item.c:
+ * src/sync_syncml_item.c:
+ Adapt to changes in SyncItem class
+
+ * src/sync_group.c: (sync_group_set_item1), (sync_group_set_item2):
+ Adapt to changes in SyncItem class
+
+ * src/sync_item.c: (sync_item_set_property),
+ (sync_item_get_property):
+ * src/sync_item.h:
+ Don't extend GInitiallyUnknown, change methods slightly to allow
+ SyncItem's to be placed in multiple SyncGroup's
+
+ * src/sync_main.c: (sync_clean_backup), (sync_item_activated_cb),
+ (main):
+ * src/sync_main.h:
+ Use SyncCollection instead of SyncGroup for synchronisation,
+ synchronise contacts, events and tasks simultaneously when doing a
+ SyncML synchronisation
+
2006-08-02 Chris Lord,,, <chris@openedhand.com>
* data/sync.glade:
diff --git a/sync/src/Makefile.am b/sync/src/Makefile.am
index 80a4ba5..87a4753 100644
--- a/sync/src/Makefile.am
+++ b/sync/src/Makefile.am
@@ -5,7 +5,8 @@ bin_PROGRAMS = sync
sync_SOURCES = sync_main.c sync.h sync_group.c sync_group.h sync_item.c \
sync_item.h sync_evo2_item.c sync_evo2_item.h sync_file_item.c \
- sync_file_item.h sync_syncml_item.c sync_syncml_item.h
+ sync_file_item.h sync_syncml_item.c sync_syncml_item.h \
+ sync_collection.c sync_collection.h
sync_LDADD = $(SYNC_LIBS)
diff --git a/sync/src/sync_collection.c b/sync/src/sync_collection.c
new file mode 100644
index 0000000..88b2d05
--- /dev/null
+++ b/sync/src/sync_collection.c
@@ -0,0 +1,406 @@
+
+#include <glib.h>
+#include "sync_group.h"
+#include "sync_collection.h"
+
+G_DEFINE_TYPE (SyncCollection, sync_collection, G_TYPE_OBJECT);
+
+#define COLLECTION_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), SYNC_TYPE_COLLECTION, SyncCollectionPrivate))
+
+typedef struct _SyncCollectionPrivate SyncCollectionPrivate;
+
+enum {
+ STARTED,
+ PROGRESS,
+ CONFLICT,
+ FINISHED,
+ FAILED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+typedef struct {
+ SyncGroup *group;
+ gdouble progress;
+ gchar *error;
+} SyncCollectionGroup;
+
+struct _SyncCollectionPrivate
+{
+ GList *groups;
+
+ gboolean started;
+ gdouble progress;
+ gint num_groups;
+ gint num_finished;
+};
+
+static void
+sync_collection_finalize (GObject *object)
+{
+ SyncCollection *collection = SYNC_COLLECTION (object);
+/* SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);*/
+
+ /* TODO: Guard against, or cater for this happening during a sync */
+ sync_collection_remove_all (collection);
+
+ G_OBJECT_CLASS (sync_collection_parent_class)->finalize (object);
+}
+
+static void
+sync_collection_class_init (SyncCollectionClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ signals[STARTED] =
+ g_signal_new ("started",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SyncCollectionClass, started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[PROGRESS] =
+ g_signal_new ("progress",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SyncCollectionClass, progress),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1, G_TYPE_DOUBLE);
+ signals[CONFLICT] =
+ g_signal_new ("conflict",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SyncCollectionClass, conflict),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 0, G_TYPE_OBJECT);
+ signals[FINISHED] =
+ g_signal_new ("finished",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SyncCollectionClass, finished),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ signals[FAILED] =
+ g_signal_new ("failed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (SyncCollectionClass, failed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ g_type_class_add_private (klass, sizeof (SyncCollectionPrivate));
+
+ object_class->finalize = sync_collection_finalize;
+}
+
+static void
+sync_collection_init (SyncCollection *self)
+{
+}
+
+SyncCollection*
+sync_collection_new (void)
+{
+ return g_object_new (SYNC_TYPE_COLLECTION, NULL);
+}
+
+static void
+sync_collection_namespace_func (gpointer data, gpointer user_data)
+{
+ SyncCollectionGroup *col_group = data;
+ const gchar *namespace = user_data;
+
+ sync_group_set_namespace (col_group->group, namespace);
+}
+
+static void
+sync_collection_start_func (gpointer data, gpointer user_data)
+{
+ SyncCollectionGroup *col_group = data;
+ gboolean *success = user_data;
+
+ if (!sync_group_start (col_group->group))
+ *success = FALSE;
+}
+
+static void
+sync_collection_abort_func (gpointer data, gpointer user_data)
+{
+ SyncCollectionGroup *col_group = data;
+
+ sync_group_abort (col_group->group);
+}
+
+static void
+sync_collection_save_func (gpointer data, gpointer user_data)
+{
+ SyncCollectionGroup *col_group = data;
+ gboolean *success = user_data;
+
+ if (!sync_group_save (col_group->group))
+ *success = FALSE;
+}
+
+static void
+sync_collection_delete_func (gpointer data, gpointer user_data)
+{
+ SyncCollectionGroup *col_group = data;
+ gboolean *success = user_data;
+
+ if (!sync_group_delete (col_group->group))
+ *success = FALSE;
+}
+
+static gint
+sync_collection_find_func (gconstpointer a, gconstpointer b)
+{
+ const SyncCollectionGroup *col_group = a;
+ const SyncGroup *group = b;
+
+ if (col_group->group == group) return 0;
+ else return -1;
+}
+
+static void
+sync_collection_started_cb (SyncGroup *group, SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ if (!priv->started) {
+ priv->started = TRUE;
+ g_signal_emit (collection, signals[STARTED], 0);
+ }
+}
+
+static void
+sync_collection_progress_cb (SyncGroup *group, gdouble progress,
+ SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ SyncCollectionGroup *col_group = (SyncCollectionGroup *)
+ ((g_list_find_custom (priv->groups, group,
+ sync_collection_find_func))->data);
+
+ priv->progress -= col_group->progress;
+ col_group->progress = progress;
+ priv->progress += col_group->progress;
+
+ g_signal_emit (collection, signals[PROGRESS], 0,
+ priv->progress / (gdouble)priv->num_groups);
+}
+
+static void
+sync_collection_conflict_cb (SyncGroup *group, SyncCollection *collection)
+{
+ g_signal_emit (collection, signals[CONFLICT], 0, group);
+}
+
+static void
+sync_collection_finished (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ priv->num_finished ++;
+ if (priv->num_finished == priv->num_groups) {
+ GList *c;
+ gchar *error = NULL;
+ for (c = priv->groups; c; c = c->next) {
+ gchar *new_error;
+ SyncCollectionGroup *col_group = c->data;
+
+ col_group->progress = 0;
+ if (!col_group->error) continue;
+
+ if (!error) {
+ error = g_strdup (col_group->error);
+ continue;
+ }
+ new_error = g_strconcat (error, "\n",
+ col_group->error, NULL);
+ g_free (error);
+ error = new_error;
+
+ g_free (col_group->error);
+ col_group->error = NULL;
+ }
+ priv->num_finished = 0;
+ priv->progress = 0;
+ priv->started = FALSE;
+ if (!error) {
+ g_signal_emit (collection, signals[FINISHED], 0);
+ } else {
+ g_signal_emit (collection, signals[FAILED], 0, error);
+ g_free (error);
+ }
+ }
+}
+
+static void
+sync_collection_finished_cb (SyncGroup *group, SyncCollection *collection)
+{
+ sync_collection_finished (collection);
+}
+
+static void
+sync_collection_failed_cb (SyncGroup *group, const gchar *error,
+ SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ SyncCollectionGroup *col_group = (SyncCollectionGroup *)
+ ((g_list_find_custom (priv->groups, group,
+ sync_collection_find_func))->data);
+
+ col_group->error = g_strdup (error);
+ sync_collection_finished (collection);
+}
+
+static SyncCollectionGroup *
+sync_collection_group_new (SyncCollection *collection, SyncGroup *group)
+{
+ SyncCollectionGroup *col_group = g_new0 (SyncCollectionGroup, 1);
+ col_group->group = g_object_ref (group);
+
+ g_signal_connect (G_OBJECT (group), "started",
+ G_CALLBACK (sync_collection_started_cb), collection);
+ g_signal_connect (G_OBJECT (group), "progress",
+ G_CALLBACK (sync_collection_progress_cb), collection);
+ g_signal_connect (G_OBJECT (group), "conflict",
+ G_CALLBACK (sync_collection_conflict_cb), collection);
+ g_signal_connect (G_OBJECT (group), "finished",
+ G_CALLBACK (sync_collection_finished_cb), collection);
+ g_signal_connect (G_OBJECT (group), "failed",
+ G_CALLBACK (sync_collection_failed_cb), collection);
+
+ return col_group;
+}
+
+static void
+sync_collection_group_free (SyncCollection *collection,
+ SyncCollectionGroup *col_group)
+{
+ g_signal_handlers_disconnect_by_func (
+ col_group->group, sync_collection_started_cb, collection);
+ g_signal_handlers_disconnect_by_func (
+ col_group->group, sync_collection_progress_cb, collection);
+ g_signal_handlers_disconnect_by_func (
+ col_group->group, sync_collection_conflict_cb, collection);
+ g_signal_handlers_disconnect_by_func (
+ col_group->group, sync_collection_finished_cb, collection);
+ g_signal_handlers_disconnect_by_func (
+ col_group->group, sync_collection_failed_cb, collection);
+
+ g_object_unref (col_group->group);
+ g_free (col_group->error);
+ g_free (col_group);
+}
+
+void
+sync_collection_add_group (SyncCollection *collection,
+ SyncGroup *group)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ priv->groups = g_list_prepend (priv->groups, sync_collection_group_new (
+ collection, group));
+ priv->num_groups ++;
+}
+
+void
+sync_collection_set_namespace (SyncCollection *collection,
+ const gchar *namespace)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ g_list_foreach (priv->groups,
+ sync_collection_namespace_func, (gpointer)namespace);
+}
+
+GList *
+sync_collection_get_groups (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ return g_list_copy (priv->groups);
+}
+
+gboolean
+sync_collection_start (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ gboolean success = TRUE;
+
+ g_list_foreach (priv->groups,
+ sync_collection_start_func, &success);
+
+ return success;
+}
+
+void
+sync_collection_abort (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ g_list_foreach (priv->groups,
+ sync_collection_abort_func, collection);
+}
+
+void
+sync_collection_remove_group (SyncCollection *collection,
+ SyncGroup *group)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ GList *col_group;
+
+ col_group = g_list_find_custom (
+ priv->groups, group, sync_collection_find_func);
+ if (col_group) {
+ sync_collection_group_free (collection, (SyncCollectionGroup *)
+ col_group->data);
+ priv->groups = g_list_delete_link (priv->groups, col_group);
+ }
+}
+
+void
+sync_collection_remove_all (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+
+ while (priv->groups) {
+ SyncCollectionGroup *col_group = priv->groups->data;
+
+ sync_collection_group_free (collection, col_group);
+ priv->groups = g_list_delete_link (priv->groups, priv->groups);
+ }
+}
+
+gboolean
+sync_collection_delete (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ gboolean success = TRUE;
+
+ g_list_foreach (priv->groups,
+ sync_collection_delete_func, &success);
+
+ return success;
+}
+
+gboolean
+sync_collection_save (SyncCollection *collection)
+{
+ SyncCollectionPrivate *priv = COLLECTION_PRIVATE (collection);
+ gboolean success = TRUE;
+
+ g_list_foreach (priv->groups,
+ sync_collection_save_func, &success);
+
+ return success;
+}
+
diff --git a/sync/src/sync_collection.h b/sync/src/sync_collection.h
new file mode 100644
index 0000000..8550baf
--- /dev/null
+++ b/sync/src/sync_collection.h
@@ -0,0 +1,67 @@
+
+#ifndef SYNC_COLLECTION_H
+#define SYNC_COLLECTION_H
+
+#include <glib-object.h>
+#include "sync_group.h"
+
+G_BEGIN_DECLS
+
+#define SYNC_TYPE_COLLECTION sync_collection_get_type()
+
+#define SYNC_COLLECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ SYNC_TYPE_COLLECTION, SyncCollection))
+
+#define SYNC_COLLECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ SYNC_TYPE_COLLECTION, SyncCollectionClass))
+
+#define SYNC_IS_COLLECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ SYNC_TYPE_COLLECTION))
+
+#define SYNC_IS_COLLECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ SYNC_TYPE_COLLECTION))
+
+#define SYNC_COLLECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ SYNC_TYPE_COLLECTION, SyncCollectionClass))
+
+typedef struct {
+ GObject parent;
+} SyncCollection;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ void (* started) (SyncCollection *collection);
+ void (* progress) (SyncCollection *collection, gdouble progress);
+ void (* conflict) (SyncCollection *collection, SyncGroup *group);
+ void (* finished) (SyncCollection *collection);
+ void (* failed) (SyncCollection *collection);
+} SyncCollectionClass;
+
+GType sync_collection_get_type (void);
+
+SyncCollection* sync_collection_new (void);
+
+void sync_collection_add_group (SyncCollection *collection,
+ SyncGroup *group);
+void sync_collection_set_namespace (SyncCollection *collection,
+ const gchar *namespace);
+GList * sync_collection_get_groups (SyncCollection *collection);
+gboolean sync_collection_start (SyncCollection *collection);
+void sync_collection_resolve_conflict(SyncCollection *collection,
+ SyncGroupConflictRes res);
+void sync_collection_abort (SyncCollection *collection);
+void sync_collection_remove_group (SyncCollection *collection,
+ SyncGroup *group);
+void sync_collection_remove_all (SyncCollection *collection);
+gboolean sync_collection_delete (SyncCollection *collection);
+gboolean sync_collection_save (SyncCollection *collection);
+
+G_END_DECLS
+
+#endif
diff --git a/sync/src/sync_evo2_item.c b/sync/src/sync_evo2_item.c
index 19666b9..ae28009 100644
--- a/sync/src/sync_evo2_item.c
+++ b/sync/src/sync_evo2_item.c
@@ -20,15 +20,14 @@ typedef struct {
} SyncEvo2ItemData;
static OSyncMember *
-sync_evo2_item_get_member (SyncItem *item)
+sync_evo2_item_get_member (SyncItem *item, SyncGroup *group)
{
OSyncMember *member;
OSyncError *error = NULL;
OSyncConfigurationTypes type = NO_CONFIGURATION;
/* Setup Evolution2 sync member */
- member = osync_member_new (sync_group_get_osync_group (
- sync_item_get_group (item)));
+ member = osync_member_new (sync_group_get_osync_group (group));
if (!osync_member_instance_plugin (member, EVO2_PLUGIN, &error)) {
g_warning ("Error instancing Evolution2 plug-in: %s",
osync_error_print (&error));
diff --git a/sync/src/sync_file_item.c b/sync/src/sync_file_item.c
index 132c4de..56f2261 100644
--- a/sync/src/sync_file_item.c
+++ b/sync/src/sync_file_item.c
@@ -13,14 +13,13 @@
"</config>"
static OSyncMember *
-sync_file_item_get_member (SyncItem *item)
+sync_file_item_get_member (SyncItem *item, SyncGroup *group)
{
OSyncMember *member;
OSyncError *error = NULL;
OSyncConfigurationTypes type = NO_CONFIGURATION;
- member = osync_member_new (sync_group_get_osync_group (
- sync_item_get_group (item)));
+ member = osync_member_new (sync_group_get_osync_group (group));
if (!osync_member_instance_plugin (member, FILE_PLUGIN, &error)) {
g_warning ("Error instancing file plug-in: %s",
osync_error_print (&error));
diff --git a/sync/src/sync_group.c b/sync/src/sync_group.c
index 284eb2f..d741ed3 100644
--- a/sync/src/sync_group.c
+++ b/sync/src/sync_group.c
@@ -227,12 +227,12 @@ sync_group_set_item1 (SyncGroup *group, SyncItem *item1)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
- if (priv->item1)
- sync_item_ungroup (priv->item1);
- if (item1) {
- priv->item1 = g_object_ref_sink (item1);
- sync_item_set_group (item1, group);
+ if (priv->item1) {
+ g_object_unref (priv->item1);
+ priv->item1 = NULL;
}
+ if (item1)
+ priv->item1 = g_object_ref (item1);
}
void
@@ -240,12 +240,12 @@ sync_group_set_item2 (SyncGroup *group, SyncItem *item2)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
- if (priv->item2)
- sync_item_ungroup (priv->item2);
- if (item2) {
- priv->item2 = g_object_ref_sink (item2);
- sync_item_set_group (item2, group);
+ if (priv->item2) {
+ g_object_unref (priv->item2);
+ priv->item2 = NULL;
}
+ if (item2)
+ priv->item2 = g_object_ref (item2);
}
void sync_group_set_namespace (SyncGroup *group, const gchar *namespace)
@@ -315,23 +315,11 @@ gchar *sync_group_get_name (SyncGroup *group)
gboolean
sync_group_delete (SyncGroup *group)
{
- SyncGroupPrivate *priv = GROUP_PRIVATE (group);
OSyncEnv *env;
OSyncGroup *os_group;
OSyncError *error = NULL;
gchar *name;
- SyncItem *item1 = NULL;
- SyncItem *item2 = NULL;
- if (priv->item1) {
- item1 = g_object_ref (priv->item1);
- sync_item_ungroup (priv->item1);
- }
- if (priv->item2) {
- item2 = g_object_ref (priv->item2);
- sync_item_ungroup (priv->item2);
- }
-
env = sync_group_get_default_env ();
name = sync_group_get_name (group);
os_group = osync_env_find_group (env, name);
@@ -345,15 +333,6 @@ sync_group_delete (SyncGroup *group)
return FALSE;
}
- if (item1) {
- sync_group_set_item1 (group, item1);
- g_object_unref (item1);
- }
- if (item2) {
- sync_group_set_item2 (group, item2);
- g_object_unref (item2);
- }
-
return TRUE;
}
@@ -403,8 +382,8 @@ sync_group_get_osync_group (SyncGroup *group)
osync_group_set_name (priv->group, name);
/* Create OSyncMembers (adds them to group) */
- sync_item_get_member (priv->item1);
- sync_item_get_member (priv->item2);
+ sync_item_create_member (priv->item1, group);
+ sync_item_create_member (priv->item2, group);
}
g_free (name);
@@ -814,50 +793,16 @@ sync_group_abort (SyncGroup *group)
else g_warning ("%s called, but no sync in progress", G_STRFUNC);
}
-static void
-sync_group_regroup (SyncGroup *group, gboolean item1, gboolean item2)
-{
- SyncGroupPrivate *priv = GROUP_PRIVATE (group);
-
- /* Regroup items so their members can be recreated */
- if (priv->group) {
- SyncItem *item;
-
- /* Freeing groups with OpenSync removes them from the env */
- priv->group = NULL;
-
- if (item1) {
- item = g_object_ref (priv->item1);
- sync_item_ungroup (priv->item1);
- sync_group_set_item1 (group, item);
- g_object_unref (item);
- }
- if (item2) {
- item = g_object_ref (priv->item2);
- sync_item_ungroup (priv->item2);
- sync_group_set_item2 (group, item);
- g_object_unref (item);
- }
- }
-}
-
void sync_group_remove_item (SyncGroup *group,
SyncItem *item)
{
SyncGroupPrivate *priv = GROUP_PRIVATE (group);
- gboolean item1;
if (priv->item1 == item) {
- sync_group_regroup (group, FALSE, TRUE);
- priv->item1 = NULL;
- g_object_unref (item);
- item1 = TRUE;
+ sync_group_set_item1 (group, NULL);
} else if (priv->item2 == item) {
- sync_group_regroup (group, TRUE, FALSE);
- priv->item2 = NULL;
- g_object_unref (item);
+ sync_group_set_item2 (group, NULL);
} else {
g_warning ("%s called on group not containing item", G_STRFUNC);
- return;
}
}
diff --git a/sync/src/sync_item.c b/sync/src/sync_item.c
index 324972c..4565749 100644
--- a/sync/src/sync_item.c
+++ b/sync/src/sync_item.c
@@ -4,7 +4,7 @@
#include "sync_item.h"
#include "sync_group.h"
-G_DEFINE_TYPE (SyncItem, sync_item, G_TYPE_INITIALLY_UNOWNED);
+G_DEFINE_TYPE (SyncItem, sync_item, G_TYPE_OBJECT);
#define ITEM_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), SYNC_TYPE_ITEM, SyncItemPrivate))
@@ -17,7 +17,6 @@ enum {
PROP_DATA,
PROP_DATA_FREE_FUNC,
PROP_MEMBER_FUNC,
- PROP_GROUP,
};
struct _SyncItemPrivate
@@ -27,8 +26,6 @@ struct _SyncItemPrivate
gpointer data;
SyncItemMemberFunc get_member;
SyncItemDataFreeFunc free_data;
- SyncGroup *group;
- OSyncMember *member;
};
static void
@@ -70,10 +67,6 @@ sync_item_set_property (GObject *object,
sync_item_set_member_func (
item, g_value_get_pointer (value));
break;
- case PROP_GROUP :
- sync_item_set_group (item,
- SYNC_GROUP (g_value_get_object (value)));
- break;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
@@ -107,10 +100,6 @@ sync_item_get_property (GObject *object,
g_value_set_pointer (
value, sync_item_get_member_func (item));
break;
- case PROP_GROUP :
- g_value_set_object (
- value, sync_item_get_group (item));
- break;
default :
G_OBJECT_WARN_INVALID_PROPERTY_ID (
object, prop_id, pspec);
@@ -168,15 +157,6 @@ sync_item_class_init (SyncItemClass *klass)
("Member Function"),
("Function pointer to retrieve OSyncMember."),
G_PARAM_READWRITE));
- g_object_class_install_property (
- object_class,
- PROP_GROUP,
- g_param_spec_object (
- "group",
- ("SyncGroup"),
- ("SyncGroup this item belongs to."),
- SYNC_TYPE_GROUP,
- G_PARAM_READWRITE));
g_type_class_add_private (klass, sizeof (SyncItemPrivate));
@@ -236,26 +216,11 @@ sync_item_get_member_func (SyncItem *item)
}
OSyncMember *
-sync_item_get_member (SyncItem *item)
+sync_item_create_member (SyncItem *item, SyncGroup *group)
{
SyncItemPrivate *priv = ITEM_PRIVATE (item);
- if (!priv->group) {
- g_warning ("%s called on SyncItem with no group", G_STRFUNC);
- return NULL;
- }
-
- if (!priv->member)
- priv->member = priv->get_member (item);
-
- return priv->member;
-}
-
-SyncGroup *
-sync_item_get_group (SyncItem *item)
-{
- SyncItemPrivate *priv = ITEM_PRIVATE (item);
- return priv->group;
+ return priv->get_member (item, group);
}
void
@@ -296,29 +261,3 @@ sync_item_set_member_func (SyncItem *item,
SyncItemPrivate *priv = ITEM_PRIVATE (item);
priv->get_member = member_func;
}
-
-void
-sync_item_set_group (SyncItem *item, SyncGroup *group)
-{
- SyncItemPrivate *priv = ITEM_PRIVATE (item);
- if (priv->group) {
- g_warning ("SyncItem already contained in a group");
- return;
- }
- priv->group = group;
-}
-
-void
-sync_item_ungroup (SyncItem *item)
-{
- SyncItemPrivate *priv = ITEM_PRIVATE (item);
- if (priv->group) {
- /* Removing the item from the group frees the group, which in
- * turn frees the member.
- */
- sync_group_remove_item (priv->group, item);
- priv->group = NULL;
- priv->member = NULL;
- } else
- g_warning ("%s called on SyncItem with no group", G_STRFUNC);
-}
diff --git a/sync/src/sync_item.h b/sync/src/sync_item.h
index f7a4930..87cdfbc 100644
--- a/sync/src/sync_item.h
+++ b/sync/src/sync_item.h
@@ -38,21 +38,20 @@ typedef struct {
GObjectClass parent_class;
} SyncItemClass;
-typedef OSyncMember * (*SyncItemMemberFunc) (SyncItem *item);
-typedef void (*SyncItemDataFreeFunc) (gpointer data);
-
GType sync_item_get_type (void);
#include "sync_group.h"
+typedef OSyncMember * (*SyncItemMemberFunc) (SyncItem *item,
+ SyncGroup *group);
+typedef void (*SyncItemDataFreeFunc) (gpointer data);
+
SyncItem * sync_item_new (const gchar * name,
const gchar * adr,
SyncItemMemberFunc member_func);
const gchar * sync_item_get_name (SyncItem * item);
const gchar * sync_item_get_adr (SyncItem * item);
gpointer sync_item_get_data (SyncItem * item);
-OSyncMember * sync_item_get_member (SyncItem * item);
-SyncGroup * sync_item_get_group (SyncItem * item);
SyncItemDataFreeFunc sync_item_get_data_free_func (SyncItem * item);
SyncItemMemberFunc sync_item_get_member_func (SyncItem * item);
@@ -67,10 +66,9 @@ void sync_item_set_data_free_func (SyncItem * item,
SyncItemDataFreeFunc data_free_func);
void sync_item_set_member_func (SyncItem * item,
SyncItemMemberFunc member_func);
-void sync_item_set_group (SyncItem * item,
- SyncGroup * group);
-void sync_item_ungroup (SyncItem * item);
+OSyncMember * sync_item_create_member (SyncItem * item,
+ SyncGroup * group);
G_END_DECLS
diff --git a/sync/src/sync_main.c b/sync/src/sync_main.c
index e3d2f1e..dcfbaa7 100644
--- a/sync/src/sync_main.c
+++ b/sync/src/sync_main.c
@@ -10,6 +10,7 @@
#include <osengine/engine.h>
#include "sync_main.h"
+#include "sync_collection.h"
#include "sync_group.h"
#include "sync_item.h"
#include "sync_evo2_item.h"
@@ -60,88 +61,6 @@ sync_clean_backup (SyncData *data)
return TRUE;
}
-
-static OSyncGroup *
-sync_get_backup_group (SyncData *data)
-{
- OSyncGroup *group;
- OSyncMember *member;
- OSyncError *error = NULL;
- OSyncConfigurationTypes type = NO_CONFIGURATION;
-
- if (!sync_clean_backup (data)) {
- g_warning ("Unable to clear old backup data\n");
- return NULL;
- }
-
- group = osync_group_new (data->osync);
- osync_group_set_name (group, BACKUP_GROUP);
-
- /* Setup Evolution2 sync member */
- member = osync_member_new (group);
- if (!osync_member_instance_plugin (member, EVO2_PLUGIN, &error)) {
- g_warning ("Error instancing Evolution2 plug-in: %s",
- osync_error_print (&error));
- osync_error_free (&error);
- return NULL;
- }
- if (!osync_member_need_config (member, &type, &error)) {
- g_warning ("Error reading plug-in config requirements: %s",
- osync_error_print (&error));
- osync_error_free (&error);
- return NULL;
- }
- if (type == NO_CONFIGURATION) {
- g_warning (
- "Evolution2 plug-in reports no need for configuration");
- } else {
- osync_member_set_config (
- member, EVO2_CONFIG, strlen (EVO2_CONFIG));
- }
-
- /* Setup File sync member */
- member = osync_member_new (group);
- if (!osync_member_instance_plugin (member, FILE_PLUGIN, &error)) {
- g_warning ("Error instancing file plug-in: %s",
- osync_error_print (&error));
- osync_error_free (&error);
- return NULL;
- }
- if (!osync_member_need_config (member, &type, &error)) {
- g_warning ("Error reading plug-in config requirements: %s",
- osync_error_print (&error));
- osync_error_free (&error);
- return NULL;
- }
- if (type == NO_CONFIGURATION) {
- g_warning (
- "File sync plug-in reports no need for configuration");
- } else {
- gchar *backup_config, *backup_path;
-
- backup_path = g_strdup_printf (BACKUP_PATH, g_getenv ("HOME"));
- if (g_mkdir_with_parents (backup_path, 0755) == -1) {
- g_warning ("Couldn't create backup directory");
- g_free (backup_path);
- return NULL;
- }
-
- backup_config = g_strdup_printf (FILE_CONFIG, backup_path);
- osync_member_set_config (
- member, backup_config, strlen (backup_config));
- g_free (backup_config);
- g_free (backup_path);
- }
-
- /* Save the group */
- if (!osync_group_save (group, &error)) {
- g_warning ("Error saving group: %s",
- osync_error_print (&error));
- osync_error_free (&error);
- }
-
- return group;
-}
#endif
static gboolean
@@ -185,7 +104,7 @@ sync_animate (SyncData *data)
}
static void
-sync_started_cb (SyncGroup *group, SyncData *data)
+sync_started_cb (SyncCollection *collection, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (
data->xml, "sync_progressbar");
@@ -202,7 +121,7 @@ sync_started_cb (SyncGroup *group, SyncData *data)
}
static void
-sync_progress_cb (SyncGroup *group, gdouble progress, SyncData *data)
+sync_progress_cb (SyncCollection *collection, gdouble progress, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (
data->xml, "sync_progressbar");
@@ -210,28 +129,31 @@ sync_progress_cb (SyncGroup *group, gdouble progress, SyncData *data)
}
static void
-sync_conflict_cb (SyncGroup *group, SyncData *data)
+sync_conflict_cb (SyncCollection *collection, SyncGroup *group, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (data->xml, "main_notebook");
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), TAB_CONFLICT);
+ data->group = group;
}
static void
-sync_finished_cb (SyncGroup *group, SyncData *data)
+sync_finished_cb (SyncCollection *collection, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (data->xml, "main_notebook");
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), TAB_SUCCESS);
g_source_remove (data->animate_id);
+ sync_collection_remove_all (collection);
}
static void
-sync_failed_cb (SyncGroup *group, const gchar *error, SyncData *data)
+sync_failed_cb (SyncCollection *collection, const gchar *error, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (data->xml, "main_notebook");
gtk_notebook_set_current_page (GTK_NOTEBOOK (widget), TAB_ERROR);
widget = glade_xml_get_widget (data->xml, "sync_error_label");
gtk_label_set_text (GTK_LABEL (widget), error);
g_source_remove (data->animate_id);
+ sync_collection_remove_all (collection);
}
gboolean
@@ -248,20 +170,76 @@ sync_item_activated_cb (GtkIconView *iconview, GtkTreePath *arg1,
if (gtk_tree_model_get_iter (
GTK_TREE_MODEL (data->model), &iter, arg1)) {
- SyncItem *item;
const gchar *name;
+ SyncType type;
GtkWidget *widget;
gfloat x, y;
gtk_tree_model_get (GTK_TREE_MODEL (data->model),
- &iter, COL_NAME, &name, -1);
-
- item = (SyncItem *)g_hash_table_lookup (data->sync_items, name);
+ &iter, COL_NAME, &name, COL_TYPE, &type, -1);
- sync_group_set_item2 (data->group, item);
+ switch (type) {
+ SyncItem *item;
+ SyncGroup *group;
+ gchar *path;
+
+ case TYPE_SYNCML:
+ /* Contacts SyncML item */
+ item = sync_syncml_item_new ("Mobical",
+ "http://www.mobical.net/sync/server",
+ CONTACTS, "Cwiiis", "2e9tp2", "con");
+ group = sync_group_new_with_items (
+ data->local_item, item);
+ sync_collection_add_group (data->collection,
+ group);
+ g_object_unref (group);
+ g_object_unref (item);
+
+ /* Events SyncML item */
+ item = sync_syncml_item_new ("Mobical",
+ "http://www.mobical.net/sync/server",
+ EVENTS, "Cwiiis", "2e9tp2", "cal");
+ group = sync_group_new_with_items (
+ data->local_item, item);
+ sync_collection_add_group (data->collection,
+ group);
+ g_object_unref (group);
+ g_object_unref (item);
+
+ /* Todo SyncML item */
+ item = sync_syncml_item_new ("Mobical",
+ "http://www.mobical.net/sync/server",
+ TODO, "Cwiiis", "2e9tp2", "task");
+ group = sync_group_new_with_items (
+ data->local_item, item);
+ sync_collection_add_group (data->collection,
+ group);
+ g_object_unref (group);
+ g_object_unref (item);
+
+ /* TODO: Check if notes sync works? */
+
+ break;
+ case TYPE_FILE:
+ path = g_strdup_printf (TEMP_PATH,
+ g_getenv ("HOME"));
+ item = sync_file_item_new ("Test", path);
+ g_free (path);
+
+ group = sync_group_new_with_items (
+ data->local_item, item);
+ sync_collection_add_group (data->collection,
+ group);
+ g_object_unref (group);
+ g_object_unref (item);
+ break;
+ default:
+ return;
+ }
+
data->started = FALSE;
- if (!sync_group_start (data->group)) {
+ if (!sync_collection_start (data->collection)) {
/* Switch to error tab */
widget = glade_xml_get_widget (
data->xml, "main_notebook");
@@ -312,7 +290,7 @@ sync_abort_cb (GtkWidget *source, SyncData *data)
{
GtkWidget *widget = glade_xml_get_widget (data->xml, "cancel_button");
gtk_widget_set_sensitive (widget, FALSE);
- sync_group_abort (data->group);
+ sync_collection_abort (data->collection);
}
void
@@ -389,8 +367,6 @@ main (int argc, char **argv)
GtkIconTheme *icon_theme;
gint width = 0, height = 0;
SyncData data;
- SyncItem *preset_item;
- gchar *temp_path;
gtk_init (&argc, &argv);
glade_init ();
@@ -415,43 +391,44 @@ main (int argc, char **argv)
data.network_icon = gtk_icon_theme_load_icon (icon_theme,
GTK_STOCK_NETWORK, MIN (width, height),
GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ data.add_icon = gtk_icon_theme_load_icon (icon_theme,
+ GTK_STOCK_ADD, MIN (width, height),
+ GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
/* Setup icon-view */
widget = glade_xml_get_widget (data.xml, "main_iconview");
data.model = gtk_list_store_new (
- 2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+ 3, G_TYPE_STRING, G_TYPE_INT, GDK_TYPE_PIXBUF);
gtk_icon_view_set_model (GTK_ICON_VIEW (widget),
GTK_TREE_MODEL (data.model));
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (widget), COL_PIXBUF);
gtk_icon_view_set_text_column (GTK_ICON_VIEW (widget), COL_NAME);
- /* Create local sync-item and sync group */
+ /* Create local sync-item and sync collection */
+ data.collection = sync_collection_new ();
data.local_item = sync_evo2_item_new ("Local", NULL, NULL, NULL);
- data.group = sync_group_new_with_items (data.local_item, NULL);
- /* Create SyncItem hash-table */
- data.sync_items = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, g_object_unref);
+ /* Insert some items for testing (TODO: look at loading groups later) */
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
+ G_MAXINT, COL_NAME, "SyncML Test", COL_TYPE, TYPE_SYNCML,
+ COL_PIXBUF, data.network_icon, -1);
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
+ G_MAXINT, COL_NAME, "File Test", COL_TYPE, TYPE_FILE,
+ COL_PIXBUF, data.backup_icon, -1);
+
/* Insert preset items */
- temp_path = g_strdup_printf (TEMP_PATH, g_getenv ("HOME"));
- preset_item = g_object_ref (sync_file_item_new ("Test", temp_path));
- g_hash_table_insert (data.sync_items, "Test", preset_item);
gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
- 0, COL_NAME, "Test", COL_PIXBUF, data.backup_icon, -1);
- g_free (temp_path);
-
- preset_item = g_object_ref (sync_syncml_item_new ("Mobical",
- "http://www.mobical.net/sync/server", CONTACTS,
- "guest", "guest", "con"));
- g_hash_table_insert (data.sync_items, "Mobical", preset_item);
+ G_MAXINT, COL_NAME, "Backup", COL_TYPE, TYPE_BACKUP,
+ COL_PIXBUF, data.backup_icon, -1);
+ gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
+ G_MAXINT, COL_NAME, "Restore", COL_TYPE, TYPE_RESTORE,
+ COL_PIXBUF, data.restore_icon, -1);
gtk_list_store_insert_with_values (GTK_LIST_STORE (data.model), &iter,
- 0, COL_NAME, "Mobical", COL_PIXBUF, data.network_icon, -1);
+ G_MAXINT, COL_NAME, "Add target...", COL_TYPE, TYPE_ADD_NEW,
+ COL_PIXBUF, data.add_icon, -1);
- /* TODO: Insert saved items */
- /* TODO: Avahi detection of local sync servers */
+ /* TODO: Avahi detection of local sync servers? */
/* TODO: Bluetooth scanning? */
- /* Insert backup item */
- /* Insert restore item */
/* Select first item */
path = gtk_tree_path_new_first ();
@@ -462,16 +439,16 @@ main (int argc, char **argv)
/* Connect signals */
glade_xml_signal_autoconnect_full (data.xml, dates_autoconnect, &data);
- /* Connect SyncGroup signals */
- g_signal_connect (G_OBJECT (data.group), "started",
+ /* Connect SyncCollection signals */
+ g_signal_connect (G_OBJECT (data.collection), "started",
G_CALLBACK (sync_started_cb), &data);
- g_signal_connect (G_OBJECT (data.group), "progress",
+ g_signal_connect (G_OBJECT (data.collection), "progress",
G_CALLBACK (sync_progress_cb), &data);
- g_signal_connect (G_OBJECT (data.group), "conflict",
+ g_signal_connect (G_OBJECT (data.collection), "conflict",
G_CALLBACK (sync_conflict_cb), &data);
- g_signal_connect (G_OBJECT (data.group), "finished",
+ g_signal_connect (G_OBJECT (data.collection), "finished",
G_CALLBACK (sync_finished_cb), &data);
- g_signal_connect (G_OBJECT (data.group), "failed",
+ g_signal_connect (G_OBJECT (data.collection), "failed",
G_CALLBACK (sync_failed_cb), &data);
gtk_main ();
diff --git a/sync/src/sync_main.h b/sync/src/sync_main.h
index 528b70e..1f8e7c7 100644
--- a/sync/src/sync_main.h
+++ b/sync/src/sync_main.h
@@ -5,6 +5,7 @@
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <opensync/opensync.h>
+#include "sync_collection.h"
#include "sync_group.h"
#include "sync_item.h"
@@ -15,8 +16,18 @@
#define ANIM_FREQ 100
#define SWITCH_FREQ 10
+typedef enum {
+ TYPE_FILE,
+ TYPE_EVO2,
+ TYPE_SYNCML,
+ TYPE_ADD_NEW,
+ TYPE_BACKUP,
+ TYPE_RESTORE,
+} SyncType;
+
enum {
COL_NAME,
+ COL_TYPE,
COL_PIXBUF,
};
@@ -38,10 +49,11 @@ typedef struct {
GdkPixbuf *backup_icon;
GdkPixbuf *restore_icon;
GdkPixbuf *network_icon;
+ GdkPixbuf *add_icon;
GtkListStore *model;
- SyncItem *local_item;
+ SyncCollection *collection;
SyncGroup *group;
- GHashTable *sync_items;
+ SyncItem *local_item;
gboolean started;
guint animate_id;
diff --git a/sync/src/sync_syncml_item.c b/sync/src/sync_syncml_item.c
index 0e57959..239332d 100644
--- a/sync/src/sync_syncml_item.c
+++ b/sync/src/sync_syncml_item.c
@@ -115,16 +115,14 @@ sync_syncml_type_to_source_string (SyncSyncMLType type)
}
static OSyncMember *
-sync_syncml_item_get_member (SyncItem *item)
+sync_syncml_item_get_member (SyncItem *item, SyncGroup *group)
{
OSyncMember *member;
OSyncError *error = NULL;
OSyncConfigurationTypes type = NO_CONFIGURATION;
- SyncGroup *group;
OSyncGroup *os_group;
/* Setup SyncML sync member */
- group = sync_item_get_group (item);
os_group = sync_group_get_osync_group (group);
member = osync_member_new (os_group);
if (!osync_member_instance_plugin (member, SYNCML_PLUGIN, &error)) {