diff options
author | Martyn Russell <martyn@lanedo.com> | 2011-02-09 10:53:36 +0000 |
---|---|---|
committer | Martyn Russell <martyn@lanedo.com> | 2011-02-09 10:53:36 +0000 |
commit | 1fca084bd3e55ccd3712b43207cc1dec9f31ff39 (patch) | |
tree | 2a97142386c410382fde28851e98f506c393d05d | |
parent | 42c43a37eb0ff8086660d94fa8708e12d1296cf6 (diff) | |
parent | 4b30c6797f13d3c960b4b6924f389f9d7ee1d78b (diff) | |
download | tracker-1fca084bd3e55ccd3712b43207cc1dec9f31ff39.tar.gz |
Merge branch 'nautilus-extension-update'
-rw-r--r-- | src/plugins/nautilus/Makefile.am | 2 | ||||
-rw-r--r-- | src/plugins/nautilus/tracker-tags-extension.c | 66 | ||||
-rw-r--r-- | src/plugins/nautilus/tracker-tags-utils.c | 94 | ||||
-rw-r--r-- | src/plugins/nautilus/tracker-tags-view.c | 561 |
4 files changed, 427 insertions, 296 deletions
diff --git a/src/plugins/nautilus/Makefile.am b/src/plugins/nautilus/Makefile.am index c1e34b8df..9581fd81d 100644 --- a/src/plugins/nautilus/Makefile.am +++ b/src/plugins/nautilus/Makefile.am @@ -19,6 +19,6 @@ libnautilus_tracker_tags_la_SOURCES = \ libnautilus_tracker_tags_la_LDFLAGS = -module -avoid-version libnautilus_tracker_tags_la_LIBADD = \ - $(top_builddir)/src/libtracker-client/libtracker-client-@TRACKER_API_VERSION@.la \ + $(top_builddir)/src/libtracker-sparql/libtracker-sparql-@TRACKER_API_VERSION@.la \ $(BUILD_LIBS) \ $(TRACKER_NAUTILUS_EXTENSION_LIBS) diff --git a/src/plugins/nautilus/tracker-tags-extension.c b/src/plugins/nautilus/tracker-tags-extension.c index ae85ac4b3..6331667b9 100644 --- a/src/plugins/nautilus/tracker-tags-extension.c +++ b/src/plugins/nautilus/tracker-tags-extension.c @@ -26,7 +26,7 @@ #include <libnautilus-extension/nautilus-menu-provider.h> #include <libnautilus-extension/nautilus-property-page-provider.h> -#include <libtracker-client/tracker-client.h> +#include <libtracker-sparql/tracker-sparql.h> #include "tracker-tags-utils.h" #include "tracker-tags-view.h" @@ -34,28 +34,21 @@ #define TRACKER_TYPE_TAGS_EXTENSION (tracker_tags_extension_get_type ()) #define TRACKER_TAGS_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_TAGS_EXTENSION, TrackerTagsExtension)) #define TRACKER_TAGS_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRACKER_TYPE_TAGS_EXTENSION, TrackerTagsExtensionClass)) -#define TRACKER_TAGS_EXTENSION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TRACKER_TYPE_TAGS_EXTENSION, TrackerTagsExtensionPrivate)) #define TRACKER_IS_TAGS_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_TAGS_EXTENSION)) #define TRACKER_IS_TAGS_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRACKER_TYPE_TAGS_EXTENSION)) -typedef struct _TrackerTagsExtensionPrivate TrackerTagsExtensionPrivate; typedef struct _TrackerTagsExtension TrackerTagsExtension; typedef struct _TrackerTagsExtensionClass TrackerTagsExtensionClass; struct _TrackerTagsExtension { GObject parent; - TrackerTagsExtensionPrivate *private; }; struct _TrackerTagsExtensionClass { GObjectClass parent; }; -struct _TrackerTagsExtensionPrivate { - TrackerClient *tracker_client; -}; - typedef void (*MenuDataFreeFunc)(gpointer data); typedef struct { @@ -67,7 +60,6 @@ typedef struct { static void tracker_tags_extension_menu_provider_iface_init (NautilusMenuProviderIface *iface); static void tracker_tags_extension_property_page_provider_iface_init (NautilusPropertyPageProviderIface *iface); static GType tracker_tags_extension_get_type (void); -static void tracker_tags_extension_finalize (GObject *object); G_DEFINE_DYNAMIC_TYPE_EXTENDED (TrackerTagsExtension, tracker_tags_extension, G_TYPE_OBJECT, 0, G_IMPLEMENT_INTERFACE (NAUTILUS_TYPE_MENU_PROVIDER, @@ -110,7 +102,7 @@ menu_data_destroy (gpointer data, } static void -menu_tags_activate_cb (NautilusMenuItem *menu_item, +menu_tags_activate_cb (NautilusMenuItem *menu_item, gpointer user_data) { MenuData *md = user_data; @@ -123,8 +115,8 @@ menu_tags_activate_cb (NautilusMenuItem *menu_item, dialog = gtk_dialog_new_with_buttons (N_("Tags"), window, - GTK_DIALOG_MODAL | - GTK_DIALOG_DESTROY_WITH_PARENT | + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT | #if GTK_CHECK_VERSION (2,90,7) 0, #else @@ -137,8 +129,8 @@ menu_tags_activate_cb (NautilusMenuItem *menu_item, gtk_window_set_default_size (GTK_WINDOW (dialog), 250, 375); gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); gtk_window_set_transient_for (GTK_WINDOW (dialog), window); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); action_area = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); @@ -172,13 +164,13 @@ extension_get_background_items (NautilusMenuProvider *provider, } menu_item = nautilus_menu_item_new ("tracker-tags-new", - N_("Tags..."), - N_("Tag one or more files"), - NULL); + N_("Tags..."), + N_("Tag one or more files"), + NULL); menu_items = g_list_append (menu_items, menu_item); - g_signal_connect_data (menu_item, "activate", - G_CALLBACK (menu_tags_activate_cb), + g_signal_connect_data (menu_item, "activate", + G_CALLBACK (menu_tags_activate_cb), menu_data_new (provider, FALSE, window), menu_data_destroy, G_CONNECT_AFTER); @@ -199,13 +191,13 @@ extension_get_file_items (NautilusMenuProvider *provider, } menu_item = nautilus_menu_item_new ("tracker-tags-new", - N_("Tags..."), - N_("Tag one or more files"), - NULL); + N_("Tags..."), + N_("Tag one or more files"), + NULL); menu_items = g_list_append (menu_items, menu_item); - g_signal_connect_data (menu_item, "activate", - G_CALLBACK (menu_tags_activate_cb), + g_signal_connect_data (menu_item, "activate", + G_CALLBACK (menu_tags_activate_cb), menu_data_new (tracker_glist_copy_with_nautilus_files (files), TRUE, window), menu_data_destroy, G_CONNECT_AFTER); @@ -245,12 +237,12 @@ extension_get_pages (NautilusPropertyPageProvider *provider, static void tracker_tags_extension_menu_provider_iface_init (NautilusMenuProviderIface *iface) { - iface->get_file_items = extension_get_file_items; - iface->get_toolbar_items = extension_get_toolbar_items; + iface->get_file_items = extension_get_file_items; + iface->get_toolbar_items = extension_get_toolbar_items; - if (0) { - iface->get_background_items = extension_get_background_items; - } + if (0) { + iface->get_background_items = extension_get_background_items; + } } static void @@ -262,10 +254,6 @@ tracker_tags_extension_property_page_provider_iface_init (NautilusPropertyPagePr static void tracker_tags_extension_class_init (TrackerTagsExtensionClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = tracker_tags_extension_finalize; - g_type_class_add_private (gobject_class, sizeof (TrackerTagsExtensionPrivate)); } static void @@ -276,18 +264,6 @@ tracker_tags_extension_class_finalize (TrackerTagsExtensionClass *klass) static void tracker_tags_extension_init (TrackerTagsExtension *self) { - self->private = TRACKER_TAGS_EXTENSION_GET_PRIVATE (self); - self->private->tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT); -} - -static void -tracker_tags_extension_finalize (GObject *object) -{ - TrackerTagsExtension *extension = TRACKER_TAGS_EXTENSION (object); - - g_object_unref (extension->private->tracker_client); - - G_OBJECT_CLASS (tracker_tags_extension_parent_class)->finalize (object); } void diff --git a/src/plugins/nautilus/tracker-tags-utils.c b/src/plugins/nautilus/tracker-tags-utils.c index 62c80d5c0..898894d6a 100644 --- a/src/plugins/nautilus/tracker-tags-utils.c +++ b/src/plugins/nautilus/tracker-tags-utils.c @@ -123,35 +123,35 @@ tracker_tags_escape_sparql_string (const gchar *str) GString *sparql; sparql = g_string_new (""); - g_string_append_c (sparql, '"'); - - while (*str != '\0') { - gsize len = strcspn (str, "\t\n\r\"\\"); - g_string_append_len (sparql, str, len); - str += len; - switch (*str) { - case '\t': - g_string_append (sparql, "\\t"); - break; - case '\n': - g_string_append (sparql, "\\n"); - break; - case '\r': - g_string_append (sparql, "\\r"); - break; - case '"': - g_string_append (sparql, "\\\""); - break; - case '\\': - g_string_append (sparql, "\\\\"); - break; - default: - continue; - } - str++; - } - - g_string_append_c (sparql, '"'); + g_string_append_c (sparql, '"'); + + while (*str != '\0') { + gsize len = strcspn (str, "\t\n\r\"\\"); + g_string_append_len (sparql, str, len); + str += len; + switch (*str) { + case '\t': + g_string_append (sparql, "\\t"); + break; + case '\n': + g_string_append (sparql, "\\n"); + break; + case '\r': + g_string_append (sparql, "\\r"); + break; + case '"': + g_string_append (sparql, "\\\""); + break; + case '\\': + g_string_append (sparql, "\\\\"); + break; + default: + continue; + } + str++; + } + + g_string_append_c (sparql, '"'); return g_string_free (sparql, FALSE); } @@ -164,17 +164,17 @@ tracker_tags_add_query (const gchar *tag_label) tag_label_escaped = tracker_tags_escape_sparql_string (tag_label); query = g_strdup_printf ("INSERT { " - " _:tag a nao:Tag ;" - " nao:prefLabel %s ." - "} " - "WHERE {" - " OPTIONAL {" - " ?tag a nao:Tag ;" - " nao:prefLabel %s" - " } ." - " FILTER (!bound(?tag)) " - "}", - tag_label_escaped, + " _:tag a nao:Tag ;" + " nao:prefLabel %s ." + "} " + "WHERE {" + " OPTIONAL {" + " ?tag a nao:Tag ;" + " nao:prefLabel %s" + " } ." + " FILTER (!bound(?tag)) " + "}", + tag_label_escaped, tag_label_escaped); g_free (tag_label_escaped); @@ -189,13 +189,13 @@ tracker_tags_remove_query (const gchar *tag_label) tag_label_escaped = tracker_tags_escape_sparql_string (tag_label); query = g_strdup_printf ("DELETE { " - " ?tag a rdfs:Resource " - "} " - "WHERE {" - " ?tag a nao:Tag ;" - " nao:prefLabel %s " - "}", - tag_label_escaped); + " ?tag a rdfs:Resource " + "} " + "WHERE {" + " ?tag a nao:Tag ;" + " nao:prefLabel %s " + "}", + tag_label_escaped); g_free (tag_label_escaped); return query; diff --git a/src/plugins/nautilus/tracker-tags-view.c b/src/plugins/nautilus/tracker-tags-view.c index e9ac94c20..6ac6436f2 100644 --- a/src/plugins/nautilus/tracker-tags-view.c +++ b/src/plugins/nautilus/tracker-tags-view.c @@ -26,7 +26,7 @@ #include <libnautilus-extension/nautilus-file-info.h> -#include <libtracker-client/tracker-client.h> +#include <libtracker-sparql/tracker-sparql.h> #include "tracker-tags-utils.h" #include "tracker-tags-view.h" @@ -34,7 +34,11 @@ #define TRACKER_TAGS_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TRACKER_TYPE_TAGS_VIEW, TrackerTagsViewPrivate)) struct _TrackerTagsViewPrivate { - TrackerClient *tracker_client; + TrackerSparqlConnection *connection; + GCancellable *cancellable; + + GList *tag_data_requests; + GList *files; GtkListStore *store; @@ -47,6 +51,7 @@ struct _TrackerTagsViewPrivate { typedef struct { TrackerTagsView *tv; + GCancellable *cancellable; gchar *tag_id; GtkTreeIter *iter; gint items; @@ -78,6 +83,7 @@ enum { static void tracker_tags_view_finalize (GObject *object); static void tags_view_create_ui (TrackerTagsView *tv); +static void tag_data_free (TagData *td); G_DEFINE_TYPE (TrackerTagsView, tracker_tags_view, GTK_TYPE_VBOX); @@ -95,12 +101,23 @@ tracker_tags_view_class_init (TrackerTagsViewClass *klass) static void tracker_tags_view_init (TrackerTagsView *tv) { + GError *error = NULL; + tv->private = TRACKER_TAGS_VIEW_GET_PRIVATE (tv); - tv->private->tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT); + tv->private->cancellable = g_cancellable_new (); + tv->private->connection = tracker_sparql_connection_get (tv->private->cancellable, + &error); + if (!tv->private->connection) { + g_critical ("Couldn't get a proper SPARQL connection: '%s'", + error ? error->message : "unknown error"); + g_clear_error (&error); + } + tv->private->files = NULL; - tv->private->store = gtk_list_store_new (N_COLUMNS, - G_TYPE_INT, /* Selection type */ + + tv->private->store = gtk_list_store_new (N_COLUMNS, + G_TYPE_INT, /* Selection type */ G_TYPE_STRING, /* Tag ID */ G_TYPE_STRING, /* Tag Name */ G_TYPE_STRING, /* Tag Count String */ @@ -112,16 +129,28 @@ tracker_tags_view_finalize (GObject *object) { TrackerTagsView *tv = TRACKER_TAGS_VIEW (object); - g_object_unref (tv->private->tracker_client); + if (tv->private->cancellable) { + g_cancellable_cancel (tv->private->cancellable); + g_object_unref (tv->private->cancellable); + } + + if (tv->private->connection) { + g_object_unref (tv->private->connection); + } g_list_foreach (tv->private->files, (GFunc) g_object_unref, NULL); g_list_free (tv->private->files); + if (tv->private->tag_data_requests) { + g_list_foreach (tv->private->tag_data_requests, (GFunc) tag_data_free, NULL); + g_list_free (tv->private->tag_data_requests); + } + G_OBJECT_CLASS (tracker_tags_view_parent_class)->finalize (object); } static TagData * -tag_data_new (gchar *tag_id, +tag_data_new (const gchar *tag_id, GtkTreeIter *iter, gboolean update, gboolean selected, @@ -132,8 +161,11 @@ tag_data_new (gchar *tag_id, td = g_slice_new (TagData); - td->tv = tv; + g_debug ("Creating tag data"); + + td->tv = tv; + td->cancellable = g_cancellable_new (); td->tag_id = g_strdup (tag_id); if (iter) { @@ -152,6 +184,11 @@ tag_data_new (gchar *tag_id, static void tag_data_free (TagData *td) { + if (td->cancellable) { + g_cancellable_cancel (td->cancellable); + g_object_unref (td->cancellable); + } + g_free (td->tag_id); if (td->iter) { @@ -169,7 +206,7 @@ tag_data_copy (TagData *td) new_td = g_slice_new (TagData); new_td->tv = td->tv; - + new_td->cancellable = g_cancellable_new (); new_td->tag_id = g_strdup (td->tag_id); if (td->iter) { @@ -185,6 +222,25 @@ tag_data_copy (TagData *td) return new_td; } +static void +show_error_dialog (GError *error) +{ + GtkWidget *dialog; + const gchar *str; + + str = error->message ? error->message : _("No error was given"); + + dialog = gtk_message_dialog_new (NULL, + 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", + str); + g_signal_connect (dialog, "response", + G_CALLBACK (gtk_widget_destroy), NULL); + gtk_dialog_run (GTK_DIALOG (dialog)); +} + static gboolean tag_view_model_find_tag_foreach (GtkTreeModel *model, GtkTreePath *path, @@ -194,8 +250,8 @@ tag_view_model_find_tag_foreach (GtkTreeModel *model, gchar *tag; gtk_tree_model_get (model, iter, - COL_TAG_NAME, &tag, - -1); + COL_TAG_NAME, &tag, + -1); if (!tag) { return FALSE; @@ -236,8 +292,8 @@ tag_view_model_find_tag (TrackerTagsView *tv, model = gtk_tree_view_get_model (view); gtk_tree_model_foreach (model, - (GtkTreeModelForeachFunc) tag_view_model_find_tag_foreach, - &data); + (GtkTreeModelForeachFunc) tag_view_model_find_tag_foreach, + &data); if (data.found == TRUE) { *iter = data.found_iter; @@ -248,113 +304,133 @@ tag_view_model_find_tag (TrackerTagsView *tv, } static void -tags_view_tag_removed_cb (GError *error, - gpointer user_data) +tags_view_tag_removed_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { TagData *td = user_data; + GError *error = NULL; + + g_debug ("Update callback\n"); + + tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (source_object), + res, + &error); if (error) { - g_warning ("Could not remove tag, %s", - error->message ? error->message : "no error given"); + show_error_dialog (error); g_error_free (error); - return; - } + } else { + g_debug ("Tag removed\n"); - g_debug ("Tag removed\n"); + gtk_list_store_remove (td->tv->private->store, td->iter); + } - gtk_list_store_remove (td->tv->private->store, td->iter); + td->tv->private->tag_data_requests = + g_list_remove (td->tv->private->tag_data_requests, td); tag_data_free (td); } static void -tags_view_query_files_for_tag_id_cb (GPtrArray *result, - GError *error, - gpointer user_data) +tags_view_query_files_for_tag_id_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { + TrackerSparqlCursor *cursor; TagData *td = user_data; TrackerTagsView *tv = td->tv; GtkTreeIter *iter = td->iter; + GError *error = NULL; gchar *str; guint files_selected, files_with_tag, has_tag_in_selection; + cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (source_object), + res, + &error); + if (error) { - GtkWidget *dialog; - const gchar *str; - - str = error->message ? error->message : _("No error was given"); - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", - str); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_dialog_run (GTK_DIALOG (dialog)); - + show_error_dialog (error); g_error_free (error); + + tv->private->tag_data_requests = + g_list_remove (tv->private->tag_data_requests, td); tag_data_free (td); + if (cursor) { + g_object_unref (cursor); + } + return; } has_tag_in_selection = 0; - files_with_tag = result->len; + files_with_tag = 0; files_selected = g_list_length (tv->private->files); - if (result && result->len > 0) { + /* FIXME: make this async */ + while (tracker_sparql_cursor_next (cursor, + tv->private->cancellable, + &error)) { GList *l; + gboolean equal; + + files_with_tag++; - for (l = tv->private->files; l; l = l->next) { + for (l = tv->private->files, equal = FALSE; l && !equal; l = l->next) { gchar *uri; - gboolean equal; - gint i; + const gchar *str; uri = nautilus_file_info_get_uri (NAUTILUS_FILE_INFO (l->data)); - for (i = 0, equal = FALSE; i < result->len && !equal; i++) { - GStrv strv; + str = tracker_sparql_cursor_get_string (cursor, 0, NULL); + equal = g_strcmp0 (str, uri) == 0; - strv = g_ptr_array_index (result, i); - equal = g_strcmp0 (strv[0], uri) == 0; - - if (equal) { - has_tag_in_selection++; - } + if (equal) { + has_tag_in_selection++; } g_free (uri); } } - g_debug ("Querying files with tag, in selection:%d, in total:%d, selected:%d\n", + if (cursor) { + g_object_unref (cursor); + } + + if (error) { + show_error_dialog (error); + + g_error_free (error); + + return; + } + + g_debug ("Querying files with tag, in selection:%d, in total:%d, selected:%d\n", has_tag_in_selection, files_with_tag, files_selected); - g_ptr_array_foreach (result, (GFunc) g_strfreev, NULL); - g_ptr_array_free (result, TRUE); - if (has_tag_in_selection == 0) { - gtk_list_store_set (tv->private->store, iter, - COL_SELECTION, SELECTION_FALSE, + gtk_list_store_set (tv->private->store, iter, + COL_SELECTION, SELECTION_FALSE, -1); } else if (files_selected != has_tag_in_selection) { - gtk_list_store_set (tv->private->store, iter, - COL_SELECTION, SELECTION_INCONSISTENT, + gtk_list_store_set (tv->private->store, iter, + COL_SELECTION, SELECTION_INCONSISTENT, -1); } else { - gtk_list_store_set (tv->private->store, iter, + gtk_list_store_set (tv->private->store, iter, COL_SELECTION, SELECTION_TRUE, -1); } str = g_strdup_printf ("%d", files_with_tag); - gtk_list_store_set (tv->private->store, iter, + gtk_list_store_set (tv->private->store, iter, COL_TAG_COUNT, str, COL_TAG_COUNT_VALUE, files_with_tag, -1); g_free (str); - + + tv->private->tag_data_requests = + g_list_remove (tv->private->tag_data_requests, td); tag_data_free (td); } @@ -363,6 +439,13 @@ tags_view_query_files_for_tag_id (TagData *td) { gchar *query; + if (!td->tv->private->connection) { + g_warning ("Can't query files for tag id '%s', " + "no SPARQL connection available", + td->tag_id); + return; + } + query = g_strdup_printf ("SELECT ?url " "WHERE {" " ?urn a rdfs:Resource ;" @@ -370,96 +453,94 @@ tags_view_query_files_for_tag_id (TagData *td) " nao:hasTag <%s> . " "}", td->tag_id); - tracker_resources_sparql_query_async (td->tv->private->tracker_client, - query, - tags_view_query_files_for_tag_id_cb, - td); + tracker_sparql_connection_query_async (td->tv->private->connection, + query, + td->cancellable, + tags_view_query_files_for_tag_id_cb, + td); g_free (query); } static void -tags_view_append_foreach (gpointer data, - gpointer user_data) -{ - TrackerTagsView *tv = user_data; - TagData *td; - GtkTreeIter iter; - GStrv strv = data; - - g_debug ("Adding tag id:'%s' with label:'%s' to store\n", strv[0], strv[1]); - - gtk_list_store_append (tv->private->store, &iter); - gtk_list_store_set (tv->private->store, &iter, - COL_TAG_ID, strv[0], - COL_TAG_NAME, strv[1], - COL_SELECTION, SELECTION_FALSE, - -1); - - td = tag_data_new (strv[0], &iter, FALSE, TRUE, 1, tv); - tags_view_query_files_for_tag_id (td); -} - -static void -tags_view_add_tags_cb (GPtrArray *result, - GError *error, - gpointer user_data) +tags_view_add_tags_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { + TrackerSparqlCursor *cursor; TrackerTagsView *tv = user_data; + GError *error = NULL; g_debug ("Clearing tags in store\n"); + cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (source_object), + res, + &error); + gtk_list_store_clear (tv->private->store); if (error) { - GtkWidget *dialog; - const gchar *str; - - str = error->message ? error->message : _("No error was given"); - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", - str); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_dialog_run (GTK_DIALOG (dialog)); - + show_error_dialog (error); g_error_free (error); + + if (cursor) { + g_object_unref (cursor); + } } else { g_debug ("Adding all tags...\n"); - g_ptr_array_foreach (result, tags_view_append_foreach, tv); - g_ptr_array_foreach (result, (GFunc) g_strfreev, NULL); - g_ptr_array_free (result, TRUE); + + /* FIXME: make async */ + while (tracker_sparql_cursor_next (cursor, tv->private->cancellable, NULL)) { + TagData *td; + GtkTreeIter iter; + const gchar *id, *label; + + id = tracker_sparql_cursor_get_string (cursor, 0, NULL); + label = tracker_sparql_cursor_get_string (cursor, 1, NULL); + + g_debug ("Adding tag id:'%s' with label:'%s' to store\n", id, label); + + gtk_list_store_append (tv->private->store, &iter); + gtk_list_store_set (tv->private->store, &iter, + COL_TAG_ID, id, + COL_TAG_NAME, label, + COL_SELECTION, SELECTION_FALSE, + -1); + + td = tag_data_new (id, &iter, FALSE, TRUE, 1, tv); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td); + + tags_view_query_files_for_tag_id (td); + } + + if (cursor) { + g_object_unref (cursor); + } + + if (error) { + show_error_dialog (error); + g_error_free (error); + } } } static void -tags_view_model_update_cb (GError *error, - gpointer user_data) +tags_view_model_update_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { TagData *td = user_data; TrackerTagsView *tv = td->tv; + GError *error = NULL; - g_debug ("Query callback\n"); + g_debug ("Update callback\n"); + + tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (source_object), + res, + &error); if (error) { - GtkWidget *dialog; - const gchar *str; - - str = error->message ? error->message : _("No error was given"); - - dialog = gtk_message_dialog_new (NULL, - 0, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - "%s", - str); - g_signal_connect (dialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - gtk_dialog_run (GTK_DIALOG (dialog)); - + show_error_dialog (error); g_error_free (error); } else { const gchar *tag; @@ -483,27 +564,41 @@ tags_view_model_update_cb (GError *error, -1); g_free (str); } else if (td->selected) { + TagData *td_copy; + g_debug ("Setting tag selection state to ON\n"); gtk_list_store_set (tv->private->store, td->iter, COL_SELECTION, SELECTION_TRUE, -1); - tags_view_query_files_for_tag_id (tag_data_copy (td)); + td_copy = tag_data_copy (td); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td_copy); + + tags_view_query_files_for_tag_id (td_copy); } else { + TagData *td_copy; + g_debug ("Setting tag selection state to FALSE\n"); gtk_list_store_set (tv->private->store, td->iter, COL_SELECTION, SELECTION_FALSE, -1); - tags_view_query_files_for_tag_id (tag_data_copy (td)); + td_copy = tag_data_copy (td); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td_copy); + + tags_view_query_files_for_tag_id (td_copy); } } gtk_entry_set_text (GTK_ENTRY (tv->private->entry), ""); gtk_widget_set_sensitive (tv->private->entry, TRUE); + tv->private->tag_data_requests = + g_list_remove (tv->private->tag_data_requests, td); tag_data_free (td); } @@ -511,9 +606,17 @@ static void tags_view_add_tag (TrackerTagsView *tv, const gchar *tag) { + TagData *td; GString *query; gint files; + if (!tv->private->connection) { + g_warning ("Can't add tag '%s', " + "no SPARQL connection available", + tag); + return; + } + gtk_widget_set_sensitive (tv->private->entry, FALSE); files = g_list_length (tv->private->files); @@ -531,7 +634,7 @@ tags_view_add_tag (TrackerTagsView *tv, tag_escaped = tracker_tags_escape_sparql_string (tag); for (i = 0; files[i] != NULL; i++) { - g_string_append_printf (query, + g_string_append_printf (query, "INSERT { _:file a nie:DataObject ; nie:url '%s' } " "WHERE { " " OPTIONAL {" @@ -544,29 +647,29 @@ tags_view_add_tag (TrackerTagsView *tv, } g_string_append_printf (query, - "INSERT { " - " _:tag a nao:Tag;" - " nao:prefLabel %s . " - "} " - "WHERE {" - " OPTIONAL {" - " ?tag a nao:Tag ;" - " nao:prefLabel %s" - " } ." - " FILTER (!bound(?tag)) " - "} " - "INSERT { " - " ?urn nao:hasTag ?label " - "} " - "WHERE {" - " ?urn nie:url ?f ." - " ?label nao:prefLabel %s " - " %s " - "}", - tag_escaped, - tag_escaped, - tag_escaped, - filter); + "INSERT { " + " _:tag a nao:Tag;" + " nao:prefLabel %s . " + "} " + "WHERE {" + " OPTIONAL {" + " ?tag a nao:Tag ;" + " nao:prefLabel %s" + " } ." + " FILTER (!bound(?tag)) " + "} " + "INSERT { " + " ?urn nao:hasTag ?label " + "} " + "WHERE {" + " ?urn nie:url ?f ." + " ?label nao:prefLabel %s " + " %s " + "}", + tag_escaped, + tag_escaped, + tag_escaped, + filter); g_free (tag_escaped); g_free (filter); @@ -575,10 +678,16 @@ tags_view_add_tag (TrackerTagsView *tv, query = g_string_new (tracker_tags_add_query (tag)); } - tracker_resources_sparql_update_async (tv->private->tracker_client, - query->str, - tags_view_model_update_cb, - tag_data_new (NULL, NULL, FALSE, TRUE, files, tv)); + td = tag_data_new (NULL, NULL, FALSE, TRUE, files, tv); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td); + + tracker_sparql_connection_update_async (tv->private->connection, + query->str, + G_PRIORITY_DEFAULT, + td->cancellable, + tags_view_model_update_cb, + td); g_string_free (query, TRUE); } @@ -594,7 +703,7 @@ tags_view_model_toggle_cell_data_func (GtkTreeViewColumn *column, gint selection; gtk_tree_model_get (tree_model, iter, COL_SELECTION, &selection, -1); - gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE (cell_renderer), + gtk_cell_renderer_toggle_set_active (GTK_CELL_RENDERER_TOGGLE (cell_renderer), SELECTION_TRUE == selection); g_value_init (&inconsistent, G_TYPE_BOOLEAN); @@ -606,6 +715,7 @@ static void tags_view_model_toggle_row (TrackerTagsView *tv, GtkTreePath *path) { + TagData *td; GStrv files; GtkTreeIter iter; GtkTreeModel *model; @@ -642,8 +752,8 @@ tags_view_model_toggle_row (TrackerTagsView *tv, " ?urn nie:url ?f ." /* NB: ?f is used in filter. */ " ?label nao:prefLabel %s ." " %s " - "}", - tag_escaped, + "}", + tag_escaped, filter); } else { TagData *td; @@ -656,13 +766,16 @@ tags_view_model_toggle_row (TrackerTagsView *tv, " ?label nao:prefLabel %s ." " %s " "}", - tag_escaped, + tag_escaped, filter); - + /* Check if there are any files left with this tag and * remove tag if not. */ td = tag_data_new (id, &iter, FALSE, TRUE, 1, tv); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td); + tags_view_query_files_for_tag_id (td); } @@ -671,12 +784,26 @@ tags_view_model_toggle_row (TrackerTagsView *tv, gtk_widget_set_sensitive (tv->private->entry, FALSE); + if (!tv->private->connection) { + g_warning ("Can't update tags, " + "no SPARQL connection available"); + g_free (id); + g_free (query); + return; + } + g_debug ("Running query:'%s'\n", query); - tracker_resources_sparql_update_async (tv->private->tracker_client, - query, - tags_view_model_update_cb, - tag_data_new (id, &iter, TRUE, selection, 1, tv)); + td = tag_data_new (id, &iter, TRUE, selection, 1, tv); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td); + + tracker_sparql_connection_update_async (tv->private->connection, + query, + G_PRIORITY_DEFAULT, + td->cancellable, + tags_view_model_update_cb, + td); g_free (id); g_free (query); @@ -695,9 +822,9 @@ tags_view_model_cell_toggled_cb (GtkCellRendererToggle *cell, } static void -tags_view_model_row_activated_cb (GtkTreeView *view, - GtkTreePath *path, - GtkTreeViewColumn *column, +tags_view_model_row_activated_cb (GtkTreeView *view, + GtkTreePath *path, + GtkTreeViewColumn *column, gpointer user_data) { tags_view_model_toggle_row (user_data, path); @@ -728,7 +855,7 @@ tags_view_entry_activate_cb (GtkEditable *editable, } static void -tags_view_add_clicked_cb (GtkButton *button, +tags_view_add_clicked_cb (GtkButton *button, gpointer user_data) { TrackerTagsView *tv = user_data; @@ -742,22 +869,36 @@ static void tags_view_remove_tag (TrackerTagsView *tv, TagData *td) { + TagData *td_copy; gchar *query; + if (!tv->private->connection) { + g_warning ("Can't remove tag '%s', " + "no SPARQL connection available", + td->tag_id); + return; + } + query = g_strdup_printf ("DELETE { " " <%s> a rdfs:Resource " "}", td->tag_id); - tracker_resources_sparql_update_async (tv->private->tracker_client, - query, - tags_view_tag_removed_cb, - tag_data_copy (td)); + td_copy = tag_data_copy (td); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td_copy); + + tracker_sparql_connection_update_async (tv->private->connection, + query, + G_PRIORITY_DEFAULT, + td_copy->cancellable, + tags_view_tag_removed_cb, + td_copy); g_free (query); } static void -tags_view_remove_clicked_cb (GtkButton *button, +tags_view_remove_clicked_cb (GtkButton *button, gpointer user_data) { TrackerTagsView *tv = user_data; @@ -771,8 +912,15 @@ tags_view_remove_clicked_cb (GtkButton *button, if (gtk_tree_selection_get_selected (select, &model, &iter)) { gtk_tree_model_get (GTK_TREE_MODEL (tv->private->store), &iter, COL_TAG_ID, &id, -1); + td = tag_data_new (id, &iter, FALSE, TRUE, 1, tv); + tv->private->tag_data_requests = + g_list_prepend (tv->private->tag_data_requests, td); + tags_view_remove_tag (tv, td); + + tv->private->tag_data_requests = + g_list_remove (tv->private->tag_data_requests, td); tag_data_free (td); } } @@ -833,11 +981,11 @@ tags_view_create_ui (TrackerTagsView *tv) gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry); - g_signal_connect (entry, "changed", - G_CALLBACK (tags_view_entry_changed_cb), + g_signal_connect (entry, "changed", + G_CALLBACK (tags_view_entry_changed_cb), tv); - g_signal_connect (entry, "activate", - G_CALLBACK (tags_view_entry_activate_cb), + g_signal_connect (entry, "activate", + G_CALLBACK (tags_view_entry_activate_cb), tv); button = gtk_button_new_from_stock (GTK_STOCK_ADD); @@ -846,8 +994,8 @@ tags_view_create_ui (TrackerTagsView *tv) gtk_widget_set_can_default (button, TRUE); gtk_widget_set_sensitive (button, FALSE); - g_signal_connect (button, "clicked", - G_CALLBACK (tags_view_add_clicked_cb), + g_signal_connect (button, "clicked", + G_CALLBACK (tags_view_add_clicked_cb), tv); tv->private->button_add = button; @@ -857,8 +1005,8 @@ tags_view_create_ui (TrackerTagsView *tv) gtk_widget_set_sensitive (button, FALSE); - g_signal_connect (button, "clicked", - G_CALLBACK (tags_view_remove_clicked_cb), + g_signal_connect (button, "clicked", + G_CALLBACK (tags_view_remove_clicked_cb), tv); tv->private->button_remove = button; @@ -867,9 +1015,9 @@ tags_view_create_ui (TrackerTagsView *tv) scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_box_pack_start (GTK_BOX (tv), scrolled_window, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); view = gtk_tree_view_new (); @@ -888,10 +1036,10 @@ tags_view_create_ui (TrackerTagsView *tv) tv); gtk_tree_view_column_pack_start (column, cell_renderer, TRUE); - gtk_tree_view_column_set_cell_data_func (column, - cell_renderer, - tags_view_model_toggle_cell_data_func, - NULL, + gtk_tree_view_column_set_cell_data_func (column, + cell_renderer, + tags_view_model_toggle_cell_data_func, + NULL, NULL); gtk_cell_renderer_toggle_set_radio (GTK_CELL_RENDERER_TOGGLE (cell_renderer), FALSE); @@ -917,27 +1065,34 @@ tags_view_create_ui (TrackerTagsView *tv) /* List settings */ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); - gtk_tree_view_set_model (GTK_TREE_VIEW (view), + gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (tv->private->store)); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - g_signal_connect (view, "row-activated", - G_CALLBACK (tags_view_model_row_activated_cb), + g_signal_connect (view, "row-activated", + G_CALLBACK (tags_view_model_row_activated_cb), tv); - g_signal_connect (selection, "changed", - G_CALLBACK (tags_view_model_row_selected_cb), + g_signal_connect (selection, "changed", + G_CALLBACK (tags_view_model_row_selected_cb), tv); - tracker_resources_sparql_query_async (tv->private->tracker_client, - "SELECT ?urn ?label " - "WHERE {" - " ?urn a nao:Tag ;" - " nao:prefLabel ?label . " - "} ORDER BY ?label", - tags_view_add_tags_cb, tv); + if (tv->private->connection) { + tracker_sparql_connection_query_async (tv->private->connection, + "SELECT ?urn ?label " + "WHERE {" + " ?urn a nao:Tag ;" + " nao:prefLabel ?label . " + "} ORDER BY ?label", + tv->private->cancellable, + tags_view_add_tags_cb, + tv); + } else { + g_warning ("Can't query for tags, " + "no SPARQL connection available"); + } gtk_widget_show_all (GTK_WIDGET (tv)); gtk_widget_grab_focus (entry); @@ -959,7 +1114,7 @@ tracker_tags_view_new (GList *files) TrackerTagsView *tv; g_return_val_if_fail (files != NULL, NULL); - + tv = g_object_new (TRACKER_TYPE_TAGS_VIEW, NULL); tv->private->files = tracker_glist_copy_with_nautilus_files (files); |