[gthumb/ext] put the used tags first in the tags expander
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] put the used tags first in the tags expander
- Date: Sun, 25 Oct 2009 10:27:05 +0000 (UTC)
commit 80dd535d4dbc14e302aaa9b7d2a31d56557e10aa
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Oct 25 11:26:21 2009 +0100
put the used tags first in the tags expander
gthumb/gth-tags-entry.c | 11 ++-
gthumb/gth-tags-expander.c | 237 +++++++++++++++++++++++++++++---------------
2 files changed, 168 insertions(+), 80 deletions(-)
---
diff --git a/gthumb/gth-tags-entry.c b/gthumb/gth-tags-entry.c
index 3f8ad6e..f09c834 100644
--- a/gthumb/gth-tags-entry.c
+++ b/gthumb/gth-tags-entry.c
@@ -440,7 +440,8 @@ gth_tags_entry_get_tags (GthTagsEntry *self,
all_tags[i] = g_strstrip (all_tags[i]);
if (all_tags[i][0] != '\0') {
tags[j] = g_strdup (all_tags[i]);
- gth_tags_file_add (tags_file, tags[j]);
+ if (update_globals)
+ gth_tags_file_add (tags_file, tags[j]);
j++;
}
}
@@ -462,6 +463,14 @@ gth_tags_entry_set_tags (GthTagsEntry *self,
{
char *s;
+ if (tags == NULL)
+ return;
+
+ if (tags[0] == NULL) {
+ gtk_entry_set_text (GTK_ENTRY (self), "");
+ return;
+ }
+
s = g_strjoinv(", ", tags);
gtk_entry_set_text (GTK_ENTRY (self), s);
g_free (s);
diff --git a/gthumb/gth-tags-expander.c b/gthumb/gth-tags-expander.c
index dc3abd2..bdca5e2 100644
--- a/gthumb/gth-tags-expander.c
+++ b/gthumb/gth-tags-expander.c
@@ -31,20 +31,29 @@
enum {
USED_COLUMN,
+ SEPARATOR_COLUMN,
NAME_COLUMN,
N_COLUMNS
};
struct _GthTagsExpanderPrivate {
- GtkEntry *entry;
- char **tags;
- GtkWidget *tree_view;
- GtkListStore *store;
- gulong monitor_event;
+ GtkEntry *entry;
+ char **tags;
+ char **last_used;
+ GtkWidget *tree_view;
+ GtkListStore *store;
+ gulong monitor_event;
};
+typedef struct {
+ char *name;
+ gboolean used;
+ gboolean suggested;
+} TagData;
+
+
static gpointer parent_class = NULL;
@@ -56,6 +65,7 @@ gth_tags_expander_finalize (GObject *obj)
self = GTH_TAGS_EXPANDER (obj);
g_signal_handler_disconnect (gth_main_get_default_monitor (), self->priv->monitor_event);
+ g_strfreev (self->priv->last_used);
g_strfreev (self->priv->tags);
G_OBJECT_CLASS (parent_class)->finalize (obj);
@@ -75,79 +85,158 @@ gth_tags_expander_class_init (GthTagsExpanderClass *klass)
}
+static int
+sort_tag_data (gconstpointer a,
+ gconstpointer b,
+ gpointer user_data)
+{
+ TagData *tag_data_a = * (TagData **) a;
+ TagData *tag_data_b = * (TagData **) b;
+
+ if (tag_data_a->used && tag_data_b->used)
+ return g_utf8_collate (tag_data_a->name, tag_data_b->name);
+ else if (tag_data_a->used || tag_data_b->used)
+ return tag_data_a->used ? -1 : 1;
+ else if (tag_data_a->suggested && tag_data_b->suggested)
+ return g_utf8_collate (tag_data_a->name, tag_data_b->name);
+ else if (tag_data_a->suggested || tag_data_b->suggested)
+ return tag_data_a->suggested ? -1 : 1;
+ else
+ return g_utf8_collate (tag_data_a->name, tag_data_b->name);
+}
+
+
static void
-update_tag_list (GthTagsExpander *self)
+update_list_view_from_entry (GthTagsExpander *self)
{
- GthTagsFile *tags;
- int i;
+ char **all_tags;
+ char **used_tags;
+ TagData **tag_data;
+ int i;
+ GtkTreeIter iter;
+ gboolean separator_required;
+
+ all_tags = g_strdupv (gth_tags_file_get_tags (gth_main_get_default_tag_file ()));
+ used_tags = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (self->priv->entry), FALSE);
+
+ tag_data = g_new (TagData *, g_strv_length (all_tags) + 1);
+ for (i = 0; all_tags[i] != NULL; i++) {
+ int j;
+
+ tag_data[i] = g_new0 (TagData, 1);
+ tag_data[i]->name = g_strdup (all_tags[i]);
+ tag_data[i]->suggested = FALSE;
+ tag_data[i]->used = FALSE;
+ for (j = 0; ! tag_data[i]->used && (used_tags[j] != NULL); j++)
+ if (g_utf8_collate (tag_data[i]->name, used_tags[j]) == 0)
+ tag_data[i]->used = TRUE;
+
+ if (! tag_data[i]->used)
+ for (j = 0; ! tag_data[i]->suggested && (self->priv->last_used[j] != NULL); j++)
+ if (g_utf8_collate (tag_data[i]->name, self->priv->last_used[j]) == 0)
+ tag_data[i]->suggested = TRUE;
+ }
+ tag_data[i] = NULL;
- tags = gth_main_get_default_tag_file ();
+ g_qsort_with_data (tag_data,
+ g_strv_length (all_tags),
+ sizeof (TagData *),
+ sort_tag_data,
+ NULL);
- g_strfreev (self->priv->tags);
- self->priv->tags = g_strdupv (gth_tags_file_get_tags (tags));
+ gtk_list_store_clear (self->priv->store);
+
+ /* used */
- for (i = 0; self->priv->tags[i] != NULL; i++) {
+ separator_required = FALSE;
+ for (i = 0; tag_data[i] != NULL; i++) {
GtkTreeIter iter;
+ if (! tag_data[i]->used)
+ continue;
+
+ separator_required = TRUE;
+
gtk_list_store_append (self->priv->store, &iter);
gtk_list_store_set (self->priv->store, &iter,
- NAME_COLUMN, self->priv->tags[i],
+ USED_COLUMN, TRUE,
+ SEPARATOR_COLUMN, FALSE,
+ NAME_COLUMN, tag_data[i]->name,
-1);
}
- gtk_list_store_clear (self->priv->store);
- for (i = 0; self->priv->tags[i] != NULL; i++) {
- GtkTreeIter iter;
-
+ if (separator_required) {
gtk_list_store_append (self->priv->store, &iter);
gtk_list_store_set (self->priv->store, &iter,
- NAME_COLUMN, self->priv->tags[i],
+ USED_COLUMN, FALSE,
+ SEPARATOR_COLUMN, TRUE,
+ NAME_COLUMN, "",
-1);
}
-}
+ /* suggested */
-static void
-tags_changed_cb (GthMonitor *monitor,
- GthTagsExpander *self)
-{
- update_tag_list (self);
-}
+ separator_required = FALSE;
+ for (i = 0; tag_data[i] != NULL; i++) {
+ GtkTreeIter iter;
+ if (! tag_data[i]->suggested)
+ continue;
-static void
-update_list_view_from_entry (GthTagsExpander *self)
-{
- char **tags;
- GtkTreeIter iter;
+ separator_required = TRUE;
+
+ gtk_list_store_append (self->priv->store, &iter);
+ gtk_list_store_set (self->priv->store, &iter,
+ USED_COLUMN, FALSE,
+ SEPARATOR_COLUMN, FALSE,
+ NAME_COLUMN, tag_data[i]->name,
+ -1);
+ }
+
+ if (separator_required) {
+ gtk_list_store_append (self->priv->store, &iter);
+ gtk_list_store_set (self->priv->store, &iter,
+ USED_COLUMN, FALSE,
+ SEPARATOR_COLUMN, TRUE,
+ NAME_COLUMN, "",
+ -1);
+ }
- tags = gth_tags_entry_get_tags (GTH_TAGS_ENTRY (self->priv->entry), FALSE);
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->priv->store), &iter))
- do {
- char *name;
- gboolean used = FALSE;
- int i;
+ /* others */
- gtk_tree_model_get (GTK_TREE_MODEL (self->priv->store), &iter,
- NAME_COLUMN, &name,
- -1);
+ for (i = 0; tag_data[i] != NULL; i++) {
+ GtkTreeIter iter;
- for (i = 0; ! used && (tags[i] != NULL); i++)
- if (g_utf8_collate (name, tags[i]) == 0)
- used = TRUE;
+ if (tag_data[i]->used || tag_data[i]->suggested)
+ continue;
- gtk_list_store_set (self->priv->store, &iter,
- USED_COLUMN, used,
- -1);
+ gtk_list_store_append (self->priv->store, &iter);
+ gtk_list_store_set (self->priv->store, &iter,
+ USED_COLUMN, FALSE,
+ SEPARATOR_COLUMN, FALSE,
+ NAME_COLUMN, tag_data[i]->name,
+ -1);
+ }
- g_free (name);
- }
- while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->store), &iter));
+ g_strfreev (self->priv->last_used);
+ self->priv->last_used = used_tags;
- g_strfreev (tags);
+ for (i = 0; tag_data[i] != NULL; i++) {
+ g_free (tag_data[i]->name);
+ g_free (tag_data[i]);
+ }
+ g_free (tag_data);
+ g_strfreev (all_tags);
}
+static void
+tags_changed_cb (GthMonitor *monitor,
+ GthTagsExpander *self)
+{
+ update_list_view_from_entry (self);
+}
+
static void
update_entry_from_list_view (GthTagsExpander *self)
@@ -178,9 +267,6 @@ update_entry_from_list_view (GthTagsExpander *self)
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (self->priv->store), &iter));
- if (name_list == NULL)
- return;
-
name_list = g_list_reverse (name_list);
tags = g_new (char *, g_list_length (name_list) + 1);
for (i = 0, scan = name_list; scan; scan = scan->next)
@@ -226,28 +312,6 @@ cell_renderer_toggle_toggled_cb (GtkCellRendererToggle *cell_renderer,
static void
-tag_list_map_cb (GtkWidget *widget,
- GthTagsExpander *self)
-{
- GtkWidget *toplevel;
- GdkGeometry geometry;
-
-return; /* FIXME */
-
- toplevel = gtk_widget_get_toplevel (widget);
- if (! GTK_WIDGET_TOPLEVEL (toplevel))
- return;
-
- geometry.min_width = -1;
- geometry.min_height = 230;
- gtk_window_set_geometry_hints (GTK_WINDOW (toplevel),
- widget,
- &geometry,
- GDK_HINT_MIN_SIZE);
-}
-
-
-static void
tag_list_unmap_cb (GtkWidget *widget,
GthTagsExpander *self)
{
@@ -267,6 +331,19 @@ tag_list_unmap_cb (GtkWidget *widget,
}
+static gboolean
+row_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gboolean separator;
+
+ gtk_tree_model_get (model, iter, SEPARATOR_COLUMN, &separator, -1);
+
+ return separator;
+}
+
+
static void
gth_tags_expander_instance_init (GthTagsExpander *self)
{
@@ -275,12 +352,17 @@ gth_tags_expander_instance_init (GthTagsExpander *self)
GtkWidget *scrolled_window;
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_TAGS_EXPANDER, GthTagsExpanderPrivate);
+ self->priv->last_used = g_new0 (char *, 1);
/* the treeview */
- self->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING);
+ self->priv->store = gtk_list_store_new (N_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING);
self->priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (self->priv->store));
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->priv->tree_view), FALSE);
+ gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (self->priv->tree_view),
+ row_separator_func,
+ self,
+ NULL);
g_object_unref (self->priv->store);
/* the checkbox column */
@@ -295,11 +377,9 @@ gth_tags_expander_instance_init (GthTagsExpander *self)
gtk_tree_view_column_set_attributes (column, renderer,
"active", USED_COLUMN,
NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (self->priv->tree_view), column);
/* the name column. */
- column = gtk_tree_view_column_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
gtk_tree_view_column_set_attributes (column, renderer,
@@ -325,7 +405,6 @@ gth_tags_expander_instance_init (GthTagsExpander *self)
NULL);
gtk_widget_set_size_request (scrolled_window, -1, 230);
gtk_container_add (GTK_CONTAINER (scrolled_window), self->priv->tree_view);
- g_signal_connect (scrolled_window, "map", G_CALLBACK (tag_list_map_cb), self);
g_signal_connect (scrolled_window, "unmap", G_CALLBACK (tag_list_unmap_cb), self);
gtk_widget_show (scrolled_window);
gtk_container_add (GTK_CONTAINER (self), scrolled_window);
@@ -367,7 +446,7 @@ gth_tags_expander_new (GtkEntry *entry)
self = g_object_new (GTH_TYPE_TAGS_EXPANDER, "label", _("_Show all the tags"), "use-underline", TRUE, NULL);
self->priv->entry = entry;
- update_tag_list (self);
+ update_list_view_from_entry (self);
g_signal_connect_swapped (self->priv->entry,
"notify::text",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]