diff options
-rw-r--r-- | sync/ChangeLog | 29 | ||||
-rw-r--r-- | sync/src/Makefile.am | 3 | ||||
-rw-r--r-- | sync/src/sync_collection.c | 406 | ||||
-rw-r--r-- | sync/src/sync_collection.h | 67 | ||||
-rw-r--r-- | sync/src/sync_evo2_item.c | 5 | ||||
-rw-r--r-- | sync/src/sync_file_item.c | 5 | ||||
-rw-r--r-- | sync/src/sync_group.c | 83 | ||||
-rw-r--r-- | sync/src/sync_item.c | 67 | ||||
-rw-r--r-- | sync/src/sync_item.h | 14 | ||||
-rw-r--r-- | sync/src/sync_main.c | 223 | ||||
-rw-r--r-- | sync/src/sync_main.h | 16 | ||||
-rw-r--r-- | sync/src/sync_syncml_item.c | 4 |
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)) { |