[bijiben] noteTagsDialog Sort tags properly and scroll to new tags
- From: Pierre-Yves Luyten <pyluyten src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [bijiben] noteTagsDialog Sort tags properly and scroll to new tags
- Date: Wed, 30 Jan 2013 22:39:57 +0000 (UTC)
commit 9f2339fb93766a8e2a6d1e0b2f7a9f39d2484b95
Author: Pierre-Yves Luyten <py luyten fr>
Date: Wed Jan 30 23:38:05 2013 +0100
noteTagsDialog Sort tags properly and scroll to new tags
https://bugzilla.gnome.org/show_bug.cgi?id=692791
https://bugzilla.gnome.org/show_bug.cgi?id=692790
src/bjb-note-tag-dialog.c | 118 ++++++++++++++++++---
src/libbiji/biji-note-obj.c | 6 +-
src/libbiji/biji-tracker.c | 67 ++++++++++---
src/libbiji/biji-tracker.h | 6 +-
src/libbiji/deserializer/biji-lazy-deserializer.c | 3 +-
5 files changed, 170 insertions(+), 30 deletions(-)
---
diff --git a/src/bjb-note-tag-dialog.c b/src/bjb-note-tag-dialog.c
index f0bd71b..ea6a81d 100644
--- a/src/bjb-note-tag-dialog.c
+++ b/src/bjb-note-tag-dialog.c
@@ -52,12 +52,16 @@ struct _BjbNoteTagDialogPrivate
// parent
GtkWindow *window;
- // to create new tag
+ // widgets
GtkWidget * entry;
+ GtkTreeView * view;
// data
GList *notes;
GtkListStore *store;
+
+ // tmp when a new tag added
+ gchar *tag_to_scroll_to;
};
#define BJB_NOTE_TAG_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BJB_TYPE_NOTE_TAG_DIALOG, BjbNoteTagDialogPrivate))
@@ -91,25 +95,92 @@ append_tag (gchar *tag, BjbNoteTagDialog *self)
COL_TAG_NAME , tag, -1);
}
-/* Current tags selection & sorting might be improved */
+static gint
+bjb_compare_tag (gconstpointer a, gconstpointer b)
+{
+ gchar *up_a, *up_b;
+ gint retval;
+
+ up_a = g_utf8_strup (a, -1);
+ up_b = g_utf8_strup (b, -1);
+ retval = g_strcmp0 (up_a, up_b);
+
+ g_free (up_a);
+ g_free (up_b);
+ return retval;
+}
+
+/* If true, free the retval with gtk_tree_path_free */
+static gboolean
+bjb_get_path_for_str (GtkTreeModel *model,
+ GtkTreePath **return_value,
+ gint column,
+ gchar *needle)
+{
+ gboolean retval= FALSE;
+ GtkTreeIter iter;
+ gboolean valid = gtk_tree_model_get_iter_first (model, &iter);
+ *return_value = NULL;
+
+ while (valid)
+ {
+ gchar *cur_str = NULL;
+ gtk_tree_model_get (model, &iter, column, &cur_str, -1);
+
+ if (cur_str)
+ {
+ if (g_strcmp0 (cur_str, needle)==0)
+ *return_value = gtk_tree_model_get_path (model, &iter);
+
+ g_free (cur_str);
+ }
+
+ if (*return_value)
+ {
+ retval = TRUE;
+ break;
+ }
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ return retval;
+}
+
static void
bjb_note_tag_dialog_handle_tags (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
BjbNoteTagDialog *self = BJB_NOTE_TAG_DIALOG (user_data);
+ BjbNoteTagDialogPrivate *priv = self->priv;
GList *tags;
tags = biji_get_all_tags_finish (source_object, res);
- tags = g_list_sort (tags, (GCompareFunc) g_strcmp0);
+ tags = g_list_sort (tags, bjb_compare_tag);
g_list_foreach (tags, (GFunc) append_tag, self);
g_list_free_full (tags, g_free);
+
+ /* If a new tag was added, scroll & free */
+ if (priv->tag_to_scroll_to)
+ {
+ GtkTreePath *path = NULL;
+
+ if (bjb_get_path_for_str (GTK_TREE_MODEL (priv->store), &path,
+ COL_TAG_NAME, priv->tag_to_scroll_to))
+ {
+ gtk_tree_view_scroll_to_cell (priv->view, path, NULL, TRUE, 0.5, 0.5);
+ gtk_tree_path_free (path);
+ }
+
+ g_clear_pointer (& (priv->tag_to_scroll_to), g_free);
+ }
}
static void
-update_tags_model (BjbNoteTagDialog *self)
+update_tags_model_async (BjbNoteTagDialog *self)
{
gtk_list_store_clear (self->priv->store);
biji_get_all_tracker_tags_async (bjb_note_tag_dialog_handle_tags, self);
@@ -163,10 +234,24 @@ on_tag_toggled (GtkCellRendererToggle *cell,
}
static void
+on_new_tag_added_cb (gpointer user_data)
+{
+ BjbNoteTagDialog *self = user_data;
+ BjbNoteTagDialogPrivate *priv = self->priv;
+
+ priv->tag_to_scroll_to = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
+ g_list_foreach (priv->notes, (GFunc) note_dialog_add_tag, priv->tag_to_scroll_to);
+
+ update_tags_model_async (self);
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), "");
+}
+
+static void
add_new_tag (BjbNoteTagDialog *self)
{
- push_tag_to_tracker ((gchar*) gtk_entry_get_text(GTK_ENTRY(self->priv->entry)));
- update_tags_model (self);
+ push_tag_to_tracker (gtk_entry_get_text (GTK_ENTRY (self->priv->entry)),
+ on_new_tag_added_cb,
+ self );
}
static void
@@ -231,6 +316,7 @@ bjb_note_tag_dialog_init (BjbNoteTagDialog *self)
self->priv = priv;
priv->notes = NULL;
priv->window = NULL;
+ priv->tag_to_scroll_to = NULL;
gtk_window_set_default_size (GTK_WINDOW (self),
BJB_NOTE_TAG_DIALOG_DEFAULT_WIDTH,
@@ -257,7 +343,6 @@ bjb_note_tag_dialog_constructed (GObject *obj)
BjbNoteTagDialog *self = BJB_NOTE_TAG_DIALOG (obj);
BjbNoteTagDialogPrivate *priv = self->priv;
GtkWidget *hbox, *label, *new, *area, *sw, *close;
- GtkTreeView *treeview;
gtk_window_set_transient_for (GTK_WINDOW (self), priv->window);
@@ -287,16 +372,16 @@ bjb_note_tag_dialog_constructed (GObject *obj)
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- update_tags_model (self);
- treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->store)));
+ update_tags_model_async (self);
+ priv->view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->store)));
g_object_unref (self->priv->store);
- gtk_tree_view_set_rules_hint (treeview, TRUE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (treeview),
+ gtk_tree_view_set_rules_hint (priv->view, TRUE);
+ gtk_tree_selection_set_mode (gtk_tree_view_get_selection (priv->view),
GTK_SELECTION_MULTIPLE);
- add_columns (treeview, self);
- gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (treeview));
+ add_columns (priv->view, self);
+ gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->view));
gtk_box_pack_start (GTK_BOX (area), sw, TRUE, TRUE,2);
@@ -312,6 +397,13 @@ bjb_note_tag_dialog_constructed (GObject *obj)
static void
bjb_note_tag_dialog_finalize (GObject *object)
{
+ BjbNoteTagDialog *self = BJB_NOTE_TAG_DIALOG (object);
+ BjbNoteTagDialogPrivate *priv = self->priv;
+
+ /* no reason, it should have been freed earlier */
+ if (priv->tag_to_scroll_to)
+ g_free (priv->tag_to_scroll_to);
+
G_OBJECT_CLASS (bjb_note_tag_dialog_parent_class)->finalize (object);
}
diff --git a/src/libbiji/biji-note-obj.c b/src/libbiji/biji-note-obj.c
index f13d665..96e7704 100644
--- a/src/libbiji/biji-note-obj.c
+++ b/src/libbiji/biji-note-obj.c
@@ -594,11 +594,13 @@ biji_note_obj_add_label (BijiNoteObj *note, gchar *label, gboolean on_user_actio
g_return_val_if_fail (label != NULL, FALSE);
g_return_val_if_fail (!biji_note_obj_has_label (note, label), FALSE);
- g_hash_table_add (note->priv->labels, label);
+ gchar *tag = g_strdup (label);
+
+ g_hash_table_add (note->priv->labels, tag);
if (on_user_action_cb)
{
- push_existing_or_new_tag_to_note (label, note); // Tracker
+ push_existing_or_new_tag_to_note (tag, note); // Tracker
biji_note_id_set_last_metadata_change_date_now (note->priv->id);
biji_note_obj_save_note (note);
}
diff --git a/src/libbiji/biji-tracker.c b/src/libbiji/biji-tracker.c
index fe3d93b..5e84898 100644
--- a/src/libbiji/biji-tracker.c
+++ b/src/libbiji/biji-tracker.c
@@ -17,6 +17,39 @@
#include "biji-tracker.h"
+/* To perform something after async tracker query */
+typedef struct {
+
+ /* query, could add the cancellable */
+ gchar *query;
+
+ /* after the query */
+ BijiFunc func;
+ gpointer user_data;
+
+} BijiTrackerFinisher;
+
+static BijiTrackerFinisher *
+biji_tracker_finisher_new (gchar *query, BijiFunc f, gpointer user_data)
+{
+ BijiTrackerFinisher *retval = g_new (BijiTrackerFinisher, 1);
+
+ retval->query = query;
+ retval->func = f;
+ retval->user_data = user_data;
+
+ return retval;
+}
+
+static void
+biji_tracker_finisher_free (BijiTrackerFinisher *f)
+{
+ if (f->query)
+ g_free (f->query);
+
+ g_free (f);
+}
+
TrackerSparqlConnection *bjb_connection ;
static TrackerSparqlConnection *
@@ -55,7 +88,8 @@ biji_finish_update (GObject *source_object,
{
TrackerSparqlConnection *self = TRACKER_SPARQL_CONNECTION (source_object);
GError *error = NULL;
- gchar *query = user_data;
+ BijiTrackerFinisher *finisher = user_data;
+ gchar *query = finisher->query;
tracker_sparql_connection_update_finish (self, res, &error);
@@ -65,18 +99,24 @@ biji_finish_update (GObject *source_object,
g_error_free (error);
}
- g_free (query);
+ /* See if the query has something to perform afterward */
+ if (finisher->func)
+ finisher->func (finisher->user_data);
+
+ biji_tracker_finisher_free (finisher);
}
static void
-biji_perform_update_async_and_free (gchar *query)
+biji_perform_update_async_and_free (gchar *query, BijiFunc f, gpointer user_data)
{
+ BijiTrackerFinisher *finisher = biji_tracker_finisher_new (query, f, user_data);
+
tracker_sparql_connection_update_async (get_connection_singleton(),
query,
0, // priority
NULL,
biji_finish_update,
- query);
+ finisher);
}
/* Don't worry too much. We just want plain text here */
@@ -204,17 +244,18 @@ biji_get_notes_with_string_or_tag_async (gchar *needle, GAsyncReadyCallback f, g
}
void
-push_tag_to_tracker(gchar *tag)
+push_tag_to_tracker (const gchar *tag, BijiFunc afterward, gpointer user_data)
{
gchar *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,tag);
- biji_perform_update_async_and_free (query) ;
+ biji_perform_update_async_and_free (query, afterward, user_data);
}
-// removes the tag EVEN if files associated.
+/* removes the tag EVEN if files associated.
+ * TODO : afterward */
void
remove_tag_from_tracker(gchar *tag)
{
@@ -222,12 +263,12 @@ remove_tag_from_tracker(gchar *tag)
gchar *query = g_strdup_printf ("DELETE { ?tag a nao:Tag } \
WHERE { ?tag nao:prefLabel '%s' }",value);
- biji_perform_update_async_and_free (query);
+ biji_perform_update_async_and_free (query, NULL, NULL);
g_free (tag);
}
void
-push_existing_or_new_tag_to_note (gchar *tag,BijiNoteObj *note)
+push_existing_or_new_tag_to_note (gchar *tag, BijiNoteObj *note)
{
gchar *url = get_note_url (note);
gchar *query = g_strdup_printf (
@@ -235,7 +276,7 @@ push_existing_or_new_tag_to_note (gchar *tag,BijiNoteObj *note)
?unknown nao:hasTag _:tag} WHERE {?unknown nie:url '%s'}",
tag, url);
- biji_perform_update_async_and_free (query);
+ biji_perform_update_async_and_free (query, NULL, NULL);
g_free (url);
}
@@ -249,7 +290,7 @@ remove_tag_from_note (gchar *tag, BijiNoteObj *note)
WHERE { ?urn nie:url ?f . ?label nao:prefLabel '%s' . \
FILTER (?f = '%s') }", tag, url);
- biji_perform_update_async_and_free (query);
+ biji_perform_update_async_and_free (query, NULL, NULL);
g_free (url);
}
@@ -260,7 +301,7 @@ biji_note_delete_from_tracker (BijiNoteObj *note)
gchar *query = g_strdup_printf ("DELETE { <%s> a rdfs:Resource }",
biji_note_obj_get_path(note));
- biji_perform_update_async_and_free (query);
+ biji_perform_update_async_and_free (query, NULL, NULL);
}
void
@@ -292,7 +333,7 @@ bijiben_push_note_to_tracker (BijiNoteObj *note)
title,
content) ;
- biji_perform_update_async_and_free (query);
+ biji_perform_update_async_and_free (query, NULL, NULL);
g_free(title);
g_free(file);
diff --git a/src/libbiji/biji-tracker.h b/src/libbiji/biji-tracker.h
index 66a8ce3..b6a8952 100644
--- a/src/libbiji/biji-tracker.h
+++ b/src/libbiji/biji-tracker.h
@@ -24,15 +24,19 @@
#include <libbiji/libbiji.h>
+/* todo : find this on glib */
+typedef void (*BijiFunc) (gpointer user_data);
+
/* All notes matching (either content or tag) */
GList * biji_get_notes_with_strings_or_tag_finish (GObject *source_object, GAsyncResult *res, BijiNoteBook *book);
void biji_get_notes_with_string_or_tag_async (gchar *needle, GAsyncReadyCallback f, gpointer user_data);
/* Get tags */
GList * biji_get_all_tags_finish (GObject *source_object, GAsyncResult *res);
+
void biji_get_all_tracker_tags_async (GAsyncReadyCallback f, gpointer user_data);
-void push_tag_to_tracker(gchar *tag);
+void push_tag_to_tracker (const gchar *tag, BijiFunc afterward, gpointer user_data);
void remove_tag_from_tracker(gchar *tag);
diff --git a/src/libbiji/deserializer/biji-lazy-deserializer.c b/src/libbiji/deserializer/biji-lazy-deserializer.c
index b9b43b2..13f0ece 100644
--- a/src/libbiji/deserializer/biji-lazy-deserializer.c
+++ b/src/libbiji/deserializer/biji-lazy-deserializer.c
@@ -492,7 +492,8 @@ processNode (BijiLazyDeserializer *self)
{
norm = g_string_new (tag);
g_string_erase (norm,0,16);
- biji_note_obj_add_label (n, g_string_free (norm, FALSE), FALSE);
+ biji_note_obj_add_label (n, norm->str, FALSE);
+ g_string_free (norm, TRUE);
}
free (tag);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]